diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index 9327e9666eb..b5c10e2d612 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -1925,8 +1925,8 @@ public class AiController { return Math.min(player.getLife() -1,MyRandom.getRandom().nextInt(Math.max(player.getLife() / 3, player.getWeakestOpponent().getLife())) + 1); } else if ("HighestGetCounter".equals(logic)) { return MyRandom.getRandom().nextInt(3); - } else if (source.hasSVar("EnergyToPay")) { - return AbilityUtils.calculateAmount(source, source.getSVar("EnergyToPay"), sa); + } else if (sa.hasSVar("EnergyToPay")) { + return AbilityUtils.calculateAmount(source, sa.getSVar("EnergyToPay"), sa); } else if ("Vermin".equals(logic)) { return MyRandom.getRandom().nextInt(Math.max(player.getLife() - 5, 0)); } else if ("SweepCreatures".equals(logic)) { diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index 762585f8bdb..7f3a22dc133 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -500,17 +500,19 @@ public class AnimateAi extends SpellAbilityAi { } // give sVars - if (sVars.size() > 0) { - for (final String s : sVars) { - String actualsVar = source.getSVar(s); + if (sa.hasParam("sVars")) { + Map sVarsMap = Maps.newHashMap(); + for (final String s : sa.getParam("sVars").split(",")) { + String actualsVar = AbilityUtils.getSVar(sa, s); String name = s; if (actualsVar.startsWith("SVar:")) { actualsVar = actualsVar.split("SVar:")[1]; name = actualsVar.split(":")[0]; actualsVar = actualsVar.split(":")[1]; } - card.setSVar(name, actualsVar); + sVarsMap.put(name, actualsVar); } + card.addChangedSVars(sVarsMap, timestamp, 0); } ComputerUtilCard.applyStaticContPT(game, card, null); } diff --git a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java index c8394b33d4b..420a4be32b7 100644 --- a/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/DamageDealAi.java @@ -53,6 +53,7 @@ import forge.util.MyRandom; public class DamageDealAi extends DamageAiBase { @Override public boolean chkAIDrawback(SpellAbility sa, Player ai) { + final SpellAbility root = sa.getRootAbility(); final String damage = sa.getParam("NumDmg"); Card source = sa.getHostCard(); int dmg = AbilityUtils.calculateAmount(source, damage, sa); @@ -76,7 +77,7 @@ public class DamageDealAi extends DamageAiBase { if (dmg > energy || dmg < 1) { continue; // in case the calculation gets messed up somewhere } - source.setSVar("EnergyToPay", "Number$" + dmg); + root.setSVar("EnergyToPay", "Number$" + dmg); return true; } } diff --git a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java index 4db53dcaf13..e5705d72927 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PumpAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PumpAi.java @@ -731,7 +731,7 @@ public class PumpAi extends PumpAiBase { if (minus > energy || minus < 1) { continue; // in case the calculation gets messed up somewhere } - source.setSVar("EnergyToPay", "Number$" + minus); + root.setSVar("EnergyToPay", "Number$" + minus); return true; } } diff --git a/forge-game/src/main/java/forge/game/CardTraitBase.java b/forge-game/src/main/java/forge/game/CardTraitBase.java index f2c791042c4..c10cc1a01d2 100644 --- a/forge-game/src/main/java/forge/game/CardTraitBase.java +++ b/forge-game/src/main/java/forge/game/CardTraitBase.java @@ -55,15 +55,13 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, /** Keys of descriptive (text) parameters. */ private static final ImmutableList descriptiveKeys = ImmutableList.builder() .add("Description", "SpellDescription", "StackDescription", "TriggerDescription").build(); - /** Keys to be followed as SVar names when changing text. */ - private static final ImmutableList mutableKeys = ImmutableList.builder() - .add("AddAbility").build(); /** * Keys that should not changed */ private static final ImmutableList noChangeKeys = ImmutableList.builder() - .add("TokenScript", "LegacyImage", "TokenImage", "NewName", "ChooseFromList").build(); + .add("TokenScript", "LegacyImage", "TokenImage", "NewName", "ChooseFromList") + .add("AddAbility").build(); /** *

@@ -511,11 +509,6 @@ public abstract class CardTraitBase extends GameObject implements IHasCardView, } else if (descriptiveKeys.contains(key)) { // change descriptions differently newValue = AbilityUtils.applyDescriptionTextChangeEffects(value, this); - } else if (mutableKeys.contains(key)) { - // follow SVar and change it - final String originalSVarValue = hostCard.getSVar(value); - hostCard.changeSVar(value, AbilityUtils.applyAbilityTextChangeEffects(originalSVarValue, this)); - newValue = null; } else if (this.getHostCard().hasSVar(value)) { // don't change literal SVar names! newValue = null; diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index dfda9c27aa6..8e650d1ae22 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -233,13 +233,6 @@ public class GameAction { } } - // Clean up the temporary Dash/Blitz SVar when the card leaves the battlefield - // Clean up the temporary AtEOT SVar - String endofTurn = c.getSVar("EndOfTurnLeavePlay"); - if (fromBattlefield && (endofTurn.equals("Dash") || endofTurn.equals("Blitz") || endofTurn.equals("AtEOT"))) { - c.removeSVar("EndOfTurnLeavePlay"); - } - if (fromBattlefield && !toBattlefield) { c.getController().setRevolt(true); } @@ -337,7 +330,7 @@ public class GameAction { CardCollectionView comCards = c.getOwner().getCardsIn(ZoneType.Command); for (final Card effCard : comCards) { for (final ReplacementEffect re : effCard.getReplacementEffects()) { - if (re.hasSVar("CommanderMoveReplacement") && effCard.getEffectSource().getName().equals(c.getRealCommander().getName())) { + if (re.hasParam("CommanderMoveReplacement") && effCard.getEffectSource().getName().equals(c.getRealCommander().getName())) { commanderEffect = effCard; break; } diff --git a/forge-game/src/main/java/forge/game/StaticEffect.java b/forge-game/src/main/java/forge/game/StaticEffect.java index 05bed4adb7a..639f13588cd 100644 --- a/forge-game/src/main/java/forge/game/StaticEffect.java +++ b/forge-game/src/main/java/forge/game/StaticEffect.java @@ -288,6 +288,8 @@ public class StaticEffect { affectedCard.removeCanBlockAdditional(getTimestamp()); } + affectedCard.removeChangedSVars(getTimestamp(), ability.getId()); + affectedCard.updateAbilityTextForView(); // only update keywords and text for view to avoid flickering } return affectedCards; diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index da91b969bef..9cd9c20eade 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -300,13 +300,12 @@ public abstract class SpellAbilityEffect { delTrig.append("| TriggerDescription$ ").append(desc); final Trigger trig = TriggerHandler.parseTrigger(delTrig.toString(), CardUtil.getLKICopy(sa.getHostCard()), intrinsic); + long ts = sa.getHostCard().getGame().getNextTimestamp(); for (final Card c : crds) { trig.addRemembered(c); // Svar for AI - if (!c.hasSVar("EndOfTurnLeavePlay")) { - c.setSVar("EndOfTurnLeavePlay", "AtEOT"); - } + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "AtEOT"), ts, 0); } String trigSA = ""; if (location.equals("Hand")) { @@ -346,9 +345,7 @@ public abstract class SpellAbilityEffect { card.addTrigger(trig); // Svar for AI - if (!card.hasSVar("EndOfTurnLeavePlay")) { - card.setSVar("EndOfTurnLeavePlay", "AtEOT"); - } + card.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "AtEOT"), card.getGame().getNextTimestamp(), 0); } protected static SpellAbility getForgetSpellAbility(final Card card) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java index efd631c5773..d79bb6d4502 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java @@ -1,10 +1,12 @@ package forge.game.ability.effects; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import forge.GameCommand; import forge.card.CardType; @@ -64,17 +66,17 @@ public class AnimateAllEffect extends AnimateEffectBase { types.add(host.getChosenType2()); } - final List keywords = new ArrayList<>(); + final List keywords = Lists.newArrayList(); if (sa.hasParam("Keywords")) { keywords.addAll(Arrays.asList(sa.getParam("Keywords").split(" & "))); } - final List removeKeywords = new ArrayList<>(); + final List removeKeywords = Lists.newArrayList(); if (sa.hasParam("RemoveKeywords")) { removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & "))); } - final List hiddenKeywords = new ArrayList<>(); + final List hiddenKeywords = Lists.newArrayList(); if (sa.hasParam("HiddenKeywords")) { hiddenKeywords.addAll(Arrays.asList(sa.getParam("HiddenKeywords").split(" & "))); } @@ -99,27 +101,32 @@ public class AnimateAllEffect extends AnimateEffectBase { } // abilities to add to the animated being - final List abilities = new ArrayList<>(); + final List abilities = Lists.newArrayList(); if (sa.hasParam("Abilities")) { abilities.addAll(Arrays.asList(sa.getParam("Abilities").split(","))); } // replacement effects to add to the animated being - final List replacements = new ArrayList<>(); + final List replacements = Lists.newArrayList(); if (sa.hasParam("Replacements")) { replacements.addAll(Arrays.asList(sa.getParam("Replacements").split(","))); } // triggers to add to the animated being - final List triggers = new ArrayList<>(); + final List triggers = Lists.newArrayList(); if (sa.hasParam("Triggers")) { triggers.addAll(Arrays.asList(sa.getParam("Triggers").split(","))); } // sVars to add to the animated being - final List sVars = new ArrayList<>(); + final List sVars = Lists.newArrayList(); if (sa.hasParam("sVars")) { sVars.addAll(Arrays.asList(sa.getParam("sVars").split(","))); } + Map sVarsMap = Maps.newHashMap(); + for (final String s : sVars) { + sVarsMap.put(s, AbilityUtils.getSVar(sa, s)); + } + final String valid = sa.getParamOrDefault("ValidCards", ""); CardCollectionView list; @@ -139,9 +146,10 @@ public class AnimateAllEffect extends AnimateEffectBase { timestamp); // give sVars - for (final String s : sVars) { - c.setSVar(s, AbilityUtils.getSVar(sa, s)); + if (!sVarsMap.isEmpty() ) { + c.addChangedSVars(sVarsMap, timestamp, 0); } + game.fireEvent(new GameEventCardStatsChanged(c)); final GameCommand unanimate = new GameCommand() { diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java index f2c37658ead..bc166d03de7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java @@ -2,7 +2,9 @@ package forge.game.ability.effects; import java.util.Arrays; import java.util.List; +import java.util.Map; +import com.google.common.collect.Maps; import com.google.common.collect.Lists; import forge.card.CardType; @@ -138,11 +140,22 @@ public class AnimateEffect extends AnimateEffectBase { } // sVars to add to the animated being - final List sVars = Lists.newArrayList(); + Map sVarsMap = Maps.newHashMap(); if (sa.hasParam("sVars")) { - sVars.addAll(Arrays.asList(sa.getParam("sVars").split(","))); + for (final String s : sa.getParam("sVars").split(",")) { + String actualsVar = AbilityUtils.getSVar(sa, s); + String name = s; + if (actualsVar.startsWith("SVar:")) { + actualsVar = actualsVar.split("SVar:")[1]; + name = actualsVar.split(":")[0]; + actualsVar = actualsVar.split(":")[1]; + } + sVarsMap.put(name, actualsVar); + } } + + List tgts = getCardsfromTargets(sa); if (sa.hasParam("Optional")) { @@ -166,15 +179,8 @@ public class AnimateEffect extends AnimateEffectBase { } // give sVars - for (final String s : sVars) { - String actualsVar = AbilityUtils.getSVar(sa, s); - String name = s; - if (actualsVar.startsWith("SVar:")) { - actualsVar = actualsVar.split("SVar:")[1]; - name = actualsVar.split(":")[0]; - actualsVar = actualsVar.split(":")[1]; - } - c.setSVar(name, actualsVar); + if (!sVarsMap.isEmpty()) { + c.addChangedSVars(sVarsMap, timestamp, 0); } // give Remembered diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java index 70ac1823195..6df27fae809 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffectBase.java @@ -137,6 +137,7 @@ public abstract class AnimateEffectBase extends SpellAbilityEffect { public void run() { doUnanimate(c, timestamp); + c.removeChangedSVars(timestamp, 0); c.removeChangedName(timestamp, 0); c.updateStateForView(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java index 28881ebb355..a7133e10f6a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ControlGainEffect.java @@ -1,5 +1,9 @@ package forge.game.ability.effects; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import com.google.common.collect.Lists; import forge.GameCommand; @@ -16,9 +20,6 @@ import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.Localizer; -import java.util.Arrays; -import java.util.List; - public class ControlGainEffect extends SpellAbilityEffect { @Override @@ -210,11 +211,11 @@ public class ControlGainEffect extends SpellAbilityEffect { } if (lose.contains("EOT")) { game.getEndOfTurn().addUntil(loseControl); - tgtC.setSVar("SacMe", "6"); + tgtC.addChangedSVars(Collections.singletonMap("SacMe", "6"), tStamp, 0); } if (lose.contains("EndOfCombat")) { game.getEndOfCombat().addUntil(loseControl); - tgtC.setSVar("SacMe", "6"); + tgtC.addChangedSVars(Collections.singletonMap("SacMe", "6"), tStamp, 0); } if (lose.contains("StaticCommandCheck")) { String leftVar = sa.getSVar(sa.getParam("StaticCommandCheckSVar")); @@ -276,7 +277,7 @@ public class ControlGainEffect extends SpellAbilityEffect { @Override public void run() { doLoseControl(c, hostCard, bTapOnLose, tStamp); - c.removeSVar("SacMe"); + c.removeChangedSVars(tStamp, 0); } }; diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 6591ceaeb6e..bb1d424d7f6 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -299,7 +299,7 @@ public class DamageDealEffect extends DamageBaseEffect { } else { damageMap.put(sourceLKI, c, dmg); if (sa.hasParam("ExcessSVar")) { - hostCard.setSVar(sa.getParam("ExcessSVar"), Integer.toString(excess)); + sa.setSVar(sa.getParam("ExcessSVar"), Integer.toString(excess)); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java b/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java index fa1334fffa6..136a70e7c3f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/LifeLoseEffect.java @@ -2,7 +2,6 @@ package forge.game.ability.effects; import forge.game.ability.AbilityUtils; -import forge.game.ability.ApiType; import forge.game.ability.SpellAbilityEffect; import forge.game.player.Player; import forge.game.spellability.SpellAbility; @@ -41,14 +40,7 @@ public class LifeLoseEffect extends SpellAbilityEffect { lifeLost += p.loseLife(lifeAmount, false, false); } } - sa.getHostCard().setSVar("AFLifeLost", "Number$" + lifeLost); - - // Exceptional case for Extort: must propagate the amount of life lost to subability, - // otherwise the first Extort trigger per game won't work - if (sa.getSubAbility() != null && ApiType.GainLife.equals(sa.getSubAbility().getApi())) { - sa.getSubAbility().setSVar("AFLifeLost", "Number$" + lifeLost); - } - + sa.setSVar("AFLifeLost", "Number$" + lifeLost); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java index ddb356c4da1..e985b309554 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PermanentEffect.java @@ -1,5 +1,6 @@ package forge.game.ability.effects; +import java.util.Collections; import java.util.Map; import com.google.common.collect.Lists; @@ -42,12 +43,12 @@ public class PermanentEffect extends SpellAbilityEffect { // some extra for Dashing if (sa.isDash() && c.isInPlay()) { - c.setSVar("EndOfTurnLeavePlay", "Dash"); + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Dash"), c.getGame().getNextTimestamp(), 0); registerDelayedTrigger(sa, "Hand", Lists.newArrayList(c)); } // similar for Blitz keyword if (sa.isBlitz() && c.isInPlay()) { - c.setSVar("EndOfTurnLeavePlay", "Blitz"); + c.addChangedSVars(Collections.singletonMap("EndOfTurnLeavePlay", "Blitz"), c.getGame().getNextTimestamp(), 0); registerDelayedTrigger(sa, "Sacrifice", Lists.newArrayList(c)); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/RollDiceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RollDiceEffect.java index 2931da09e9f..fb0a99ace99 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RollDiceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RollDiceEffect.java @@ -126,13 +126,13 @@ public class RollDiceEffect extends SpellAbilityEffect { total += modifier; if (sa.hasParam("ResultSVar")) { - host.setSVar(sa.getParam("ResultSVar"), Integer.toString(total)); + sa.setSVar(sa.getParam("ResultSVar"), Integer.toString(total)); } if (sa.hasParam("ChosenSVar")) { int chosen = player.getController().chooseNumber(sa, Localizer.getInstance().getMessage("lblChooseAResult"), rolls, player); String message = Localizer.getInstance().getMessage("lblPlayerChooseValue", player, chosen); player.getGame().getAction().notifyOfValue(sa, player, message, player); - host.setSVar(sa.getParam("ChosenSVar"), Integer.toString(chosen)); + sa.setSVar(sa.getParam("ChosenSVar"), Integer.toString(chosen)); if (sa.hasParam("OtherSVar")) { int other = rolls.get(0); for (int i = 1; i < rolls.size(); ++i) { @@ -141,7 +141,7 @@ public class RollDiceEffect extends SpellAbilityEffect { break; } } - host.setSVar(sa.getParam("OtherSVar"), Integer.toString(other)); + sa.setSVar(sa.getParam("OtherSVar"), Integer.toString(other)); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java index 5ef63f3ba3b..2305418b22a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/VoteEffect.java @@ -126,7 +126,7 @@ public class VoteEffect extends SpellAbilityEffect { } if (sa.hasParam("StoreVoteNum")) { for (final Object type : voteType) { - host.setSVar("VoteNum" + type, "Number$" + votes.get(type).size()); + sa.setSVar("VoteNum" + type, "Number$" + votes.get(type).size()); } } else { for (final String subAb : subAbs) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4dd21525c89..927454d398e 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -159,6 +159,8 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private final NavigableMap clonedStates = Maps.newTreeMap(); // Layer 1 + private final Table> changedSVars = TreeBasedTable.create(); + private final Map mayLook = Maps.newHashMap(); private final PlayerCollection mayLookFaceDownExile = new PlayerCollection(); private final PlayerCollection mayLookTemp = new PlayerCollection(); @@ -175,9 +177,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private final CardChangedWords changedTextColors = new CardChangedWords(); private final CardChangedWords changedTextTypes = new CardChangedWords(); - /** Original values of SVars changed by text changes. */ - private Map originalSVars = Maps.newHashMap(); - private final Set rememberedObjects = Sets.newLinkedHashSet(); private Map flipResult; @@ -1586,10 +1585,20 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final String getSVar(final String var) { + for (Map map : changedSVars.values()) { + if (map.containsKey(var)) { + return map.get(var); + } + } return currentState.getSVar(var); } public final boolean hasSVar(final String var) { + for (Map map : changedSVars.values()) { + if (map.containsKey(var)) { + return true; + } + } return currentState.hasSVar(var); } @@ -1615,6 +1624,13 @@ public class Card extends GameEntity implements Comparable, IHasSVars { currentState.removeSVar(var); } + public final void addChangedSVars(Map map, long timestamp, long staticId) { + this.changedSVars.put(timestamp, staticId, map); + } + public final void removeChangedSVars(long timestamp, long staticId) { + this.changedSVars.remove(timestamp, staticId); + } + public final int getTurnInZone() { return turnInZone; } @@ -4596,7 +4612,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { * Update the changed text of the intrinsic spell abilities and keywords. */ public void updateChangedText() { - resetChangedSVars(); // update type List toAdd = Lists.newArrayList(); @@ -4664,26 +4679,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { changedTextTypes.copyFrom(other.changedTextTypes); } - /** - * Change a SVar due to a text change effect. Change is volatile and will be - * reverted upon refreshing text changes (unless it is changed again at that - * time). - * - * @param key the SVar name. - * @param value the new SVar value. - */ - public final void changeSVar(final String key, final String value) { - originalSVars.put(key, getSVar(key)); - setSVar(key, value); - } - - private void resetChangedSVars() { - for (final Entry svar : originalSVars.entrySet()) { - setSVar(svar.getKey(), svar.getValue()); - } - originalSVars.clear(); - } - public final KeywordInterface addIntrinsicKeyword(final String s) { KeywordInterface inst = currentState.addIntrinsicKeyword(s, true); if (inst != null) { diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 73cbf35e0db..9165616a5a2 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -98,6 +98,7 @@ import forge.game.keyword.KeywordsChange; import forge.game.mana.ManaPool; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; +import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementHandler; import forge.game.replacement.ReplacementResult; import forge.game.replacement.ReplacementType; @@ -3032,7 +3033,9 @@ public class Player extends GameEntity implements Comparable { String addToHandAbility = "Mode$ Continuous | EffectZone$ Command | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command | AddAbility$ MoveToHand"; String moveToHand = "ST$ ChangeZone | Cost$ 3 | Defined$ Self | Origin$ Command | Destination$ Hand | SorcerySpeed$ True | ActivationZone$ Command | SpellDescription$ Companion - Put CARDNAME in to your hand"; - eff.setSVar("MoveToHand", moveToHand); + + StaticAbility stAb = StaticAbility.create(addToHandAbility, eff, eff.getCurrentState(), true); + stAb.setSVar("MoveToHand", moveToHand); eff.addStaticAbility(addToHandAbility); return eff; @@ -3044,11 +3047,13 @@ public class Player extends GameEntity implements Comparable { if (game.getRules().hasAppliedVariant(GameType.Oathbreaker) && commander.getRules().canBeSignatureSpell()) { //signature spells can only reside on the stack or in the command zone - eff.setSVar("SignatureSpellMoveReplacement", "DB$ ChangeZone | Origin$ Stack | Destination$ Command | Defined$ ReplacedCard"); + String effStr = "DB$ ChangeZone | Origin$ Stack | Destination$ Command | Defined$ ReplacedCard"; - String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | ReplaceWith$ SignatureSpellMoveReplacement | Destination$ Graveyard,Exile,Hand,Library | " + + String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Destination$ Graveyard,Exile,Hand,Library | " + "Description$ If a signature spell would be put into another zone from the stack, put it into the command zone instead."; - eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true)); + ReplacementEffect re = ReplacementHandler.parseReplacement(moved, eff, true); + re.setOverridingAbility(AbilityFactory.getAbility(eff, effStr)); + eff.addReplacementEffect(re); //signature spells can only be cast if your oathbreaker is in on the battlefield under your control String castRestriction = "Mode$ CantBeCast | ValidCard$ Card.EffectSource+YouOwn | EffectZone$ Command | IsPresent$ Card.IsCommander+YouOwn+YouCtrl | PresentZone$ Battlefield | PresentCompare$ EQ0 | " + @@ -3056,9 +3061,9 @@ public class Player extends GameEntity implements Comparable { eff.addStaticAbility(castRestriction); } else { - eff.setSVar("CommanderMoveReplacement", "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"); + String effStr = "DB$ ChangeZone | Origin$ Battlefield,Graveyard,Exile,Library,Hand | Destination$ Command | Defined$ ReplacedCard"; - String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | ReplaceWith$ CommanderMoveReplacement "; + String moved = "Event$ Moved | ValidCard$ Card.EffectSource+YouOwn | Secondary$ True | Optional$ True | OptionalDecider$ You | CommanderMoveReplacement$ True "; if (game.getRules().hasAppliedVariant(GameType.TinyLeaders)) { moved += " | Destination$ Graveyard,Exile | Description$ If a commander would be put into its owner's graveyard or exile from anywhere, that player may put it into the command zone instead."; } @@ -3068,7 +3073,9 @@ public class Player extends GameEntity implements Comparable { // rule 903.9b moved += " | Destination$ Hand,Library | Description$ If a commander would be put into its owner's hand or library from anywhere, its owner may put it into the command zone instead."; } - eff.addReplacementEffect(ReplacementHandler.parseReplacement(moved, eff, true)); + ReplacementEffect re = ReplacementHandler.parseReplacement(moved, eff, true); + re.setOverridingAbility(AbilityFactory.getAbility(eff, effStr)); + eff.addReplacementEffect(re); } String mayBePlayedAbility = "Mode$ Continuous | EffectZone$ Command | MayPlay$ True | Affected$ Card.YouOwn+EffectSource | AffectedZone$ Command"; diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java index 8c112ab1ab0..1a32a81b354 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityContinuous.java @@ -30,6 +30,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import forge.GameCommand; import forge.card.CardStateName; @@ -779,6 +780,7 @@ public final class StaticAbilityContinuous { // add SVars if (addSVars != null) { + Map map = Maps.newHashMap(); for (final String sVar : addSVars) { String actualSVar = AbilityUtils.getSVar(stAb, sVar); String name = sVar; @@ -787,8 +789,9 @@ public final class StaticAbilityContinuous { name = actualSVar.split(":")[0]; actualSVar = actualSVar.split(":")[1]; } - affectedCard.setSVar(name, actualSVar); + map.put(name, actualSVar); } + affectedCard.addChangedSVars(map, se.getTimestamp(), stAb.getId()); } if (layer == StaticAbilityLayer.ABILITIES) { diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 44d641d8591..e67b9483cec 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -52,7 +52,7 @@ import forge.util.MyRandom; import forge.util.collect.FCollectionView; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; -import org.testng.collections.Lists; +import com.google.common.collect.Lists; import java.util.Collection; import java.util.HashMap; diff --git a/forge-gui/res/cardsfolder/a/abnormal_endurance.txt b/forge-gui/res/cardsfolder/a/abnormal_endurance.txt index 369205343f0..78c15d70fa5 100644 --- a/forge-gui/res/cardsfolder/a/abnormal_endurance.txt +++ b/forge-gui/res/cardsfolder/a/abnormal_endurance.txt @@ -2,7 +2,7 @@ Name:Abnormal Endurance ManaCost:1 B Types:Instant A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | SpellDescription$ Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control." | SubAbility$ DBAnimate -SVar:DBAnimate:DB$ Animate | Triggers$ AbnormalEnduranceChangeZone | sVars$ AbnormalEnduranceTrigChangeZone | Defined$ ParentTarget +SVar:DBAnimate:DB$ Animate | Triggers$ AbnormalEnduranceChangeZone | Defined$ ParentTarget SVar:AbnormalEnduranceChangeZone:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ AbnormalEnduranceTrigChangeZone | TriggerController$ TriggeredCardController | TriggerDescription$ When this creature dies, return it to the battlefield tapped under its owner's control. SVar:AbnormalEnduranceTrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ TriggeredNewCardLKICopy Oracle:Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control." diff --git a/forge-gui/res/cardsfolder/a/aethermages_touch.txt b/forge-gui/res/cardsfolder/a/aethermages_touch.txt index 34ed3b01913..40e27282291 100644 --- a/forge-gui/res/cardsfolder/a/aethermages_touch.txt +++ b/forge-gui/res/cardsfolder/a/aethermages_touch.txt @@ -2,7 +2,7 @@ Name:Aethermage's Touch ManaCost:2 W U Types:Instant A:SP$ Dig | Cost$ 2 W U | DigNum$ 4 | Reveal$ True | ChangeNum$ 1 | Optional$ True | ChangeValid$ Creature | DestinationZone$ Battlefield | RememberChanged$ True | SubAbility$ DBAnimate | SpellDescription$ Reveal the top four cards of your library. You may put a creature card from among them onto the battlefield. It gains "At the beginning of your end step, return this creature to its owner's hand." Then put the rest of the cards revealed this way on the bottom of your library in any order. | StackDescription$ SpellDescription -SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Duration$ Permanent | Triggers$ TrigAethermage | sVars$ BounceAethermage | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Duration$ Permanent | Triggers$ TrigAethermage | SubAbility$ DBCleanup | StackDescription$ None SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:TrigAethermage:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ BounceAethermage | TriggerDescription$ At the beginning of your end step, return CARDNAME to its owner's hand. SVar:BounceAethermage:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Hand diff --git a/forge-gui/res/cardsfolder/a/arm_with_aether.txt b/forge-gui/res/cardsfolder/a/arm_with_aether.txt index 831d42bc32f..f1b73ae2bb9 100644 --- a/forge-gui/res/cardsfolder/a/arm_with_aether.txt +++ b/forge-gui/res/cardsfolder/a/arm_with_aether.txt @@ -1,7 +1,7 @@ Name:Arm with Aether ManaCost:2 U Types:Sorcery -A:SP$ AnimateAll | Cost$ 2 U | ValidCards$ Creature.YouCtrl | Triggers$ Trig | sVars$ Eff | SpellDescription$ Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand." +A:SP$ AnimateAll | Cost$ 2 U | ValidCards$ Creature.YouCtrl | Triggers$ Trig | SpellDescription$ Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand." SVar:Trig:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | OptionalDecider$ You | Execute$ Eff | TriggerDescription$ Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand. SVar:Eff:DB$ ChangeZone | ValidTgts$ Creature | TargetsWithDefinedController$ TriggeredTarget | TgtPrompt$ Select target creature that player controls. | Origin$ Battlefield | Destination$ Hand Oracle:Until end of turn, creatures you control gain "Whenever this creature deals damage to an opponent, you may return target creature that player controls to its owner's hand." diff --git a/forge-gui/res/cardsfolder/b/brawl.txt b/forge-gui/res/cardsfolder/b/brawl.txt index b3307e6301e..bca9e3a2c2b 100644 --- a/forge-gui/res/cardsfolder/b/brawl.txt +++ b/forge-gui/res/cardsfolder/b/brawl.txt @@ -1,7 +1,7 @@ Name:Brawl ManaCost:3 R R Types:Instant -A:SP$ AnimateAll | Cost$ 3 R R | ValidCards$ Creature | Abilities$ ThrowPunch | sVars$ BrawlX | SpellDescription$ Until end of turn, all creatures gain "{T}: This creature deals damage equal to its power to target creature." +A:SP$ AnimateAll | Cost$ 3 R R | ValidCards$ Creature | Abilities$ ThrowPunch | SpellDescription$ Until end of turn, all creatures gain "{T}: This creature deals damage equal to its power to target creature." SVar:ThrowPunch:AB$ DealDamage | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ BrawlX | SpellDescription$ This creature deals damage equal to its power to target creature. SVar:BrawlX:Count$CardPower AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/c/cherished_hatchling.txt b/forge-gui/res/cardsfolder/c/cherished_hatchling.txt index cabbd4e336f..81cea1e9301 100644 --- a/forge-gui/res/cardsfolder/c/cherished_hatchling.txt +++ b/forge-gui/res/cardsfolder/c/cherished_hatchling.txt @@ -6,7 +6,7 @@ T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ SVar:TrigEffect:DB$ Effect | Name$ Cherished Hatchling Effect | StaticAbilities$ STFlash | Triggers$ HatchlingCast SVar:STFlash:Mode$ CastWithFlash | ValidCard$ Dinosaur | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ You may cast Dinosaur spells this turn as though they had flash. SVar:HatchlingCast:Mode$ SpellCast | ValidCard$ Dinosaur | ValidActivatingPlayer$ You | Execute$ TrigHatchlingAnimate | TriggerZones$ Command | TriggerDescription$ Whenever you cast a Dinosaur spell this turn, it gains "When this creature enters the battlefield, you may have it fight another target creature." -SVar:TrigHatchlingAnimate:DB$ Animate | Defined$ TriggeredCard | Duration$ Permanent | Triggers$ TrigETBHatchling | sVars$ HatchlingFight +SVar:TrigHatchlingAnimate:DB$ Animate | Defined$ TriggeredCard | Duration$ Permanent | Triggers$ TrigETBHatchling SVar:TrigETBHatchling:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ HatchlingFight | OptionalDecider$ You | TriggerDescription$ When this creature enters the battlefield, you may have it fight another target creature. SVar:HatchlingFight:DB$ Fight | Defined$ TriggeredCardLKICopy | ValidTgts$ Creature.Other | TgtPrompt$ Select another target creature DeckHints:Type$Dinosaur diff --git a/forge-gui/res/cardsfolder/c/commando_raid.txt b/forge-gui/res/cardsfolder/c/commando_raid.txt index 89496c5a5b6..72252541fe3 100644 --- a/forge-gui/res/cardsfolder/c/commando_raid.txt +++ b/forge-gui/res/cardsfolder/c/commando_raid.txt @@ -1,7 +1,7 @@ Name:Commando Raid ManaCost:2 R Types:Instant -A:SP$ Animate | Cost$ 2 R | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Triggers$ TrigDamage | sVars$ Damage,CommandoRaidX | SpellDescription$ Until end of turn, target creature you control gains "When this creature deals combat damage to a player, you may have it deal damage equal to its power to target creature that player controls." +A:SP$ Animate | Cost$ 2 R | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Triggers$ TrigDamage | SpellDescription$ Until end of turn, target creature you control gains "When this creature deals combat damage to a player, you may have it deal damage equal to its power to target creature that player controls." SVar:TrigDamage:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ Damage | OptionalDecider$ You | TriggerDescription$ When this creature deals combat damage to a player, you may have it deal damage equal to its power to target creature that player controls. SVar:Damage:DB$ DealDamage | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature defending player controls | NumDmg$ CommandoRaidX SVar:CommandoRaidX:Count$CardPower diff --git a/forge-gui/res/cardsfolder/c/cosima_god_of_the_voyage_the_omenkeel.txt b/forge-gui/res/cardsfolder/c/cosima_god_of_the_voyage_the_omenkeel.txt index c1f7c178abc..dddde364c2e 100644 --- a/forge-gui/res/cardsfolder/c/cosima_god_of_the_voyage_the_omenkeel.txt +++ b/forge-gui/res/cardsfolder/c/cosima_god_of_the_voyage_the_omenkeel.txt @@ -4,7 +4,7 @@ Types:Legendary Creature God PT:2/4 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigExile | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ At the beginning of your upkeep, you may exile NICKNAME. If you do, it gains "Whenever a land enters the battlefield under your control, if Cosima is exiled, you may put a voyage counter on it. If you don't, return Cosima to the battlefield with X +1/+1 counters on it and draw X cards, where X is the number of voyage counters on it." SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DBAnimate -SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Triggers$ LandEnter | Duration$ Permanent | sVars$ TrigReturn,DBDraw,X | SubAbility$ DBCleanup +SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Triggers$ LandEnter | Duration$ Permanent | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:LandEnter:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | TriggerZones$ Exile | ValidCard$ Land.YouCtrl | Execute$ TrigAddCounter | TriggerDescription$ Whenever a land enters the battlefield under your control, if NICKNAME is exiled, you may put a voyage counter on it. If you don't, return NICKNAME to the battlefield with X +1/+1 counters on it and draw X cards, where X is the number of voyage counters on it. SVar:TrigAddCounter:DB$ PutCounter | Optional$ True | Defined$ Self | CounterType$ VOYAGE | CounterNum$ 1 | RememberAmount$ True | SubAbility$ DBReturn diff --git a/forge-gui/res/cardsfolder/c/cruel_deceiver.txt b/forge-gui/res/cardsfolder/c/cruel_deceiver.txt index f49bee0b38f..290a98c91ca 100644 --- a/forge-gui/res/cardsfolder/c/cruel_deceiver.txt +++ b/forge-gui/res/cardsfolder/c/cruel_deceiver.txt @@ -4,7 +4,7 @@ Types:Creature Spirit PT:2/1 A:AB$ PeekAndReveal | Cost$ 1 | NoReveal$ True | SpellDescription$ Look at the top card of your library. A:AB$ PeekAndReveal | Cost$ 2 | ActivationLimit$ 1 | NoPeek$ True | RememberRevealed$ True | SubAbility$ DBAnimate | SpellDescription$ Reveal the top card of your library. -SVar:DBAnimate:DB$ Animate | Defined$ Self | Triggers$ TrigDamage | sVars$ TrigDestroy | ConditionDefined$ Remembered | ConditionPresent$ Card.Land | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ If it's a land card, CARDNAME gains "Whenever CARDNAME deals damage to a creature, destroy that creature" until end of turn. +SVar:DBAnimate:DB$ Animate | Defined$ Self | Triggers$ TrigDamage | ConditionDefined$ Remembered | ConditionPresent$ Card.Land | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ If it's a land card, CARDNAME gains "Whenever CARDNAME deals damage to a creature, destroy that creature" until end of turn. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | StackDescription$ None | SpellDescription$ Activate only once each turn. SVar:TrigDamage:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever CARDNAME deals damage to a creature, destroy that creature. SVar:TrigDestroy:DB$ Destroy | Defined$ TriggeredTargetLKICopy diff --git a/forge-gui/res/cardsfolder/d/demonic_gifts.txt b/forge-gui/res/cardsfolder/d/demonic_gifts.txt index 960d0d43aa1..c7c213ae913 100644 --- a/forge-gui/res/cardsfolder/d/demonic_gifts.txt +++ b/forge-gui/res/cardsfolder/d/demonic_gifts.txt @@ -2,7 +2,7 @@ Name:Demonic Gifts ManaCost:1 B Types:Instant A:SP$ Pump | Cost$ 1 B | ValidTgts$ Creature | TgtPrompt$ Choose target creature | NumAtt$ +2 | SubAbility$ DBAnimate | SpellDescription$ Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield under its owner's control." | StackDescription$ Spelldescription -SVar:DBAnimate:DB$ Animate | Triggers$ TrigDies | sVars$ TrigReturn | Defined$ ParentTarget | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Triggers$ TrigDies | Defined$ ParentTarget | StackDescription$ None SVar:TrigDies:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When CARDNAME dies, return it to the battlefield under its owner's control. SVar:TrigReturn:DB$ ChangeZone | DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield Oracle:Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield under its owner's control." diff --git a/forge-gui/res/cardsfolder/d/driven_despair.txt b/forge-gui/res/cardsfolder/d/driven_despair.txt index dcadc2919fc..315a702bf61 100644 --- a/forge-gui/res/cardsfolder/d/driven_despair.txt +++ b/forge-gui/res/cardsfolder/d/driven_despair.txt @@ -1,7 +1,7 @@ Name:Driven ManaCost:1 G Types:Sorcery -A:SP$ AnimateAll | Cost$ 1 G | ValidCards$ Creature.YouCtrl | Keywords$ Trample | Triggers$ Trig1 | sVars$ Eff1 | StackDescription$ SpellDescription | SpellDescription$ Until end of turn, creatures you control gain trample and "Whenever this creature deals combat damage to a player, draw a card." +A:SP$ AnimateAll | Cost$ 1 G | ValidCards$ Creature.YouCtrl | Keywords$ Trample | Triggers$ Trig1 | StackDescription$ SpellDescription | SpellDescription$ Until end of turn, creatures you control gain trample and "Whenever this creature deals combat damage to a player, draw a card." SVar:Trig1:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ Eff1 | CombatDamage$ True | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:Eff1:DB$ Draw | NumCards$ 1 AlternateMode:Split @@ -13,7 +13,7 @@ Name:Despair ManaCost:1 B Types:Sorcery K:Aftermath -A:SP$ AnimateAll | Cost$ 1 B | ValidCards$ Creature.YouCtrl | Keywords$ Menace | Triggers$ Trig2 | sVars$ Eff2 | StackDescription$ SpellDescription | SpellDescription$ Until end of turn, creatures you control gain menace and "Whenever this creature deals combat damage to a player, that player discards a card." +A:SP$ AnimateAll | Cost$ 1 B | ValidCards$ Creature.YouCtrl | Keywords$ Menace | Triggers$ Trig2 | StackDescription$ SpellDescription | SpellDescription$ Until end of turn, creatures you control gain menace and "Whenever this creature deals combat damage to a player, that player discards a card." SVar:Trig2:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ Eff2 | CombatDamage$ True | TriggerDescription$ Whenever this creature deals combat damage to a player, that player discards a card. SVar:Eff2:DB$ Discard | Defined$ TriggeredTarget | NumCards$ 1 | Mode$ TgtChoose Oracle:Aftermath (Cast this spell only from your graveyard. Then exile it.)\nUntil end of turn, creatures you control gain menace and "Whenever this creature deals combat damage to a player, that player discards a card." diff --git a/forge-gui/res/cardsfolder/f/flash_conscription.txt b/forge-gui/res/cardsfolder/f/flash_conscription.txt index a136f6a19a9..2123790c872 100644 --- a/forge-gui/res/cardsfolder/f/flash_conscription.txt +++ b/forge-gui/res/cardsfolder/f/flash_conscription.txt @@ -2,7 +2,7 @@ Name:Flash Conscription ManaCost:5 R Types:Instant A:SP$ GainControl | Cost$ 5 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | AddKWs$ Haste | LoseControl$ EOT | Untap$ True | SubAbility$ DBAnimate | SpellDescription$ Untap target creature and gain control of it until end of turn. That creature gains haste until end of turn. If {W} was spent to cast this spell, the creature gains "Whenever this creature deals combat damage, you gain that much life" until end of turn. -SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ TrigDamage | sVars$ GainLife,X | ConditionManaSpent$ W +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ TrigDamage | ConditionManaSpent$ W SVar:TrigDamage:Mode$ DamageDealtOnce | CombatDamage$ True | ValidSource$ Card.Self | Execute$ GainLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever this creature deals combat damage, you gain that much life. SVar:GainLife:DB$ GainLife | LifeAmount$ X SVar:X:TriggerCount$DamageAmount diff --git a/forge-gui/res/cardsfolder/g/genju_of_the_fields.txt b/forge-gui/res/cardsfolder/g/genju_of_the_fields.txt index eef60aac1c5..a5f0e89940f 100644 --- a/forge-gui/res/cardsfolder/g/genju_of_the_fields.txt +++ b/forge-gui/res/cardsfolder/g/genju_of_the_fields.txt @@ -3,7 +3,7 @@ ManaCost:W Types:Enchantment Aura K:Enchant Plains A:SP$ Attach | Cost$ W | ValidTgts$ Plains | AILogic$ Pump -A:AB$ Animate | Cost$ 2 | Defined$ Enchanted | Power$ 2 | Toughness$ 5 | Types$ Creature,Spirit | Colors$ White | Triggers$ PseudoLifelink | sVars$ GenjuTrigGain,GenjuX | SpellDescription$ Until end of turn, enchanted Plains becomes a 2/5 white Spirit creature with "Whenever this creature deals damage, its controller gains that much life." It's still a land. +A:AB$ Animate | Cost$ 2 | Defined$ Enchanted | Power$ 2 | Toughness$ 5 | Types$ Creature,Spirit | Colors$ White | Triggers$ PseudoLifelink | SpellDescription$ Until end of turn, enchanted Plains becomes a 2/5 white Spirit creature with "Whenever this creature deals damage, its controller gains that much life." It's still a land. T:Mode$ ChangesZone | ValidCard$ Card.AttachedBy | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigReturnOwner | OptionalDecider$ You | TriggerDescription$ When enchanted Plains is put into a graveyard, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturnOwner:DB$ ChangeZone | Defined$ Self | Origin$ Graveyard | Destination$ Hand SVar:PseudoLifelink:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ GenjuTrigGain | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, you gain that much life. diff --git a/forge-gui/res/cardsfolder/g/glyph_of_delusion.txt b/forge-gui/res/cardsfolder/g/glyph_of_delusion.txt index fa50238cd5b..be7577bfaac 100644 --- a/forge-gui/res/cardsfolder/g/glyph_of_delusion.txt +++ b/forge-gui/res/cardsfolder/g/glyph_of_delusion.txt @@ -4,7 +4,7 @@ Types:Instant A:SP$ Pump | Cost$ U | ValidTgts$ Wall.blockedThisTurn | TgtPrompt$ Select target Wall that blocked this turn | SubAbility$ DBPutCounter | StackDescription$ SpellDescription | SpellDescription$ Put X glyph counters on target creature that target Wall blocked this turn, where X is the power of that blocked creature. The creature gains "This creature doesn't untap during your untap step if it has a glyph counter on it" and "At the beginning of your upkeep, remove a glyph counter from this creature." SVar:DBPutCounter:DB$ PutCounter | CounterType$ GLYPH | CounterNum$ X | ValidTgts$ Creature.blockedByValidThisTurn ParentTarget | TgtPrompt$ Select target creature blocked by target Wall this turn to put counters on | SubAbility$ Delude | IsCurse$ True SVar:X:Targeted$CardPower -SVar:Delude:DB$ Animate | Defined$ ParentTarget | staticAbilities$ Delusional | Triggers$ TrigGlyphUpkeep | sVars$ LoseGlyph | Duration$ Permanent | StackDescription$ None +SVar:Delude:DB$ Animate | Defined$ ParentTarget | staticAbilities$ Delusional | Triggers$ TrigGlyphUpkeep | Duration$ Permanent | StackDescription$ None SVar:Delusional:Mode$ Continuous | Affected$ Card.Self+counters_GE1_GLYPH | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ CARDNAME doesn't untap during your untap step if it has a glyph counter on it. SVar:TrigGlyphUpkeep:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ LoseGlyph | TriggerDescription$ At the beginning of your upkeep, remove a glyph counter from CARDNAME. SVar:LoseGlyph:DB$ RemoveCounter | CounterType$ GLYPH | CounterNum$ 1 diff --git a/forge-gui/res/cardsfolder/g/gruesome_slaughter.txt b/forge-gui/res/cardsfolder/g/gruesome_slaughter.txt index e35e236d82d..c3a8e0455ea 100644 --- a/forge-gui/res/cardsfolder/g/gruesome_slaughter.txt +++ b/forge-gui/res/cardsfolder/g/gruesome_slaughter.txt @@ -1,7 +1,7 @@ Name:Gruesome Slaughter ManaCost:6 Types:Sorcery -A:SP$ AnimateAll | Cost$ 6 | ValidCards$ Creature.Colorless+YouCtrl | Abilities$ ThrowPunch | sVars$ GruesomeX | SpellDescription$ Until end of turn, colorless creatures you control gain "{T}: This creature deals damage equal to its power to target creature." +A:SP$ AnimateAll | Cost$ 6 | ValidCards$ Creature.Colorless+YouCtrl | Abilities$ ThrowPunch | SpellDescription$ Until end of turn, colorless creatures you control gain "{T}: This creature deals damage equal to its power to target creature." SVar:ThrowPunch:AB$ DealDamage | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ GruesomeX | SpellDescription$ This creature deals damage equal to its power to target creature. SVar:GruesomeX:Count$CardPower AI:RemoveDeck:Random diff --git a/forge-gui/res/cardsfolder/h/hunters_prowess.txt b/forge-gui/res/cardsfolder/h/hunters_prowess.txt index 28e7bca469b..b78b935ad28 100644 --- a/forge-gui/res/cardsfolder/h/hunters_prowess.txt +++ b/forge-gui/res/cardsfolder/h/hunters_prowess.txt @@ -2,7 +2,7 @@ Name:Hunter's Prowess ManaCost:4 G Types:Sorcery A:SP$ Pump | Cost$ 4 G | ValidTgts$ Creature | NumAtt$ 3 | NumDef$ 3 | KW$ Trample | SubAbility$ DBAnimate | SpellDescription$ Until end of turn, target creature gets +3/+3 and gains trample and "Whenever this creature deals combat damage to a player, draw that many cards." | StackDescription$ SpellDescription -SVar:DBAnimate:DB$ Animate | Defined$ ParentTarget | Triggers$ HunterProwessTrig | sVars$ HunterProwessX,HunterProwessY | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Defined$ ParentTarget | Triggers$ HunterProwessTrig | StackDescription$ None SVar:HunterProwessTrig:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ HunterProwessX | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, draw that many cards. SVar:HunterProwessX:DB$ Draw | Defined$ You | NumCards$ HunterProwessY SVar:HunterProwessY:TriggerCount$DamageAmount diff --git a/forge-gui/res/cardsfolder/l/launch_the_fleet.txt b/forge-gui/res/cardsfolder/l/launch_the_fleet.txt index 280d10ddf90..ab1045278a7 100644 --- a/forge-gui/res/cardsfolder/l/launch_the_fleet.txt +++ b/forge-gui/res/cardsfolder/l/launch_the_fleet.txt @@ -2,7 +2,7 @@ Name:Launch the Fleet ManaCost:W Types:Sorcery K:Strive:1 -A:SP$ Animate | Cost$ W | TargetMin$ 0 | TargetMax$ MaxTargets | AILogic$ Attacking | ValidTgts$ Creature | Triggers$ AttackTrigger | sVars$ LaunchTokenAttacking | SpellDescription$ Until end of turn, any number of target creatures each gain "Whenever this creature attacks, create a 1/1 white Soldier creature token that's tapped and attacking." +A:SP$ Animate | Cost$ W | TargetMin$ 0 | TargetMax$ MaxTargets | AILogic$ Attacking | ValidTgts$ Creature | Triggers$ AttackTrigger | SpellDescription$ Until end of turn, any number of target creatures each gain "Whenever this creature attacks, create a 1/1 white Soldier creature token that's tapped and attacking." SVar:AttackTrigger:Mode$ Attacks | ValidCard$ Card.Self | Execute$ LaunchTokenAttacking | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, create a 1/1 white Soldier creature token that's tapped and attacking. SVar:LaunchTokenAttacking:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_soldier | TokenOwner$ You | TokenAttacking$ True | TokenTapped$ True SVar:MaxTargets:Count$Valid Creature diff --git a/forge-gui/res/cardsfolder/m/malakir_rebirth_malakir_mire.txt b/forge-gui/res/cardsfolder/m/malakir_rebirth_malakir_mire.txt index 906201dae88..4ede1408b67 100644 --- a/forge-gui/res/cardsfolder/m/malakir_rebirth_malakir_mire.txt +++ b/forge-gui/res/cardsfolder/m/malakir_rebirth_malakir_mire.txt @@ -2,7 +2,7 @@ Name:Malakir Rebirth ManaCost:B Types:Instant A:SP$ LoseLife | Cost$ B | Defined$ You | LifeAmount$ 2 | SubAbility$ DBAnimate | SpellDescription$ Choose target creature. You lose 2 life. Until end of turn, that creature gains "When this creature dies, return it to the battlefield tapped under its owner's control." -SVar:DBAnimate:DB$ Animate | ValidTgts$ Creature | TgtPrompt$ Choose target creature | Triggers$ TrigDies | sVars$ TrigReturn | StackDescription$ Until end of turn, {c:Targeted} gains "When this creature dies, return it to the battlefield tapped under its owner's control." +SVar:DBAnimate:DB$ Animate | ValidTgts$ Creature | TgtPrompt$ Choose target creature | Triggers$ TrigDies | StackDescription$ Until end of turn, {c:Targeted} gains "When this creature dies, return it to the battlefield tapped under its owner's control." SVar:TrigDies:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigReturn | TriggerDescription$ When CARDNAME dies, return it to the battlefield tapped under its owner's control. SVar:TrigReturn:DB$ ChangeZone | DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True AlternateMode:Modal diff --git a/forge-gui/res/cardsfolder/m/martyrdom.txt b/forge-gui/res/cardsfolder/m/martyrdom.txt index 7c86d17580e..7e3542d529e 100644 --- a/forge-gui/res/cardsfolder/m/martyrdom.txt +++ b/forge-gui/res/cardsfolder/m/martyrdom.txt @@ -1,7 +1,7 @@ Name:Martyrdom ManaCost:1 W W Types:Instant -A:SP$ Animate | Cost$ 1 W W | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Abilities$ Martyr | sVars$ DamageEvent,DamageEventDmg,IsCreature | StackDescription$ Until end of turn, {c:Targeted} gains "{0}: The next 1 damage that would be dealt to target creature, planeswalker, or player this turn is dealt to this creature instead." | SpellDescription$ Until end of turn, target creature you control gains "{0}: The next 1 damage that would be dealt to target creature, planeswalker, or player this turn is dealt to this creature instead." Only you may activate this ability. +A:SP$ Animate | Cost$ 1 W W | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | Abilities$ Martyr | StackDescription$ Until end of turn, {c:Targeted} gains "{0}: The next 1 damage that would be dealt to target creature, planeswalker, or player this turn is dealt to this creature instead." | SpellDescription$ Until end of turn, target creature you control gains "{0}: The next 1 damage that would be dealt to target creature, planeswalker, or player this turn is dealt to this creature instead." Only you may activate this ability. SVar:Martyr:AB$ Effect | Name$ Martyrdom Effect | Cost$ 0 | Activator$ Player.IsRemembered | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target to redirect damage from | Amount$ 1 | ReplacementEffects$ DamageEvent | Duration$ UntilHostLeavesPlayOrEOT | RememberObjects$ You,Targeted | ImprintCards$ Self | ExileOnMoved$ Battlefield | StackDescription$ The next 1 damage that would be dealt to {c:Targeted}{p:Targeted} this turn is dealt to {c:Self} instead. | SpellDescription$ The next 1 damage that would be dealt to target creature, planeswalker, or player this turn is dealt to CARDNAME instead. SVar:DamageEvent:Event$ DamageDone | IsPresent$ Card.IsImprinted+Creature | ValidTarget$ Player.IsRemembered,Card.IsRemembered | ReplaceWith$ DamageEventDmg | DamageTarget$ Imprinted | Description$ The next 1 damage that would be dealt to this target this turn is dealt to EFFECTSOURCE instead. SVar:DamageEventDmg:DB$ ReplaceSplitDamage | DamageTarget$ Imprinted diff --git a/forge-gui/res/cardsfolder/m/mindbender_spores.txt b/forge-gui/res/cardsfolder/m/mindbender_spores.txt index 72156e7329f..988909535f4 100644 --- a/forge-gui/res/cardsfolder/m/mindbender_spores.txt +++ b/forge-gui/res/cardsfolder/m/mindbender_spores.txt @@ -6,7 +6,7 @@ K:Defender K:Flying T:Mode$ AttackerBlocked | ValidCard$ Creature | ValidBlocker$ Card.Self | Execute$ AddSpores | TriggerDescription$ Whenever CARDNAME blocks a creature, put four fungus counters on that creature. The creature gains "This creature doesn't untap during your untap step if it has a fungus counter on it" and "At the beginning of your upkeep, remove a fungus counter from this creature." SVar:AddSpores:DB$ PutCounter | CounterType$ FUNGUS | CounterNum$ 4 | Defined$ TriggeredAttackerLKICopy | SubAbility$ AddFungalEffects -SVar:AddFungalEffects:DB$ Animate | Defined$ TriggeredAttacker | staticAbilities$ FungalFunk | Triggers$ TrigSporeUpkeep | sVars$ LoseSpores | Duration$ Permanent +SVar:AddFungalEffects:DB$ Animate | Defined$ TriggeredAttacker | staticAbilities$ FungalFunk | Triggers$ TrigSporeUpkeep | Duration$ Permanent SVar:FungalFunk:Mode$ Continuous | Affected$ Card.Self+counters_GE1_FUNGUS | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ CARDNAME doesn't untap during your untap step if it has a fungus counter on it. SVar:TrigSporeUpkeep:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ LoseSpores | TriggerDescription$ At the beginning of your upkeep, remove a fungus counter from CARDNAME. SVar:LoseSpores:DB$ RemoveCounter | CounterType$ FUNGUS | CounterNum$ 1 diff --git a/forge-gui/res/cardsfolder/m/musician.txt b/forge-gui/res/cardsfolder/m/musician.txt index b7f5d2b55d1..4640fdc1bbc 100644 --- a/forge-gui/res/cardsfolder/m/musician.txt +++ b/forge-gui/res/cardsfolder/m/musician.txt @@ -4,7 +4,7 @@ Types:Creature Human Wizard PT:1/3 K:Cumulative upkeep:1 A:AB$ PutCounter | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | IsCurse$ True | CounterType$ MUSIC | CounterNum$ 1 | SubAbility$ PayThePiper | SpellDescription$ Put a music counter on target creature. If it doesn't have "At the beginning of your upkeep, destroy this creature unless you pay {1} for each music counter on it," it gains that ability. -SVar:PayThePiper:DB$ Animate | Defined$ Targeted | Duration$ Permanent | Keywords$ At the beginning of your upkeep, destroy this creature unless you pay {1} for each music counter on it | Triggers$ TrigMusicianPay | sVars$ MusiciansSpite,MusicX | ConditionDefined$ Targeted | ConditionPresent$ Card.withoutAt the beginning of your upkeep, destroy this creature unless you pay {1} for each music counter on it | ConditionCompare$ GE1 +SVar:PayThePiper:DB$ Animate | Defined$ Targeted | Duration$ Permanent | Keywords$ At the beginning of your upkeep, destroy this creature unless you pay {1} for each music counter on it | Triggers$ TrigMusicianPay | ConditionDefined$ Targeted | ConditionPresent$ Card.withoutAt the beginning of your upkeep, destroy this creature unless you pay {1} for each music counter on it | ConditionCompare$ GE1 #The keyword added does nothing itself other than create a keyword string to check against in the conditional SVar:TrigMusicianPay:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ MusiciansSpite | Secondary$ True | TriggerDescription$ At the beginning of your upkeep, destroy this creature unless you pay 1 for each music counter on it. SVar:MusiciansSpite:DB$ Destroy | Defined$ Self | UnlessCost$ MusicX | UnlessPayer$ You diff --git a/forge-gui/res/cardsfolder/n/necravolver.txt b/forge-gui/res/cardsfolder/n/necravolver.txt index b4640161e02..17552bec7c1 100644 --- a/forge-gui/res/cardsfolder/n/necravolver.txt +++ b/forge-gui/res/cardsfolder/n/necravolver.txt @@ -8,7 +8,7 @@ K:ETBReplacement:Other:VolverPumped:Mandatory::Card.Self+kicked 2 SVar:VolverStrength:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 | ETB$ True | SubAbility$ VolverStomp | SpellDescription$ If CARDNAME was kicked with its {1}{G} kicker, it enters the battlefield with two +1/+1 counters on it and with trample. SVar:VolverStomp:DB$ Animate | Defined$ Self | Keywords$ Trample | Duration$ Permanent SVar:VolverPumped:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ETB$ True | SubAbility$ VolverLife | SpellDescription$ If CARDNAME was kicked with its {W} kicker, it enters the battlefield with a +1/+1 counter on it and with "Whenever CARDNAME deals damage, you gain that much life." -SVar:VolverLife:DB$ Animate | Defined$ Self | Triggers$ PseudoLifelink | sVars$ VolverTrigGain,VolverX | Duration$ Permanent +SVar:VolverLife:DB$ Animate | Defined$ Self | Triggers$ PseudoLifelink | Duration$ Permanent SVar:PseudoLifelink:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ VolverTrigGain | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, you gain that much life. SVar:VolverTrigGain:DB$ GainLife | Defined$ You | LifeAmount$ VolverX SVar:VolverX:TriggerCount$DamageAmount diff --git a/forge-gui/res/cardsfolder/n/nimble_trapfinder.txt b/forge-gui/res/cardsfolder/n/nimble_trapfinder.txt index 383c5b2b219..da333a1829f 100644 --- a/forge-gui/res/cardsfolder/n/nimble_trapfinder.txt +++ b/forge-gui/res/cardsfolder/n/nimble_trapfinder.txt @@ -5,7 +5,7 @@ PT:2/1 S:Mode$ Continuous | Affected$ Card.Self | AddHiddenKeyword$ Unblockable | CheckSVar$ JoinedParty | SVarCompare$ GE1 | Description$ CARDNAME can't be blocked if you had another Cleric, Rogue, Warrior, or Wizard enter the battlefield under your control this turn. SVar:JoinedParty:Count$ThisTurnEntered_Battlefield_Cleric.YouCtrl+Other,Rogue.YouCtrl+Other,Warrior.YouCtrl+Other,Wizard.YouCtrl+Other T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ EQ4 | Execute$ TrigAnimateAll | TriggerDescription$ At the beginning of combat on your turn, if you have a full party, creatures you control gain "Whenever this creature deals combat damage to a player, draw a card" until end of turn. -SVar:TrigAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ TrigCDPlayer | sVars$ TrigDraw +SVar:TrigAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ TrigCDPlayer SVar:TrigCDPlayer:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, draw a card. SVar:TrigDraw:DB$ Draw | NumCards$ 1 SVar:X:Count$Party diff --git a/forge-gui/res/cardsfolder/o/open_into_wonder.txt b/forge-gui/res/cardsfolder/o/open_into_wonder.txt index ca3add5e32b..cfbf55598b5 100644 --- a/forge-gui/res/cardsfolder/o/open_into_wonder.txt +++ b/forge-gui/res/cardsfolder/o/open_into_wonder.txt @@ -2,7 +2,7 @@ Name:Open into Wonder ManaCost:X U U Types:Sorcery A:SP$ Pump | Cost$ X U U | ValidTgts$ Creature | KW$ HIDDEN Unblockable | AILogic$ Pump | TargetMin$ X | TargetMax$ X | TgtPrompt$ Select X target creatures | SubAbility$ DBAnimate | StackDescription$ X target creatures [{c:Targeted}] can't be blocked this turn. Until end of turn, those creatures gain "Whenever this creature deals combat damage to a player, draw a card." | SpellDescription$ X target creatures can't be blocked this turn. Until end of turn, those creatures gain "Whenever this creature deals combat damage to a player, draw a card." -SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ OpenIntoWonderTrigger | sVars$ OpenIntoWonderDraw | StackDescription$ None +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ OpenIntoWonderTrigger | StackDescription$ None SVar:OpenIntoWonderTrigger:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ OpenIntoWonderDraw | CombatDamage$ True | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:OpenIntoWonderDraw:DB$ Draw | NumCards$ 1 SVar:X:Count$xPaid diff --git a/forge-gui/res/cardsfolder/r/rakavolver.txt b/forge-gui/res/cardsfolder/r/rakavolver.txt index 4722f7c397b..520d1714eb5 100644 --- a/forge-gui/res/cardsfolder/r/rakavolver.txt +++ b/forge-gui/res/cardsfolder/r/rakavolver.txt @@ -6,7 +6,7 @@ K:Kicker:1 W:U K:ETBReplacement:Other:VolverStrength:Mandatory::Card.Self+kicked 1 K:ETBReplacement:Other:VolverPumped:Mandatory::Card.Self+kicked 2 SVar:VolverStrength:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 | ETB$ True | SubAbility$ VolverLife | SpellDescription$ If CARDNAME was kicked with its {1}{W} kicker, it enters the battlefield with two +1/+1 counters on it and with "Whenever CARDNAME deals damage, you gain that much life." -SVar:VolverLife:DB$ Animate | Defined$ Self | Triggers$ PseudoLifelink | sVars$ VolverTrigGain,VolverX | Duration$ Permanent +SVar:VolverLife:DB$ Animate | Defined$ Self | Triggers$ PseudoLifelink | Duration$ Permanent SVar:PseudoLifelink:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ VolverTrigGain | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, you gain that much life. SVar:VolverTrigGain:DB$ GainLife | Defined$ You | LifeAmount$ VolverX SVar:VolverX:TriggerCount$DamageAmount diff --git a/forge-gui/res/cardsfolder/s/shackles_of_treachery.txt b/forge-gui/res/cardsfolder/s/shackles_of_treachery.txt index 5a2bf5fcea6..f3e5596c493 100644 --- a/forge-gui/res/cardsfolder/s/shackles_of_treachery.txt +++ b/forge-gui/res/cardsfolder/s/shackles_of_treachery.txt @@ -2,7 +2,7 @@ Name:Shackles of Treachery ManaCost:2 R Types:Sorcery A:SP$ GainControl | Cost$ 2 R | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ EOT | Untap$ True | AddKWs$ Haste | SubAbility$ DBAnimate | SpellDescription$ Gain control of target creature until end of turn. Untap that creature. Until end of turn, it gains haste and "Whenever this creature deals damage, destroy target Equipment attached to it." -SVar:DBAnimate:DB$ Animate | Defined$ ParentTarget | Triggers$ Shackles | sVars$ TrigDestroy +SVar:DBAnimate:DB$ Animate | Defined$ ParentTarget | Triggers$ Shackles SVar:Shackles:Mode$ DamageDone | ValidSource$ Card.Self | Execute$ TrigDestroy | TriggerDescription$ Whenever this creature deals damage, destroy target Equipment attached to it. SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Equipment.Attached | TgtPrompt$ Select target Equipment attached to the creature Oracle:Gain control of target creature until end of turn. Untap that creature. Until end of turn, it gains haste and "Whenever this creature deals damage, destroy target Equipment attached to it." diff --git a/forge-gui/res/cardsfolder/s/showstopper.txt b/forge-gui/res/cardsfolder/s/showstopper.txt index c3e937b03fc..cdb30f04798 100644 --- a/forge-gui/res/cardsfolder/s/showstopper.txt +++ b/forge-gui/res/cardsfolder/s/showstopper.txt @@ -1,7 +1,7 @@ Name:Showstopper ManaCost:1 B R Types:Instant -A:SP$ AnimateAll | Cost$ 1 B R | ValidCards$ Creature.YouCtrl | Triggers$ DiesTrigger | sVars$ ShowstopperTrigDamage | SpellDescription$ Until end of turn, creatures you control gain "When this creature dies, it deals 2 damage to target creature an opponent controls." +A:SP$ AnimateAll | Cost$ 1 B R | ValidCards$ Creature.YouCtrl | Triggers$ DiesTrigger | SpellDescription$ Until end of turn, creatures you control gain "When this creature dies, it deals 2 damage to target creature an opponent controls." SVar:DiesTrigger:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ ShowstopperTrigDamage | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies, it deals 2 damage to target creature an opponent controls. SVar:ShowstopperTrigDamage:DB$ DealDamage | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature an opponent controls | NumDmg$ 2 AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/s/simic_basilisk.txt b/forge-gui/res/cardsfolder/s/simic_basilisk.txt index 2313c1bb12f..f94abb44ab8 100644 --- a/forge-gui/res/cardsfolder/s/simic_basilisk.txt +++ b/forge-gui/res/cardsfolder/s/simic_basilisk.txt @@ -3,7 +3,7 @@ ManaCost:4 G G Types:Creature Basilisk Mutant PT:0/0 K:Graft:3 -A:AB$ Animate | Cost$ 1 G | ValidTgts$ Creature.counters_GE1_P1P1 | TgtPrompt$ Select target creature with a +1/+1 counter on it | Triggers$ DestroyTrigger | sVars$ DelTrigSimic,TrigDestroySimic | SpellDescription$ Until end of turn, target creature with a +1/+1 counter on it gains "Whenever this creature deals combat damage to a creature, destroy that creature at end of combat." +A:AB$ Animate | Cost$ 1 G | ValidTgts$ Creature.counters_GE1_P1P1 | TgtPrompt$ Select target creature with a +1/+1 counter on it | Triggers$ DestroyTrigger | SpellDescription$ Until end of turn, target creature with a +1/+1 counter on it gains "Whenever this creature deals combat damage to a creature, destroy that creature at end of combat." SVar:DestroyTrigger:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ DelTrig | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, destroy that creature at end of combat. SVar:DelTrigSimic:DB$ DelayedTrigger | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigDestroySimic | RememberObjects$ TriggeredTargetLKICopy | TriggerDescription$ Destroy damaged creature at end of combat. SVar:TrigDestroySimic:DB$ Destroy | Defined$ DelayTriggerRememberedLKI diff --git a/forge-gui/res/cardsfolder/s/stir_the_pride.txt b/forge-gui/res/cardsfolder/s/stir_the_pride.txt index 315fa61b9db..7510b798651 100644 --- a/forge-gui/res/cardsfolder/s/stir_the_pride.txt +++ b/forge-gui/res/cardsfolder/s/stir_the_pride.txt @@ -4,7 +4,7 @@ Types:Instant K:Entwine:1 W A:SP$ Charm | Cost$ 4 W | Choices$ DBPumpAll,DBAnimateAll | CharmNum$ 1 SVar:DBPumpAll:DB$ PumpAll | NumAtt$ 2 | NumDef$ 2 | ValidCards$ Creature.YouCtrl | SpellDescription$ Creatures you control get +2/+2 until end of turn. -SVar:DBAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ TrigPrideDamage | sVars$ GainLife,GainLifeX | SpellDescription$ Until end of turn, creatures you control gain "Whenever this creature deals damage, you gain that much life." +SVar:DBAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ TrigPrideDamage | SpellDescription$ Until end of turn, creatures you control gain "Whenever this creature deals damage, you gain that much life." SVar:TrigPrideDamage:Mode$ DamageDealtOnce | ValidSource$ Card.Self | Execute$ GainLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals damage, you gain that much life. SVar:GainLife:DB$ GainLife | LifeAmount$ GainLifeX SVar:GainLifeX:TriggerCount$DamageAmount diff --git a/forge-gui/res/cardsfolder/s/storm_the_citadel.txt b/forge-gui/res/cardsfolder/s/storm_the_citadel.txt index 6cd8a430994..4fc471ee9a1 100644 --- a/forge-gui/res/cardsfolder/s/storm_the_citadel.txt +++ b/forge-gui/res/cardsfolder/s/storm_the_citadel.txt @@ -2,7 +2,7 @@ Name:Storm the Citadel ManaCost:4 G Types:Sorcery A:SP$ PumpAll | Cost$ 4 G | ValidCards$ Creature.YouCtrl | NumAtt$ 2 | NumDef$ 2 | SubAbility$ DBAnimateAll | SpellDescription$ Until end of turn, creatures you control get +2/+2 and gain "Whenever this creature deals combat damage to a player or planeswalker, destroy target artifact or enchantment defending player controls." -SVar:DBAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ Trig | sVars$ Eff +SVar:DBAnimateAll:DB$ AnimateAll | ValidCards$ Creature.YouCtrl | Triggers$ Trig SVar:Trig:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player,Planeswalker | CombatDamage$ True | Execute$ Eff | TriggerDescription$ Whenever this creature deals combat damage to a player or planeswalker, destroy target artifact or enchantment defending player controls. SVar:Eff:DB$ Destroy | ValidTgts$ Artifact,Enchantment | TargetsWithDefinedController$ TriggeredDefendingPlayer | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target artifact or enchantment defending player controls. SVar:PlayMain1:TRUE diff --git a/forge-gui/res/cardsfolder/s/supernatural_stamina.txt b/forge-gui/res/cardsfolder/s/supernatural_stamina.txt index f4ad6b71214..298a3f96ebf 100644 --- a/forge-gui/res/cardsfolder/s/supernatural_stamina.txt +++ b/forge-gui/res/cardsfolder/s/supernatural_stamina.txt @@ -2,7 +2,7 @@ Name:Supernatural Stamina ManaCost:B Types:Instant A:SP$ Pump | Cost$ B | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +2 | SpellDescription$ Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control." | SubAbility$ DBAnimate -SVar:DBAnimate:DB$ Animate | Triggers$ SupernaturalStaminaChangeZone | sVars$ SupernaturalStaminaTrigChangeZone | Defined$ ParentTarget +SVar:DBAnimate:DB$ Animate | Triggers$ SupernaturalStaminaChangeZone | Defined$ ParentTarget SVar:SupernaturalStaminaChangeZone:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ SupernaturalStaminaTrigChangeZone | TriggerController$ TriggeredCardController | TriggerDescription$ When this creature dies, return it to the battlefield tapped under its owner's control. SVar:SupernaturalStaminaTrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Tapped$ True | Defined$ TriggeredNewCardLKICopy Oracle:Until end of turn, target creature gets +2/+0 and gains "When this creature dies, return it to the battlefield tapped under its owner's control." diff --git a/forge-gui/res/cardsfolder/t/tenacious_pup.txt b/forge-gui/res/cardsfolder/t/tenacious_pup.txt index 8142f67aceb..981c17ee6ec 100644 --- a/forge-gui/res/cardsfolder/t/tenacious_pup.txt +++ b/forge-gui/res/cardsfolder/t/tenacious_pup.txt @@ -5,10 +5,10 @@ PT:1/2 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGainLife | TriggerDescription$ When CARDNAME enters the battlefield, you gain 1 life. When you cast your next creature spell, that creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it. SVar:TrigGainLife:DB$ GainLife | LifeAmount$ 1 | SubAbility$ DBDelayedTrigger SVar:DBDelayedTrigger:DB$ DelayedTrigger | Execute$ TrigAddAPI | Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerDescription$ When you cast your next creature spell, that creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it. -SVar:TrigAddAPI:DB$ Animate | Defined$ TriggeredCard | sVars$ AddExtraCounter,DBTrample,DBVigilance | SubAbility$ DBAddETBRep -SVar:DBAddETBRep:DB$ Animate | Defined$ TriggeredCard | Keywords$ ETBReplacement:Other:AddExtraCounter:Mandatory:Battlefield:Card.Self -SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBTrample -SVar:DBTrample:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ Trample | CounterNum$ 1 | SubAbility$ DBVigilance -SVar:DBVigilance:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterType$ Vigilance | CounterNum$ 1 +SVar:TrigAddAPI:DB$ Effect | RememberObjects$ TriggeredCard | ForgetOnMoved$ Stack | ReplacementEffects$ ReplaceEnter +SVar:ReplaceEnter:Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | ReplaceWith$ AddExtraCounter | Description$ That creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it. +SVar:AddExtraCounter:DB$ PutCounter | ETB$ True | Defined$ ReplacedCard | CounterTypes$ P1P1,Trample,Vigilance | CounterNum$ 1 | SubAbility$ ToBattlefield +SVar:ToBattlefield:DB$ InternalEtbReplacement | SubAbility$ DBExile +SVar:DBExile:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile DeckHas:Ability$LifeGain|Counters Oracle:When Tenacious Pup enters the battlefield, you gain 1 life. When you cast your next creature spell, that creature enters the battlefield with an additional +1/+1 counter, trample counter, and vigilance counter on it. diff --git a/forge-gui/res/cardsfolder/t/tower_above.txt b/forge-gui/res/cardsfolder/t/tower_above.txt index d623ff5da41..b700778e426 100644 --- a/forge-gui/res/cardsfolder/t/tower_above.txt +++ b/forge-gui/res/cardsfolder/t/tower_above.txt @@ -2,7 +2,7 @@ Name:Tower Above ManaCost:2/G 2/G 2/G Types:Sorcery A:SP$ Pump | Cost$ 2G 2G 2G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 4 | NumDef$ 4 | KW$ Trample & Wither | SubAbility$ DBAnimate | SpellDescription$ Until end of turn, target creature gets +4/+4 and gains trample, wither, and "When this creature attacks, target creature blocks it this turn if able." (It deals damage to creatures in the form of -1/-1 counters.) -SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ TrigAttack | sVars$ TowerAboveTrigBlock +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Triggers$ TrigAttack SVar:TrigAttack:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TowerAboveTrigBlock | TriggerDescription$ Whenever CARDNAME attacks, target creature blocks it this turn if able SVar:TowerAboveTrigBlock:DB$ MustBlock | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able. Oracle:({2/G} can be paid with any two mana or with {G}. This card's mana value is 6.)\nUntil end of turn, target creature gets +4/+4 and gains trample, wither, and "When this creature attacks, target creature blocks it this turn if able." (It deals damage to creatures in the form of -1/-1 counters.) diff --git a/forge-gui/res/cardsfolder/v/verdant_rebirth.txt b/forge-gui/res/cardsfolder/v/verdant_rebirth.txt index da62320eef9..e3f6a2b917e 100644 --- a/forge-gui/res/cardsfolder/v/verdant_rebirth.txt +++ b/forge-gui/res/cardsfolder/v/verdant_rebirth.txt @@ -1,7 +1,7 @@ Name:Verdant Rebirth ManaCost:1 G Types:Instant -A:SP$ Animate | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | Triggers$ VerdantRebirthChangeZone | sVars$ VerdantRebirthTrigChangeZone | SubAbility$ DBDraw | SpellDescription$ Until end of turn, target creature gains "When this creature dies, return it to its owner's hand." Draw a card. +A:SP$ Animate | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | Triggers$ VerdantRebirthChangeZone | SubAbility$ DBDraw | SpellDescription$ Until end of turn, target creature gains "When this creature dies, return it to its owner's hand." Draw a card. SVar:VerdantRebirthChangeZone:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ VerdantRebirthTrigChangeZone | TriggerController$ TriggeredCardController | TriggerDescription$ When this creature dies, return it to its owner's hand. SVar:VerdantRebirthTrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Defined$ TriggeredNewCardLKICopy SVar:DBDraw:DB$ Draw | NumCards$ 1 diff --git a/forge-gui/res/cardsfolder/v/vraska_scheming_gorgon.txt b/forge-gui/res/cardsfolder/v/vraska_scheming_gorgon.txt index fc033db1321..adc8bae1c3a 100644 --- a/forge-gui/res/cardsfolder/v/vraska_scheming_gorgon.txt +++ b/forge-gui/res/cardsfolder/v/vraska_scheming_gorgon.txt @@ -4,7 +4,7 @@ Types:Legendary Planeswalker Vraska Loyalty:5 A:AB$ PumpAll | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ValidCards$ Creature.YouCtrl | NumAtt$ +1 | SpellDescription$ Creatures you control get +1/+0 until end of turn. A:AB$ Destroy | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Destroy target creature. -A:AB$ AnimateAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Creature.YouCtrl | Keywords$ Deathtouch | Triggers$ Trig | sVars$ Eff | SpellDescription$ Until end of turn, creatures you control gain deathtouch and "Whenever this creature deals damage to an opponent, that player loses the game." +A:AB$ AnimateAll | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidCards$ Creature.YouCtrl | Keywords$ Deathtouch | Triggers$ Trig | SpellDescription$ Until end of turn, creatures you control gain deathtouch and "Whenever this creature deals damage to an opponent, that player loses the game." SVar:Trig:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | Execute$ Eff | TriggerDescription$ Whenever this creature deals damage to an opponent, that player loses the game. SVar:Eff:DB$ LosesGame | Defined$ TriggeredTarget SVar:PlayMain1:TRUE diff --git a/forge-gui/res/cardsfolder/v/vraska_the_unseen.txt b/forge-gui/res/cardsfolder/v/vraska_the_unseen.txt index dc18dd105c2..8af952e8eb6 100644 --- a/forge-gui/res/cardsfolder/v/vraska_the_unseen.txt +++ b/forge-gui/res/cardsfolder/v/vraska_the_unseen.txt @@ -2,7 +2,7 @@ Name:Vraska the Unseen ManaCost:3 B G Types:Legendary Planeswalker Vraska Loyalty:5 -A:AB$ Animate | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ Self | Triggers$ TrigVraska | sVars$ VraskaGaze | Duration$ UntilYourNextTurn | AILogic$ EOT | SpellDescription$ Until your next turn, whenever a creature deals combat damage to CARDNAME, destroy that creature. | StackDescription$ Until your next turn, whenever a creature deals combat damage to CARDNAME, destroy that creature. +A:AB$ Animate | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ Self | Triggers$ TrigVraska | Duration$ UntilYourNextTurn | AILogic$ EOT | SpellDescription$ Until your next turn, whenever a creature deals combat damage to CARDNAME, destroy that creature. | StackDescription$ Until your next turn, whenever a creature deals combat damage to CARDNAME, destroy that creature. SVar:TrigVraska:Mode$ DamageDone | ValidSource$ Creature | ValidTarget$ Card.Self | TriggerZones$ Battlefield | CombatDamage$ True | Execute$ VraskaGaze | TriggerDescription$ Until your next turn, whenever a creature deals combat damage to CARDNAME, destroy that creature. SVar:VraskaGaze:DB$ Destroy | Defined$ TriggeredSourceLKICopy A:AB$ Destroy | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | SpellDescription$ Destroy target nonland permanent. diff --git a/forge-gui/res/cardsfolder/w/warriors_lesson.txt b/forge-gui/res/cardsfolder/w/warriors_lesson.txt index a70d6ecb3aa..3ed0d0de144 100644 --- a/forge-gui/res/cardsfolder/w/warriors_lesson.txt +++ b/forge-gui/res/cardsfolder/w/warriors_lesson.txt @@ -1,7 +1,7 @@ Name:Warriors' Lesson ManaCost:G Types:Instant -A:SP$ Animate | Cost$ G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | TargetMin$ 0 | TargetMax$ 2 | Triggers$ WarriorLessonDmg | sVars$ WarriorLessonDraw | SpellDescription$ Until end of turn, up to two target creatures you control each gain "Whenever this creature deals combat damage to a player, draw a card." +A:SP$ Animate | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | TargetMin$ 0 | TargetMax$ 2 | Triggers$ WarriorLessonDmg | SpellDescription$ Until end of turn, up to two target creatures you control each gain "Whenever this creature deals combat damage to a player, draw a card." SVar:WarriorLessonDmg:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ WarriorLessonDraw | TriggerDescription$ Whenever this creature deals combat damage to a player, draw a card. SVar:WarriorLessonDraw:DB$ Draw | Defined$ You | NumCards$ 1 AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/w/whipgrass_entangler.txt b/forge-gui/res/cardsfolder/w/whipgrass_entangler.txt index 52d0caa6d92..a27a22b878a 100644 --- a/forge-gui/res/cardsfolder/w/whipgrass_entangler.txt +++ b/forge-gui/res/cardsfolder/w/whipgrass_entangler.txt @@ -2,7 +2,7 @@ Name:Whipgrass Entangler ManaCost:2 W Types:Creature Human Cleric PT:1/3 -A:AB$ Animate | Cost$ 1 W | ValidTgts$ Creature | staticAbilities$ WhipgrassCantAttack,WhipgrassCantBlock | sVars$ WhipgrassClericNum | SpellDescription$ Until end of turn, target creature gains "This creature can't attack or block unless its controller pays {1} for each Cleric on the battlefield." +A:AB$ Animate | Cost$ 1 W | ValidTgts$ Creature | staticAbilities$ WhipgrassCantAttack,WhipgrassCantBlock | SpellDescription$ Until end of turn, target creature gains "This creature can't attack or block unless its controller pays {1} for each Cleric on the battlefield." SVar:WhipgrassCantAttack:Mode$ CantAttackUnless | ValidCard$ Card.Self | Cost$ WhipgrassClericNum | Description$ CARDNAME can't attack or block unless you pay 1 for each Cleric on the battlefield. SVar:WhipgrassCantBlock:Mode$ CantBlockUnless | ValidCard$ Card.Self | Cost$ WhipgrassClericNum SVar:WhipgrassClericNum:Count$Valid Cleric diff --git a/forge-gui/res/cardsfolder/w/whisperwood_elemental.txt b/forge-gui/res/cardsfolder/w/whisperwood_elemental.txt index 83c143bc5fc..89eb4458473 100644 --- a/forge-gui/res/cardsfolder/w/whisperwood_elemental.txt +++ b/forge-gui/res/cardsfolder/w/whisperwood_elemental.txt @@ -4,7 +4,7 @@ Types:Creature Elemental PT:4/4 T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigManifest | TriggerDescription$ At the beginning of your end step, manifest the top card of your library. (Put it onto the battlefield face down as a 2/2 creature. Turn it face up any time for its mana cost if it's a creature card) SVar:TrigManifest:DB$ Manifest | Amount$ 1 | Defined$ TopOfLibrary -A:AB$ AnimateAll | Cost$ Sac<1/CARDNAME> | ValidCards$ Creature.YouCtrl+nonToken+faceUp | Triggers$ Trig | sVars$ WhisperwoodElementalEff | SpellDescription$ Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library." +A:AB$ AnimateAll | Cost$ Sac<1/CARDNAME> | ValidCards$ Creature.YouCtrl+nonToken+faceUp | Triggers$ Trig | SpellDescription$ Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library." SVar:Trig:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ WhisperwoodElementalEff | TriggerDescription$ When this creature dies, manifest the top card of your library. SVar:WhisperwoodElementalEff:DB$ Manifest | Amount$ 1 | Defined$ TopOfLibrary Oracle:At the beginning of your end step, manifest the top card of your library. (Put it onto the battlefield face down as a 2/2 creature. Turn it face up any time for its mana cost if it's a creature card.)\nSacrifice Whisperwood Elemental: Until end of turn, face-up nontoken creatures you control gain "When this creature dies, manifest the top card of your library." diff --git a/forge-gui/src/main/java/forge/gamemodes/puzzle/Puzzle.java b/forge-gui/src/main/java/forge/gamemodes/puzzle/Puzzle.java index d4b34e04c56..f0f2c8764ea 100644 --- a/forge-gui/src/main/java/forge/gamemodes/puzzle/Puzzle.java +++ b/forge-gui/src/main/java/forge/gamemodes/puzzle/Puzzle.java @@ -14,6 +14,7 @@ import forge.game.ability.AbilityFactory; import forge.game.card.Card; import forge.game.phase.PhaseType; import forge.game.player.Player; +import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; @@ -156,11 +157,12 @@ public class Puzzle extends GameState implements InventoryItem, Comparable