mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Merge branch 'fixes' into 'master'
Fixes See merge request core-developers/forge!276
This commit is contained in:
@@ -170,8 +170,8 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView {
|
||||
* @return a boolean.
|
||||
*/
|
||||
public static boolean matchesValid(final Object o, final String[] valids, final Card srcCard) {
|
||||
if (o instanceof GameEntity) {
|
||||
final GameEntity c = (GameEntity) o;
|
||||
if (o instanceof GameObject) {
|
||||
final GameObject c = (GameObject) o;
|
||||
return c.isValid(valids, srcCard.getController(), srcCard, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,6 +179,18 @@ public class ForgeScript {
|
||||
if (!sa.hasParam("Equip")) {
|
||||
return false;
|
||||
}
|
||||
} else if (property.startsWith("IsTargeting")) {
|
||||
String k[] = property.split(" ", 2);
|
||||
boolean found = false;
|
||||
for (GameObject o : AbilityUtils.getDefinedObjects(source, k[1], spellAbility)) {
|
||||
if (sa.isTargeting(o)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1205,7 +1205,7 @@ public class AbilityUtils {
|
||||
final SpellAbility sa) {
|
||||
final FCollection<SpellAbility> sas = new FCollection<SpellAbility>();
|
||||
final String defined = (def == null) ? "Self" : applyAbilityTextChangeEffects(def, sa); // default to Self
|
||||
final Game game = sa.getActivatingPlayer().getGame();
|
||||
final Game game = card.getGame();
|
||||
|
||||
SpellAbility s = null;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import forge.game.card.Card;
|
||||
import forge.game.event.GameEventCardModeChosen;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.List;
|
||||
@@ -34,14 +33,16 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
final SpellAbility fallback = sa.getAdditionalAbility("FallbackAbility");
|
||||
|
||||
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
// determine if any of the choices are not valid
|
||||
List<SpellAbility> saToRemove = Lists.<SpellAbility>newArrayList();
|
||||
|
||||
for (SpellAbility saChoice : abilities) {
|
||||
if ("Player.IsRemembered".equals(saChoice.getParam("Defined")) && saChoice.hasParam("UnlessCost")) {
|
||||
if (!saChoice.getRestrictions().checkOtherRestrictions(host, saChoice, sa.getActivatingPlayer()) ) {
|
||||
saToRemove.add(saChoice);
|
||||
} else if (saChoice.hasParam("UnlessCost") &&
|
||||
"Player.IsRemembered".equals(saChoice.getParam("Defined"))) {
|
||||
String unlessCost = saChoice.getParam("UnlessCost");
|
||||
// Sac a permanent in presence of Sigarda, Host of Herons
|
||||
// TODO: generalize this by testing if the unless cost can be paid
|
||||
@@ -55,7 +56,7 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
}
|
||||
abilities.removeAll(saToRemove);
|
||||
|
||||
if (tgt != null && sa.getTargets().isTargeting(p) && !p.canBeTargetedBy(sa)) {
|
||||
if (sa.usesTargeting() && sa.getTargets().isTargeting(p) && !p.canBeTargetedBy(sa)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ public class CloneEffect extends SpellAbilityEffect {
|
||||
|
||||
// set the host card for copied spellabilities
|
||||
for (final SpellAbility newSa : tgtCard.getSpellAbilities()) {
|
||||
newSa.setHostCard(cardToCopy);
|
||||
newSa.setOriginalHost(cardToCopy);
|
||||
}
|
||||
|
||||
// restore name if it should be unchanged
|
||||
|
||||
@@ -22,7 +22,7 @@ public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
||||
final Game game = hostCard.getGame();
|
||||
|
||||
// create Effect for Regeneration
|
||||
Card eff = createEffect(
|
||||
final Card eff = createEffect(
|
||||
hostCard, sa.getActivatingPlayer(), hostCard.getName() + "'s Regeneration", hostCard.getImageKey());
|
||||
|
||||
eff.addRemembered(list);
|
||||
|
||||
@@ -66,7 +66,7 @@ public class SetStateEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("Transform".equals(mode) && tgt.equals(host)) {
|
||||
if ("Transform".equals(mode) && tgt.equals(host) && sa.hasSVar("StoredTransform")) {
|
||||
// If want to Transform, and host is trying to transform self, skip if not in alignment
|
||||
boolean skip = tgt.getTransformedTimestamp() != Long.parseLong(sa.getSVar("StoredTransform"));
|
||||
// Clear SVar from SA so it doesn't get reused accidentally
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import forge.StaticData;
|
||||
import forge.card.MagicColor;
|
||||
@@ -281,10 +279,10 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
if (prototype == null) {
|
||||
tokens = tokenInfo.makeTokenWithMultiplier(controller, finalAmount, cause != null);
|
||||
grantHiddenKeywords(tokens);
|
||||
grantSvars(tokens, root);
|
||||
grantAbilities(tokens, root);
|
||||
grantTriggers(tokens, root);
|
||||
grantStatics(tokens, root);
|
||||
grantSvars(tokens, sa);
|
||||
grantAbilities(tokens, sa);
|
||||
grantTriggers(tokens, sa);
|
||||
grantStatics(tokens, sa);
|
||||
} else {
|
||||
tokens = TokenInfo.makeTokensFromPrototype(prototype, controller, finalAmount, cause != null);
|
||||
}
|
||||
@@ -352,7 +350,6 @@ public class TokenEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
private String determineTokenColor(Card host) {
|
||||
Set<String> colorSet = new HashSet<>();
|
||||
final String[] substitutedColors = Arrays.copyOf(this.tokenColors, this.tokenColors.length);
|
||||
for (int i = 0; i < substitutedColors.length; i++) {
|
||||
if (substitutedColors[i].equals("ChosenColor")) {
|
||||
|
||||
@@ -2350,11 +2350,12 @@ public class CardFactoryUtil {
|
||||
final String name = StringUtils.join(k);
|
||||
|
||||
final String trigStr = "Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield "
|
||||
+ " | Execute$ " + name + "Choose | ValidCard$ Card.Self | Secondary$ True"
|
||||
+ " | ValidCard$ Card.Self | Secondary$ True"
|
||||
+ " | TriggerDescription$ Fabricate " + n + " (" + inst.getReminderText() + ")";
|
||||
|
||||
final String choose = "DB$ GenericChoice | Choices$ DB" + name + "Counter,DB" + name + "Token | ConditionPresent$ Card.StrictlySelf | SubAbility$ DB" + name + "Token2 | AILogic$ " + name;
|
||||
final String counter = "DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ " + n + " | SpellDescription$ Put "
|
||||
final String choose = "DB$ GenericChoice | AILogic$ " + name;
|
||||
final String counter = "DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ " + n +
|
||||
" | IsPresent$ Card.StrictlySelf | SpellDescription$ Put "
|
||||
+ Lang.nounWithNumeral(n, "+1/+1 counter") + " on it.";
|
||||
final String token = "DB$ Token | TokenAmount$ " + n + " | TokenName$ Servo | TokenTypes$ Artifact,Creature,Servo"
|
||||
+ " | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 1 | TokenToughness$ 1"
|
||||
@@ -2363,10 +2364,15 @@ public class CardFactoryUtil {
|
||||
|
||||
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
|
||||
|
||||
card.setSVar(name + "Choose", choose);
|
||||
card.setSVar("DB" + name + "Counter", counter);
|
||||
card.setSVar("DB" + name + "Token", token);
|
||||
card.setSVar("DB" + name + "Token2", token + " | ConditionPresent$ Card.StrictlySelf | ConditionCompare$ EQ0");
|
||||
SpellAbility saChoose = AbilityFactory.getAbility(choose, card);
|
||||
|
||||
List<AbilitySub> list = Lists.newArrayList();
|
||||
list.add((AbilitySub)AbilityFactory.getAbility(counter, card));
|
||||
list.add((AbilitySub)AbilityFactory.getAbility(token, card));
|
||||
saChoose.setAdditionalAbilityList("Choices", list);
|
||||
saChoose.setIntrinsic(intrinsic);
|
||||
|
||||
trigger.setOverridingAbility(saChoose);
|
||||
|
||||
inst.addTrigger(trigger);
|
||||
} else if (keyword.startsWith("Fading")) {
|
||||
@@ -3367,6 +3373,8 @@ public class CardFactoryUtil {
|
||||
|
||||
// extra part for the Damage Prevention keywords
|
||||
if (keyword.startsWith("Prevent all ")) {
|
||||
// TODO add intrinsic warning
|
||||
|
||||
boolean isCombat = false;
|
||||
boolean from = false;
|
||||
boolean to = false;
|
||||
|
||||
@@ -816,6 +816,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
if (manaPart != null) {
|
||||
clone.manaPart = new AbilityManaPart(host, mapParams);
|
||||
}
|
||||
|
||||
// clear maps for copy, the values will be added later
|
||||
clone.additionalAbilities = Maps.newHashMap();
|
||||
clone.additionalAbilityLists = Maps.newHashMap();
|
||||
// run special copy Ability to make a deep copy
|
||||
CardFactory.copySpellAbility(this, clone, host, lki);
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
@@ -1486,24 +1490,33 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return topSA.getHostCard().isValid(tgt.getValidTgts(), getActivatingPlayer(), getHostCard(), this);
|
||||
}
|
||||
|
||||
public boolean isTargeting(GameObject o) {
|
||||
if (getTargets().isTargeting(o)) {
|
||||
return true;
|
||||
}
|
||||
SpellAbility p = getParent();
|
||||
return p != null && p.isTargeting(o);
|
||||
}
|
||||
|
||||
// Takes one argument like Permanent.Blue+withFlying
|
||||
@Override
|
||||
public final boolean isValid(final String restriction, final Player sourceController, final Card source, SpellAbility spellAbility) {
|
||||
// Inclusive restrictions are Card types
|
||||
final String[] incR = restriction.split("\\.", 2);
|
||||
SpellAbility root = getRootAbility();
|
||||
|
||||
if (incR[0].equals("Spell")) {
|
||||
if (!isSpell()) {
|
||||
if (!root.isSpell()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (incR[0].equals("Triggered")) {
|
||||
if (!isTrigger()) {
|
||||
if (!root.isTrigger()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (incR[0].equals("Activated")) {
|
||||
if (!(this instanceof AbilityActivated)) {
|
||||
if (!(root instanceof AbilityActivated)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ public class SimulateMatch {
|
||||
|
||||
|
||||
|
||||
private static void simulateSingleMatch(Match mc, int iGame, boolean outputGamelog) {
|
||||
private static void simulateSingleMatch(final Match mc, int iGame, boolean outputGamelog) {
|
||||
final StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
|
||||
|
||||
@@ -2,16 +2,13 @@ Name:Treasure Map
|
||||
ManaCost:2
|
||||
Types:Artifact
|
||||
A:AB$ Scry | Cost$ 1 T | ScryNum$ 1 | SubAbility$ DBLandmark | SpellDescription$ Scry 1. Put a landmark counter on CARDNAME. Then if there are three or more landmark counters on it, remove those counters, transform CARDNAME, and create three colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."
|
||||
SVar:DBLandmark:DB$ PutCounter | Defined$ Self | CounterType$ LANDMARK | CounterNum$ 1 | SubAbility$ DBStoreSVar
|
||||
SVar:DBStoreSVar:DB$ StoreSVar | SVar$ FoundTreasure | Type$ Number | Expression$ 1 | ConditionCheckSVar$ XMarksTheSpot | ConditionSVarCompare$ GE1 | References$ XMarksTheSpot,FoundTreasure | SubAbility$ DBRemoveCtrs
|
||||
SVar:DBRemoveCtrs:DB$ RemoveCounter | Defined$ Self | CounterType$ LANDMARK | CounterNum$ 3 | ConditionCheckSVar$ FoundTreasure | ConditionSVarCompare$ GE1 | References$ FoundTreasure | SubAbility$ DBTreasureTokens
|
||||
SVar:DBTreasureTokens:DB$ Token | TokenAmount$ 3 | TokenName$ Treasure | TokenTypes$ Artifact,Treasure | TokenOwner$ You | TokenColors$ Colorless | TokenImage$ c treasure | TokenAbilities$ ABTreasureMana | TokenAltImages$ c_treasure2,c_treasure3,c_treasure4 | ConditionCheckSVar$ FoundTreasure | ConditionSVarCompare$ GE1 | SubAbility$ DBTransform | References$ FoundTreasure
|
||||
SVar:DBTransform:DB$ SetState | Defined$ Self | Mode$ Transform | ConditionCheckSVar$ FoundTreasure | ConditionSVarCompare$ GE1 | References$ FoundTreasure
|
||||
SVar:DBLandmark:DB$ PutCounter | Defined$ Self | CounterType$ LANDMARK | CounterNum$ 1 | SubAbility$ DBBranch
|
||||
SVar:DBBranch:DB$ Branch | BranchConditionSVar$ XMarksTheSpot | References$ XMarksTheSpot | TrueSubAbility$ DBRemoveCtrs
|
||||
SVar:DBRemoveCtrs:DB$ RemoveCounter | Defined$ Self | CounterType$ LANDMARK | CounterNum$ All | SubAbility$ DBTransform
|
||||
SVar:DBTransform:DB$ SetState | Defined$ Self | Mode$ Transform | SubAbility$ DBTreasureTokens
|
||||
SVar:DBTreasureTokens:DB$ Token | TokenAmount$ 3 | TokenName$ Treasure | TokenTypes$ Artifact,Treasure | TokenOwner$ You | TokenColors$ Colorless | TokenImage$ c treasure | TokenAbilities$ ABTreasureMana | TokenAltImages$ c_treasure2,c_treasure3,c_treasure4 | References$ ABTreasureMana
|
||||
SVar:ABTreasureMana:AB$ Mana | Cost$ T Sac<1/CARDNAME> | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color to your mana pool.
|
||||
SVar:XMarksTheSpot:Count$Valid Card.Self+counters_GE3_LANDMARK
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | Execute$ DBInitSVar | Static$ True
|
||||
SVar:DBInitSVar:DB$ StoreSVar | SVar$ FoundTreasure | Type$ Number | Expression$ 0 | References$ FoundTreasure
|
||||
SVar:FoundTreasure:Number$0
|
||||
AlternateMode:DoubleFaced
|
||||
DeckHas:Ability$Token
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/treasure_map.jpg
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
* Created by maustin on 09/05/2017.
|
||||
*/
|
||||
public class CommanderDeckGenerator extends DeckProxy implements Comparable<CommanderDeckGenerator> {
|
||||
public static List<DeckProxy> getCommanderDecks(DeckFormat format, boolean isForAi, boolean isCardGen){
|
||||
public static List<DeckProxy> getCommanderDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){
|
||||
ItemPool uniqueCards;
|
||||
if(isCardGen){
|
||||
uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
|
||||
|
||||
Reference in New Issue
Block a user