From 11913085efe87ad7970a2de305fe288e8e61130c Mon Sep 17 00:00:00 2001 From: tool4ever Date: Thu, 13 Feb 2025 15:51:19 +0100 Subject: [PATCH] Misc cleanup (#7009) --- .../java/forge/ai/ability/ChangeZoneAi.java | 47 ++++++++----------- .../src/main/java/forge/game/GameAction.java | 2 +- .../ability/effects/ChangeZoneAllEffect.java | 6 +-- .../ability/effects/ChangeZoneEffect.java | 26 ++-------- .../game/ability/effects/ManaEffect.java | 6 +-- .../game/staticability/StaticAbility.java | 6 +-- forge-gui/res/cardsfolder/a/aether_gust.txt | 2 +- .../res/cardsfolder/a/ashioks_erasure.txt | 2 +- .../res/cardsfolder/a/aven_interrupter.txt | 2 +- .../res/cardsfolder/b/brutal_expulsion.txt | 2 +- forge-gui/res/cardsfolder/c/commit_memory.txt | 2 +- .../res/cardsfolder/d/divide_by_zero.txt | 2 +- .../res/cardsfolder/e/endless_detour.txt | 2 +- .../cardsfolder/e/erestor_of_the_council.txt | 3 +- .../res/cardsfolder/e/eye_of_the_storm.txt | 2 +- .../res/cardsfolder/f/failure_comply.txt | 2 +- .../res/cardsfolder/g/gales_redirection.txt | 2 +- forge-gui/res/cardsfolder/g/guile.txt | 2 +- .../res/cardsfolder/h/hullbreaker_horror.txt | 2 +- .../res/cardsfolder/k/knowledge_pool.txt | 2 +- .../res/cardsfolder/k/krark_the_thumbless.txt | 2 +- .../res/cardsfolder/m/mindbreak_trap.txt | 2 +- .../res/cardsfolder/n/neera_wild_mage.txt | 2 +- .../res/cardsfolder/o/obscura_interceptor.txt | 2 +- .../res/cardsfolder/p/possibility_storm.txt | 2 +- .../res/cardsfolder/p/press_the_enemy.txt | 2 +- forge-gui/res/cardsfolder/r/radiant_lotus.txt | 3 +- forge-gui/res/cardsfolder/r/reprieve.txt | 2 +- forge-gui/res/cardsfolder/r/rory_williams.txt | 2 +- .../rebalanced/a-divide_by_zero.txt | 2 +- .../rebalanced/a-hullbreaker_horror.txt | 2 +- .../s/sink_into_stupor_soporific_springs.txt | 2 +- .../res/cardsfolder/s/sliver_queen_avatar.txt | 2 +- .../cardsfolder/s/smirking_spelljacker.txt | 2 +- forge-gui/res/cardsfolder/s/spell_queller.txt | 2 +- .../s/spellscorn_coven_take_it_back.txt | 2 +- forge-gui/res/cardsfolder/s/subtlety.txt | 2 +- .../res/cardsfolder/s/summary_dismissal.txt | 2 +- .../res/cardsfolder/t/talions_throneguard.txt | 2 +- .../res/cardsfolder/u/unsubstantiate.txt | 2 +- .../cardsfolder/v/venser_shaper_savant.txt | 2 +- .../gui/control/FControlGameEventHandler.java | 6 --- 42 files changed, 69 insertions(+), 102 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index e70273b8013..f6c677cfb56 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -22,7 +22,6 @@ import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; -import forge.game.spellability.SpellAbilityStackInstance; import forge.game.spellability.TargetRestrictions; import forge.game.staticability.StaticAbilityMustTarget; import forge.game.zone.ZoneType; @@ -138,8 +137,6 @@ public class ChangeZoneAi extends SpellAbilityAi { if (aiLogic != null) { if (aiLogic.equals("Always")) { return true; - } else if (aiLogic.startsWith("ExileSpell")) { - return doExileSpellLogic(aiPlayer, sa); } else if (aiLogic.startsWith("SacAndUpgrade")) { // Birthing Pod, Natural Order, etc. return doSacAndUpgradeLogic(aiPlayer, sa); } else if (aiLogic.startsWith("SacAndRetFromGrave")) { // Recurring Nightmare, etc. @@ -878,6 +875,10 @@ public class ChangeZoneAi extends SpellAbilityAi { origin.addAll(ZoneType.listValueOf(sa.getParam("TgtZone"))); } + if (origin.contains(ZoneType.Stack) && doExileSpellLogic(ai, sa, mandatory)) { + return true; + } + final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination")); final Game game = ai.getGame(); @@ -902,7 +903,6 @@ public class ChangeZoneAi extends SpellAbilityAi { } CardCollection list = CardLists.getTargetableCards(game.getCardsIn(origin), sa); - // Filter AI-specific targets if provided list = ComputerUtil.filterAITgts(sa, ai, list, true); if (sa.hasParam("AITgtsOnlyBetterThanSelf")) { list = CardLists.filter(list, card -> ComputerUtilCard.evaluateCreature(card) > ComputerUtilCard.evaluateCreature(source) + 30); @@ -2061,31 +2061,24 @@ public class ChangeZoneAi extends SpellAbilityAi { } } - private boolean doExileSpellLogic(final Player aiPlayer, final SpellAbility sa) { - String aiLogic = sa.getParamOrDefault("AILogic", ""); - SpellAbilityStackInstance top = aiPlayer.getGame().getStack().peek(); - List dangerousApi = Arrays.asList(ApiType.DealDamage, ApiType.DamageAll, ApiType.Destroy, ApiType.DestroyAll, ApiType.Sacrifice, ApiType.SacrificeAll); - int manaCost = 0; - int minCost = 0; - - if (aiLogic.contains(".")) { - minCost = Integer.parseInt(aiLogic.substring(aiLogic.indexOf(".") + 1)); + private static boolean doExileSpellLogic(final Player ai, final SpellAbility sa, final boolean mandatory) { + List dangerousApi = null; + CardCollection spells = new CardCollection(ai.getGame().getStackZone().getCards()); + Collections.reverse(spells); + if (!mandatory && !spells.isEmpty()) { + spells = spells.subList(0, 1); + spells = ComputerUtil.filterAITgts(sa, ai, spells, true); + dangerousApi = Arrays.asList(ApiType.DealDamage, ApiType.DamageAll, ApiType.Destroy, ApiType.DestroyAll, ApiType.Sacrifice, ApiType.SacrificeAll); } - if (top != null) { - SpellAbility topSA = top.getSpellAbility(); - if (topSA != null) { - if (topSA.getPayCosts().hasManaCost()) { - manaCost = topSA.getPayCosts().getTotalMana().getCMC(); - } - - if ((manaCost >= minCost || dangerousApi.contains(topSA.getApi())) - && topSA.getActivatingPlayer().isOpponentOf(aiPlayer) - && sa.canTargetSpellAbility(topSA)) { - sa.resetTargets(); - sa.getTargets().add(topSA); - return sa.isTargetNumberValid(); - } + for (Card c : spells) { + SpellAbility topSA = ai.getGame().getStack().getSpellMatchingHost(c); + if (topSA != null && (dangerousApi == null || + (dangerousApi.contains(topSA.getApi()) && topSA.getActivatingPlayer().isOpponentOf(ai))) + && sa.canTarget(topSA)) { + sa.resetTargets(); + sa.getTargets().add(topSA); + return sa.isTargetNumberValid(); } } return false; diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index fad61035d7d..d881fb66c36 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -705,7 +705,7 @@ public class GameAction { StaticAbility stAb = eff.addStaticAbility(AbilityUtils.getSVar(cause, cause.getParam("StaticEffect"))); stAb.setActiveZone(EnumSet.of(ZoneType.Command)); // needed for ETB lookahead like Bronzehide Lion - stAb.putParam("AffectedZone", "Battlefield,Hand,Graveyard,Exile,Stack,Library,Command"); + stAb.putParam("AffectedZone", "All"); SpellAbilityEffect.addForgetOnMovedTrigger(eff, "Battlefield"); game.getAction().moveToCommand(eff, cause); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java index 850dcb9b573..ce0393edf2f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java @@ -107,10 +107,8 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { final Zone originZone = game.getZoneOf(c); // Fizzle spells so that they are removed from stack (e.g. Summary Dismissal) - if (sa.hasParam("Fizzle")) { - if (originZone.is(ZoneType.Exile) || originZone.is(ZoneType.Hand) || originZone.is(ZoneType.Stack)) { - game.getStack().remove(c); - } + if (originZone.is(ZoneType.Stack)) { + game.getStack().remove(c); } if (remLKI) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 406d18b1ae7..960de03c4d2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -558,22 +558,15 @@ public class ChangeZoneEffect extends SpellAbilityEffect { continue; } + if (originZone.is(ZoneType.Stack)) { + game.getStack().remove(gameCard); + } + Card movedCard = null; Map moveParams = AbilityKey.newMap(); AbilityKey.addCardZoneTableParams(moveParams, triggerList); - if (destination.equals(ZoneType.Library)) { - // If a card is moved to library from the stack, remove its spells from the stack - if (sa.hasParam("Fizzle")) { - // TODO only AI still targets as card, try to remove it - if (gameCard.isInZone(ZoneType.Exile) || gameCard.isInZone(ZoneType.Hand) || gameCard.isInZone(ZoneType.Stack)) { - // This only fizzles spells, not anything else. - game.getStack().remove(gameCard); - } - } - - movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, sa, moveParams); - } else if (destination.equals(ZoneType.Battlefield)) { + if (destination.equals(ZoneType.Battlefield)) { moveParams.put(AbilityKey.SimultaneousETB, tgtCards); if (sa.isReplacementAbility()) { ReplacementEffect re = sa.getReplacementEffect(); @@ -725,15 +718,6 @@ public class ChangeZoneEffect extends SpellAbilityEffect { commandCards.add(movedCard); //add to list to reveal the commandzone cards } - // If a card is Exiled from the stack, remove its spells from the stack - if (sa.hasParam("Fizzle")) { - if (gameCard.isInZone(ZoneType.Exile) || gameCard.isInZone(ZoneType.Hand) - || gameCard.isInZone(ZoneType.Stack) || gameCard.isInZone(ZoneType.Command)) { - // This only fizzles spells, not anything else. - game.getStack().remove(gameCard); - } - } - if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java index 50b209c4cfe..f597439111c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java @@ -32,6 +32,7 @@ public class ManaEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { final Card card = sa.getHostCard(); + final Game game = card.getGame(); final AbilityManaPart abMana = sa.getManaPart(); final List tgtPlayers = getDefinedPlayersOrTargeted(sa); final Player activator = sa.getActivatingPlayer(); @@ -39,10 +40,7 @@ public class ManaEffect extends SpellAbilityEffect { // Spells are not undoable sa.setUndoable(sa.isAbility() && sa.isUndoable() && tgtPlayers.size() < 2 && !sa.hasParam("ActivationLimit")); - final boolean optional = sa.hasParam("Optional"); - final Game game = activator.getGame(); - - if (optional && !activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantAddMana"), null)) { + if (sa.hasParam("Optional") && !activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantAddMana"), null)) { return; } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index b5f02349962..15e91cbb38b 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -344,10 +344,8 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone if (zone == null || !this.validHostZones.contains(zone.getZoneType())) { return false; } - } else { - if (!getHostCard().isInPlay()) { // default - return false; - } + } else if (!getHostCard().isInPlay()) { // default + return false; } } diff --git a/forge-gui/res/cardsfolder/a/aether_gust.txt b/forge-gui/res/cardsfolder/a/aether_gust.txt index 824faa25d59..c0045b09f0f 100644 --- a/forge-gui/res/cardsfolder/a/aether_gust.txt +++ b/forge-gui/res/cardsfolder/a/aether_gust.txt @@ -1,6 +1,6 @@ Name:Aether Gust ManaCost:1 U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack+Red,Card.inZoneStack+Green,Permanent.Red,Permanent.Green | TgtZone$ Battlefield,Stack | TgtPrompt$ Select target spell or permanent that's red or green | AlternativeDecider$ TargetedOwner | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | StackDescription$ {c:TargetedOwner} puts {c:Targeted} on the top or bottom of their library. | SpellDescription$ Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library. +A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack+Red,Card.inZoneStack+Green,Permanent.Red,Permanent.Green | TgtZone$ Battlefield,Stack | TgtPrompt$ Select target spell or permanent that's red or green | AlternativeDecider$ TargetedOwner | Origin$ Battlefield,Stack | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | StackDescription$ {c:TargetedOwner} puts {c:Targeted} on the top or bottom of their library. | SpellDescription$ Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library. AI:RemoveDeck:Random Oracle:Choose target spell or permanent that's red or green. Its owner puts it on the top or bottom of their library. diff --git a/forge-gui/res/cardsfolder/a/ashioks_erasure.txt b/forge-gui/res/cardsfolder/a/ashioks_erasure.txt index 9c31f50503e..74580173e9f 100644 --- a/forge-gui/res/cardsfolder/a/ashioks_erasure.txt +++ b/forge-gui/res/cardsfolder/a/ashioks_erasure.txt @@ -5,7 +5,7 @@ K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target spell. S:Mode$ CantBeCast | ValidCard$ Card.nonLand+sharesNameWith Remembered.ExiledWithSource | Caster$ Opponent | Description$ Your opponents can't cast spells with the same name as the card exiled by CARDNAME. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigBounce | TriggerDescription$ When CARDNAME leaves the battlefield, return the exiled card to its owner's hand. -SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell | RememberChanged$ True +SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell | RememberChanged$ True SVar:TrigBounce:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ Remembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:Flash\nWhen Ashiok's Erasure enters, exile target spell.\nYour opponents can't cast spells with the same name as the exiled card.\nWhen Ashiok's Erasure leaves the battlefield, return the exiled card to its owner's hand. diff --git a/forge-gui/res/cardsfolder/a/aven_interrupter.txt b/forge-gui/res/cardsfolder/a/aven_interrupter.txt index 8b99ddab29d..a2bfa6417c0 100644 --- a/forge-gui/res/cardsfolder/a/aven_interrupter.txt +++ b/forge-gui/res/cardsfolder/a/aven_interrupter.txt @@ -5,7 +5,7 @@ PT:2/2 K:Flash K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target spell. It becomes plotted. (Its owner may cast it as a sorcery on a later turn without paying its mana cost.) -SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Mandatory$ True | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell | RememberChanged$ True | SubAbility$ DBPlot +SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell | RememberChanged$ True | SubAbility$ DBPlot SVar:DBPlot:DB$ AlterAttribute | Defined$ Remembered | Attributes$ Plotted | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True S:Mode$ RaiseCost | Activator$ Opponent | ValidCard$ Card.wasCastFromGraveyard,Card.wasCastFromExile | Type$ Spell | Amount$ 2 | Description$ Spells your opponents cast from graveyards or from exile cost {2} more to cast. diff --git a/forge-gui/res/cardsfolder/b/brutal_expulsion.txt b/forge-gui/res/cardsfolder/b/brutal_expulsion.txt index cf7514cab4d..05551873b60 100644 --- a/forge-gui/res/cardsfolder/b/brutal_expulsion.txt +++ b/forge-gui/res/cardsfolder/b/brutal_expulsion.txt @@ -3,6 +3,6 @@ ManaCost:2 U R Types:Instant K:Devoid A:SP$ Charm | MinCharmNum$ 1 | CharmNum$ 2 | Choices$ DBReturn,DBDmg -SVar:DBReturn:DB$ ChangeZone | ValidTgts$ Creature,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell or creature to its owner's hand. +SVar:DBReturn:DB$ ChangeZone | ValidTgts$ Creature,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SpellDescription$ Return target spell or creature to its owner's hand. SVar:DBDmg:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | NumDmg$ 2 | ReplaceDyingDefined$ Targeted | SpellDescription$ CARDNAME deals 2 damage to target creature or planeswalker. If that creature or planeswalker would die this turn, exile it instead. Oracle:Devoid (This card has no color.)\nChoose one or both —\n• Return target spell or creature to its owner's hand.\n• Brutal Expulsion deals 2 damage to target creature or planeswalker. If that creature or planeswalker would die this turn, exile it instead. diff --git a/forge-gui/res/cardsfolder/c/commit_memory.txt b/forge-gui/res/cardsfolder/c/commit_memory.txt index 4ce33113715..5cd6e55e4f0 100644 --- a/forge-gui/res/cardsfolder/c/commit_memory.txt +++ b/forge-gui/res/cardsfolder/c/commit_memory.txt @@ -1,7 +1,7 @@ Name:Commit ManaCost:3 U Types:Instant -A:SP$ ChangeZone | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Library | ValidTgts$ Permanent.nonLand,Card.inZoneStack | TgtPrompt$ Select target spell or nonland permanent | LibraryPosition$ 1 | Fizzle$ True | SpellDescription$ Put target spell or nonland permanent into its owner's library second from the top. +A:SP$ ChangeZone | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Library | ValidTgts$ Permanent.nonLand,Card.inZoneStack | TgtPrompt$ Select target spell or nonland permanent | LibraryPosition$ 1 | SpellDescription$ Put target spell or nonland permanent into its owner's library second from the top. # LibraryPosition is zero indexed. So 1 is second from the top AlternateMode:Split Oracle:Put target spell or nonland permanent into its owner's library second from the top. diff --git a/forge-gui/res/cardsfolder/d/divide_by_zero.txt b/forge-gui/res/cardsfolder/d/divide_by_zero.txt index 62eda1dfcfe..b9428d887d4 100644 --- a/forge-gui/res/cardsfolder/d/divide_by_zero.txt +++ b/forge-gui/res/cardsfolder/d/divide_by_zero.txt @@ -1,6 +1,6 @@ Name:Divide by Zero ManaCost:2 U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner's hand. SVar:DBLearn:DB$ Learn | SpellDescription$ Learn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.) Oracle:Return target spell or permanent with mana value 1 or greater to its owner's hand.\nLearn. (You may reveal a Lesson card you own from outside the game and put it into your hand, or discard a card to draw a card.) diff --git a/forge-gui/res/cardsfolder/e/endless_detour.txt b/forge-gui/res/cardsfolder/e/endless_detour.txt index 92c03103dac..2f00eeaa693 100644 --- a/forge-gui/res/cardsfolder/e/endless_detour.txt +++ b/forge-gui/res/cardsfolder/e/endless_detour.txt @@ -1,5 +1,5 @@ Name:Endless Detour ManaCost:G W U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack,Permanent.nonLand,Card.inZoneGraveyard | TgtZone$ Battlefield,Stack,Graveyard | TgtPrompt$ Select target spell, nonland permanent, or card in a graveyard | AlternativeDecider$ TargetedOwner | Origin$ Battlefield,Stack,Graveyard | Fizzle$ True | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | StackDescription$ {p:TargetedOwner} puts {c:Targeted} on the top or bottom of their library. | SpellDescription$ The owner of target spell, nonland permanent, or card in a graveyard puts it on the top or bottom of their library. +A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack,Permanent.nonLand,Card.inZoneGraveyard | TgtZone$ Battlefield,Stack,Graveyard | TgtPrompt$ Select target spell, nonland permanent, or card in a graveyard | AlternativeDecider$ TargetedOwner | Origin$ Battlefield,Stack,Graveyard | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 | StackDescription$ {p:TargetedOwner} puts {c:Targeted} on the top or bottom of their library. | SpellDescription$ The owner of target spell, nonland permanent, or card in a graveyard puts it on the top or bottom of their library. Oracle:The owner of target spell, nonland permanent, or card in a graveyard puts it on the top or bottom of their library. diff --git a/forge-gui/res/cardsfolder/e/erestor_of_the_council.txt b/forge-gui/res/cardsfolder/e/erestor_of_the_council.txt index a80956236e5..c085ec0d759 100644 --- a/forge-gui/res/cardsfolder/e/erestor_of_the_council.txt +++ b/forge-gui/res/cardsfolder/e/erestor_of_the_council.txt @@ -4,6 +4,7 @@ Types:Legendary Creature Elf Noble PT:2/4 T:Mode$ Vote | TriggerZones$ Battlefield | Execute$ TrigTreasure | List$ OppVotedSame,OppVotedDiff | TriggerDescription$ Whenever players finish voting, each opponent who voted for a choice you voted for creates a Treasure token. You scry X, where X is the number of opponents who voted for a choice you didn't vote for. Draw a card. SVar:TrigTreasure:DB$ Token | TokenScript$ c_a_treasure_sac | TokenOwner$ TriggeredOpponentVotedSame | SubAbility$ DBScry -SVar:DBScry:DB$ Scry | ScryNum$ X +SVar:DBScry:DB$ Scry | ScryNum$ X | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw SVar:X:TriggeredPlayersOpponentVotedDiff$Amount Oracle:Whenever players finish voting, each opponent who voted for a choice you voted for creates a Treasure token. You scry X, where X is the number of opponents who voted for a choice you didn't vote for. Draw a card. diff --git a/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt b/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt index 32c7794fef5..dee8a6baa2e 100644 --- a/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt +++ b/forge-gui/res/cardsfolder/e/eye_of_the_storm.txt @@ -2,7 +2,7 @@ Name:Eye of the Storm ManaCost:5 U U Types:Enchantment T:Mode$ SpellCast | ValidCard$ Instant.nonToken,Sorcery.nonToken | Execute$ TrigExileSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts an instant or sorcery card, exile it. Then that player copies each instant or sorcery card exiled with CARDNAME. For each copy, the player may cast the copy without paying its mana cost. -SVar:TrigExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | Fizzle$ True | RememberChanged$ True | SubAbility$ DBPlaySpell +SVar:TrigExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | RememberChanged$ True | SubAbility$ DBPlaySpell SVar:DBPlaySpell:DB$ RepeatEach | UseImprinted$ True | RepeatCards$ Card.IsRemembered | ChooseOrder$ True | Zone$ Exile | RepeatSubAbility$ DBPlay SVar:DBPlay:DB$ Play | Defined$ Imprinted | Controller$ TriggeredCardController | WithoutManaCost$ True | ValidSA$ Spell | CopyCard$ True | Optional$ True T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBForget diff --git a/forge-gui/res/cardsfolder/f/failure_comply.txt b/forge-gui/res/cardsfolder/f/failure_comply.txt index 32660980d7c..8e984acb985 100644 --- a/forge-gui/res/cardsfolder/f/failure_comply.txt +++ b/forge-gui/res/cardsfolder/f/failure_comply.txt @@ -1,7 +1,7 @@ Name:Failure ManaCost:1 U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | Origin$ Stack | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand. AlternateMode:Split Oracle:Return target spell to its owner's hand. diff --git a/forge-gui/res/cardsfolder/g/gales_redirection.txt b/forge-gui/res/cardsfolder/g/gales_redirection.txt index 3106743085c..6483d4b7566 100644 --- a/forge-gui/res/cardsfolder/g/gales_redirection.txt +++ b/forge-gui/res/cardsfolder/g/gales_redirection.txt @@ -1,7 +1,7 @@ Name:Gale's Redirection ManaCost:3 U U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Exile | AILogic$ ExileSpell.3 | TgtPrompt$ Choose target spell to exile | RememberChanged$ True | SubAbility$ DBRoll | SpellDescription$ Exile target spell. +A:SP$ ChangeZone | ValidTgts$ Card | TargetType$ Spell | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | AITgts$ Card.cmcGE3 | TgtPrompt$ Choose target spell to exile | RememberChanged$ True | SubAbility$ DBRoll | SpellDescription$ Exile target spell. SVar:DBRoll:DB$ RollDice | Sides$ 20 | Modifier$ Y | ResultSubAbilities$ 1-14:DBMayPlay,Else:DBMayPlayWithoutCost | StackDescription$ SpellDescription | SpellDescription$ Roll a d20 and add that spell's mana value. SVar:DBMayPlay:DB$ Effect | StaticAbilities$ STPlay | RememberObjects$ Remembered | Duration$ Permanent | ExileOnMoved$ Exile | SubAbility$ DBCleanup | SpellDescription$ 1—14 VERT You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast it. SVar:DBMayPlayWithoutCost:DB$ Effect | StaticAbilities$ STPlayWithoutCost | RememberObjects$ Remembered | Duration$ Permanent | ExileOnMoved$ Exile | SubAbility$ DBCleanup | SpellDescription$ 15+ VERT You may cast that card without paying its mana cost for as long as it remains exiled. diff --git a/forge-gui/res/cardsfolder/g/guile.txt b/forge-gui/res/cardsfolder/g/guile.txt index 5706f3ca5f7..a5a0bd0a6ef 100644 --- a/forge-gui/res/cardsfolder/g/guile.txt +++ b/forge-gui/res/cardsfolder/g/guile.txt @@ -4,7 +4,7 @@ Types:Creature Elemental Incarnation PT:6/6 S:Mode$ MinMaxBlocker | ValidCard$ Creature.Self | Min$ 3 | Description$ CARDNAME can't be blocked except by three or more creatures. R:Event$ Counter | ActiveZones$ Battlefield | ValidSA$ Spell | ValidCause$ SpellAbility.YouCtrl | ReplaceWith$ DBRemove | Description$ If a spell or ability you control would counter a spell, instead exile that spell and you may play that card without paying its mana cost. -SVar:DBRemove:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile | Fizzle$ True | RememberChanged$ True | SubAbility$ DBPlay +SVar:DBRemove:DB$ ChangeZone | Defined$ ReplacedCard | Origin$ Stack | Destination$ Exile | RememberChanged$ True | SubAbility$ DBPlay SVar:DBPlay:DB$ Play | Defined$ Remembered | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True T:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigShuffle | TriggerDescription$ When CARDNAME is put into a graveyard from anywhere, shuffle it into its owner's library. diff --git a/forge-gui/res/cardsfolder/h/hullbreaker_horror.txt b/forge-gui/res/cardsfolder/h/hullbreaker_horror.txt index 31778800b9d..5edff304e50 100644 --- a/forge-gui/res/cardsfolder/h/hullbreaker_horror.txt +++ b/forge-gui/res/cardsfolder/h/hullbreaker_horror.txt @@ -6,6 +6,6 @@ K:Flash R:Event$ Counter | ValidCard$ Card.Self | ValidSA$ Spell | Layer$ CantHappen | Description$ This spell can't be countered. T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, ABILITY SVar:TrigCharm:DB$ Charm | Choices$ ControlReturn,ControlBounce | MinCharmNum$ 0 | CharmNum$ 1 -SVar:ControlReturn:DB$ ChangeZone | ValidTgts$ Card.YouDontCtrl | TargetType$ Spell | TgtPrompt$ Select target spell you don't control | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell you don't control to its owner's hand. +SVar:ControlReturn:DB$ ChangeZone | ValidTgts$ Card.YouDontCtrl | TargetType$ Spell | TgtPrompt$ Select target spell you don't control | TgtZone$ Stack | Origin$ Stack | Destination$ Hand | SpellDescription$ Return target spell you don't control to its owner's hand. SVar:ControlBounce:DB$ ChangeZone | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | TgtZone$ Battlefield | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent to its owner's hand. Oracle:Flash\nThis spell can't be countered.\nWhenever you cast a spell, choose up to one —\n• Return target spell you don't control to its owner's hand.\n• Return target nonland permanent to its owner's hand. diff --git a/forge-gui/res/cardsfolder/k/knowledge_pool.txt b/forge-gui/res/cardsfolder/k/knowledge_pool.txt index 8dd6eba3d63..54ed33386fa 100644 --- a/forge-gui/res/cardsfolder/k/knowledge_pool.txt +++ b/forge-gui/res/cardsfolder/k/knowledge_pool.txt @@ -4,7 +4,7 @@ Types:Artifact T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigKnowledgeExile | TriggerDescription$ Imprint — When CARDNAME enters, each player exiles the top three cards of their library. SVar:TrigKnowledgeExile:DB$ Dig | DigNum$ 3 | ChangeNum$ All | Defined$ Player | DestinationZone$ Exile | Imprint$ True T:Mode$ SpellCast | ValidCard$ Card.wasCastFromTheirHand | Execute$ TrigKnowledgeExileSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell from their hand, that player exiles it. If the player does, they may cast a spell from among other cards exiled with CARDNAME without paying its mana cost. -SVar:TrigKnowledgeExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | Imprint$ True | Fizzle$ True | SubAbility$ DBKnowledgePlaySpell | RememberChanged$ True +SVar:TrigKnowledgeExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | Imprint$ True | SubAbility$ DBKnowledgePlaySpell | RememberChanged$ True SVar:DBKnowledgePlaySpell:DB$ Play | ValidZone$ Exile | Valid$ Card.IsImprinted+IsNotRemembered+nonLand | Controller$ TriggeredCardController | WithoutManaCost$ True | Optional$ True | ConditionDefined$ TriggeredCard | ConditionPresent$ Card.IsRemembered | ConditionCompare$ EQ1 | SubAbility$ DBKnowledgeCleanup SVar:DBKnowledgeCleanup:DB$ Cleanup | ClearRemembered$ True T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsImprinted | Execute$ DBForget diff --git a/forge-gui/res/cardsfolder/k/krark_the_thumbless.txt b/forge-gui/res/cardsfolder/k/krark_the_thumbless.txt index 30903deceed..1bd480e6672 100644 --- a/forge-gui/res/cardsfolder/k/krark_the_thumbless.txt +++ b/forge-gui/res/cardsfolder/k/krark_the_thumbless.txt @@ -5,7 +5,7 @@ PT:2/2 K:Partner T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigFlip | TriggerDescription$ Whenever you cast an instant or sorcery spell, flip a coin. If you lose the flip, return that spell to its owner's hand. If you win the flip, copy that spell, and you may choose new targets for the copy. SVar:TrigFlip:DB$ FlipACoin | WinSubAbility$ DBCopy | LoseSubAbility$ DBBounce -SVar:DBBounce:DB$ ChangeZone | Defined$ TriggeredSpellAbility | Origin$ Stack | Destination$ Hand | Fizzle$ True +SVar:DBBounce:DB$ ChangeZone | Defined$ TriggeredSpellAbility | Origin$ Stack | Destination$ Hand SVar:DBCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | AILogic$ Always | MayChooseTarget$ True DeckNeeds:Type$Instant|Sorcery Oracle:Whenever you cast an instant or sorcery spell, flip a coin. If you lose the flip, return that spell to its owner's hand. If you win the flip, copy that spell, and you may choose new targets for the copy.\nPartner (You can have two commanders if both have partner.) diff --git a/forge-gui/res/cardsfolder/m/mindbreak_trap.txt b/forge-gui/res/cardsfolder/m/mindbreak_trap.txt index 7b493c5f2ca..3436b0817a3 100644 --- a/forge-gui/res/cardsfolder/m/mindbreak_trap.txt +++ b/forge-gui/res/cardsfolder/m/mindbreak_trap.txt @@ -2,7 +2,7 @@ Name:Mindbreak Trap ManaCost:2 U U Types:Instant Trap S:Mode$ AlternativeCost | ValidSA$ Spell.Self | EffectZone$ All | Cost$ 0 | CheckSVar$ OppCastThisTurn | Description$ If an opponent cast three or more spells this turn, you may pay {0} rather than pay this spell's mana cost. -A:SP$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | TargetMin$ 0 | TargetMax$ MaxTgts | Fizzle$ True | StackDescription$ SpellDescription | SpellDescription$ Exile any number of target spells. +A:SP$ ChangeZone | TargetType$ Spell | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | TargetMin$ 0 | TargetMax$ MaxTgts | StackDescription$ SpellDescription | SpellDescription$ Exile any number of target spells. SVar:OppCastThisTurn:PlayerCountOpponents$ConditionGE3 SpellsCastThisTurn SVar:MaxTgts:Count$SpellsOnStack AI:RemoveDeck:All diff --git a/forge-gui/res/cardsfolder/n/neera_wild_mage.txt b/forge-gui/res/cardsfolder/n/neera_wild_mage.txt index d0a82668a0f..f2656895c4e 100644 --- a/forge-gui/res/cardsfolder/n/neera_wild_mage.txt +++ b/forge-gui/res/cardsfolder/n/neera_wild_mage.txt @@ -3,7 +3,7 @@ ManaCost:4 U R Types:Legendary Creature Human Elf Shaman PT:2/7 T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigPutBottom | TriggerZones$ Battlefield | ActivationLimit$ 1 | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, you may put it on the bottom of its owner's library. If you do, reveal cards from the top of your library until you reveal a nonland card. You may cast that card without paying its mana cost. Then put all revealed cards not cast this way on the bottom of your library in a random order. This ability triggers only once each turn. -SVar:TrigPutBottom:DB$ ChangeZone | Origin$ Stack | Destination$ Library | LibraryPosition$ -1 | Defined$ TriggeredSpellAbility | Fizzle$ True | RememberChanged$ True | SubAbility$ DBDig +SVar:TrigPutBottom:DB$ ChangeZone | Origin$ Stack | Destination$ Library | LibraryPosition$ -1 | Defined$ TriggeredSpellAbility | RememberChanged$ True | SubAbility$ DBDig SVar:DBDig:DB$ DigUntil | Valid$ Card.nonLand | ForgetOtherRemembered$ True | ImprintFound$ True | RememberFound$ True | RememberRevealed$ True | NoMoveRevealed$ True | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBPlay SVar:DBPlay:DB$ Play | Defined$ Imprinted | ValidZone$ Library | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | ForgetPlayed$ True | SubAbility$ DBBottom SVar:DBBottom:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Library | LibraryPosition$ -1 | RandomOrder$ True | SubAbility$ DBCleanup diff --git a/forge-gui/res/cardsfolder/o/obscura_interceptor.txt b/forge-gui/res/cardsfolder/o/obscura_interceptor.txt index 3be7ac7002b..4abdbeec053 100644 --- a/forge-gui/res/cardsfolder/o/obscura_interceptor.txt +++ b/forge-gui/res/cardsfolder/o/obscura_interceptor.txt @@ -7,6 +7,6 @@ K:Lifelink T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConnive | TriggerDescription$ When CARDNAME enters, it connives. When it connives this way, return up to one target spell to its owner's hand. (To have a creature connive, draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on that creature.) SVar:TrigConnive:DB$ Connive | SubAbility$ DBImmediateTrigger SVar:DBImmediateTrigger:DB$ ImmediateTrigger | Execute$ TrigReturn | TriggerDescription$ When it connives this way, return up to one target spell to its owner's hand. -SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Card | TgtPrompt$ Select target spell | TargetMax$ 1 | TargetMin$ 0 | TgtZone$ Stack | TargetType$ Spell | Origin$ Stack | Fizzle$ True | Destination$ Hand +SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Card | TgtPrompt$ Select target spell | TargetMax$ 1 | TargetMin$ 0 | TgtZone$ Stack | TargetType$ Spell | Origin$ Stack | Destination$ Hand DeckHas:Ability$LifeGain|Discard|Counters Oracle:Flash\nLifelink\nWhen Obscura Interceptor enters, it connives. When it connives this way, return up to one target spell to its owner's hand. (To have a creature connive, draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on that creature.) diff --git a/forge-gui/res/cardsfolder/p/possibility_storm.txt b/forge-gui/res/cardsfolder/p/possibility_storm.txt index 9861651ebaf..3ef991b8740 100644 --- a/forge-gui/res/cardsfolder/p/possibility_storm.txt +++ b/forge-gui/res/cardsfolder/p/possibility_storm.txt @@ -2,7 +2,7 @@ Name:Possibility Storm ManaCost:3 R R Types:Enchantment T:Mode$ SpellCast | ValidCard$ Card.wasCastFromTheirHand | Execute$ TrigExileSpell | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell from their hand, that player exiles it, then exiles cards from the top of their library until they exile a card that shares a card type with it. That player may cast that card without paying its mana cost. Then they put all cards exiled with CARDNAME on the bottom of their library in a random order. -SVar:TrigExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | Fizzle$ True | SubAbility$ DBDig | Imprint$ True +SVar:TrigExileSpell:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | SubAbility$ DBDig | Imprint$ True SVar:DBDig:DB$ DigUntil | Defined$ TriggeredCardController | Valid$ Card.sharesCardTypeWith TriggeredCardLKICopy | ValidDescription$ shares a card type with exiled card | FoundDestination$ Exile | RevealedDestination$ Exile | RememberFound$ True | ImprintRevealed$ True | SubAbility$ DBPlay SVar:DBPlay:DB$ Play | Defined$ Remembered | Controller$ TriggeredCardController | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | SubAbility$ DBChangeZone SVar:DBChangeZone:DB$ ChangeZoneAll | Origin$ Exile | ChangeType$ Card.IsRemembered,Card.IsImprinted | Destination$ Library | LibraryPosition$ -1 | RandomOrder$ True | SubAbility$ DBPossibilityCleanup diff --git a/forge-gui/res/cardsfolder/p/press_the_enemy.txt b/forge-gui/res/cardsfolder/p/press_the_enemy.txt index 3fa99df6468..440dad22071 100644 --- a/forge-gui/res/cardsfolder/p/press_the_enemy.txt +++ b/forge-gui/res/cardsfolder/p/press_the_enemy.txt @@ -1,7 +1,7 @@ Name:Press the Enemy ManaCost:2 U U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Permanent.nonLand+OppCtrl,Card.inZoneStack+OppCtrl | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBMayPlay | SpellDescription$ Return target spell or nonland permanent an opponent controls to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Permanent.nonLand+OppCtrl,Card.inZoneStack+OppCtrl | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SubAbility$ DBMayPlay | SpellDescription$ Return target spell or nonland permanent an opponent controls to its owner's hand. SVar:DBMayPlay:DB$ Play | Valid$ Card.YouOwn | ValidZone$ Hand | ValidSA$ Instant.cmcLEZ,Sorcery.cmcLEZ | WithoutManaCost$ True | Optional$ True | SubAbility$ DBCleanup | SpellDescription$ You may cast an instant or sorcery spell with equal or lesser mana value from your hand without paying its mana cost. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:SpellTargeted$CardManaCostLKI diff --git a/forge-gui/res/cardsfolder/r/radiant_lotus.txt b/forge-gui/res/cardsfolder/r/radiant_lotus.txt index 3f9d9514bcc..74aa4797ea9 100644 --- a/forge-gui/res/cardsfolder/r/radiant_lotus.txt +++ b/forge-gui/res/cardsfolder/r/radiant_lotus.txt @@ -1,7 +1,8 @@ Name:Radiant Lotus ManaCost:6 Types:Artifact -A:AB$ Mana | Cost$ T XMin1 Sac | ValidTgts$ Player | Produced$ Any | Amount$ Y | SpellDescription$ Choose a color. Target player adds three mana of the chosen color for each artifact sacrificed this way. | StackDescription$ SpellDescription +A:AB$ ChooseColor | Cost$ T Sac | XMin$ 1 | Defined$ You | SubAbility$ DBMana | SpellDescription$ Choose a color. Target player adds three mana of the chosen color for each artifact sacrificed this way. +SVar:DBMana:DB$ Mana | ValidTgts$ Player | Produced$ Chosen | Amount$ X SVar:X:Count$xPaid SVar:Y:SVar$X/Times.3 SVar:BuffedBy:Artifact diff --git a/forge-gui/res/cardsfolder/r/reprieve.txt b/forge-gui/res/cardsfolder/r/reprieve.txt index 0589dd77e1b..ffc25d20292 100644 --- a/forge-gui/res/cardsfolder/r/reprieve.txt +++ b/forge-gui/res/cardsfolder/r/reprieve.txt @@ -1,6 +1,6 @@ Name:Reprieve ManaCost:1 W Types:Instant -A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBDraw | SpellDescription$ Return target spell to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack | TgtZone$ Stack | Origin$ Stack | Destination$ Hand | SubAbility$ DBDraw | SpellDescription$ Return target spell to its owner's hand. SVar:DBDraw:DB$ Draw | NumCards$ 1 Oracle:Return target spell to its owner's hand.\nDraw a card. diff --git a/forge-gui/res/cardsfolder/r/rory_williams.txt b/forge-gui/res/cardsfolder/r/rory_williams.txt index 5fb33d9716d..7560a4a7e20 100644 --- a/forge-gui/res/cardsfolder/r/rory_williams.txt +++ b/forge-gui/res/cardsfolder/r/rory_williams.txt @@ -6,7 +6,7 @@ K:Partner:Amy Pond K:First Strike K:Lifelink T:Mode$ SpellCast | ValidCard$ Card.Self+!wasCastFromExile | Execute$ TrigExile | TriggerDescription$ The Last Centurion — When you cast this spell from anywhere other than exile, exile it with three time counters on it. It gains suspend. Then investigate. (Create a Clue token. It's an artifact with "{2}, Sacrifice this artifact: Draw a card.") -SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredSpellAbility | Origin$ Stack | Destination$ Exile | Fizzle$ True | WithCountersType$ TIME | WithCountersAmount$ 3 | RememberChanged$ True | SubAbility$ GiveSuspend +SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredSpellAbility | Origin$ Stack | Destination$ Exile | WithCountersType$ TIME | WithCountersAmount$ 3 | RememberChanged$ True | SubAbility$ GiveSuspend SVar:GiveSuspend:DB$ Pump | Defined$ Remembered | KW$ Suspend | PumpZone$ Exile | Duration$ Permanent | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBInvestigate SVar:DBInvestigate:DB$ Investigate diff --git a/forge-gui/res/cardsfolder/rebalanced/a-divide_by_zero.txt b/forge-gui/res/cardsfolder/rebalanced/a-divide_by_zero.txt index a827ebcb590..2392f6c1d0f 100644 --- a/forge-gui/res/cardsfolder/rebalanced/a-divide_by_zero.txt +++ b/forge-gui/res/cardsfolder/rebalanced/a-divide_by_zero.txt @@ -1,6 +1,6 @@ Name:A-Divide by Zero ManaCost:2 U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner's hand. If its mana value was 4 or less, learn. +A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner's hand. If its mana value was 4 or less, learn. SVar:DBLearn:DB$ Learn | ConditionDefined$ Targeted | ConditionPresent$ Card.cmcLE4 | ConditionCompare$ EQ1 Oracle:Return target spell or permanent with mana value 1 or greater to its owner's hand. If its mana value was 4 or less, learn. diff --git a/forge-gui/res/cardsfolder/rebalanced/a-hullbreaker_horror.txt b/forge-gui/res/cardsfolder/rebalanced/a-hullbreaker_horror.txt index 422b5ce2184..0bd83d57e56 100644 --- a/forge-gui/res/cardsfolder/rebalanced/a-hullbreaker_horror.txt +++ b/forge-gui/res/cardsfolder/rebalanced/a-hullbreaker_horror.txt @@ -5,6 +5,6 @@ PT:7/8 K:Flash T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, ABILITY SVar:TrigCharm:DB$ Charm | Choices$ ControlReturn,ControlBounce | MinCharmNum$ 0 | CharmNum$ 1 -SVar:ControlReturn:DB$ ChangeZone | ValidTgts$ Card.YouDontCtrl | TgtPrompt$ Select target spell you don't control | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell you don't control to its owner's hand. +SVar:ControlReturn:DB$ ChangeZone | ValidTgts$ Card.YouDontCtrl | TgtPrompt$ Select target spell you don't control | TgtZone$ Stack | Origin$ Stack | Destination$ Hand | SpellDescription$ Return target spell you don't control to its owner's hand. SVar:ControlBounce:DB$ ChangeZone | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | TgtZone$ Battlefield | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent to its owner's hand. Oracle:Flash\nWhenever you cast a spell, choose up to one —\n• Return target spell you don't control to its owner's hand.\n• Return target nonland permanent to its owner's hand. diff --git a/forge-gui/res/cardsfolder/s/sink_into_stupor_soporific_springs.txt b/forge-gui/res/cardsfolder/s/sink_into_stupor_soporific_springs.txt index 8fc4007c53c..68305089da7 100644 --- a/forge-gui/res/cardsfolder/s/sink_into_stupor_soporific_springs.txt +++ b/forge-gui/res/cardsfolder/s/sink_into_stupor_soporific_springs.txt @@ -1,7 +1,7 @@ Name:Sink into Stupor ManaCost:1 U U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Permanent.nonLand+OppCtrl,Card.inZoneStack+OppCtrl | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell or nonland permanent an opponent controls to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Permanent.nonLand+OppCtrl,Card.inZoneStack+OppCtrl | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SpellDescription$ Return target spell or nonland permanent an opponent controls to its owner's hand. AlternateMode:Modal Oracle:Return target spell or nonland permanent an opponent controls to its owner's hand. diff --git a/forge-gui/res/cardsfolder/s/sliver_queen_avatar.txt b/forge-gui/res/cardsfolder/s/sliver_queen_avatar.txt index b3581edb2eb..0ab264f3247 100644 --- a/forge-gui/res/cardsfolder/s/sliver_queen_avatar.txt +++ b/forge-gui/res/cardsfolder/s/sliver_queen_avatar.txt @@ -3,7 +3,7 @@ ManaCost:no cost Types:Vanguard HandLifeModifier:+0/+7 T:Mode$ SpellCast | ValidCard$ Creature.nonSliver | ValidActivatingPlayer$ You | TriggerZones$ Command | Execute$ TrigCopy | TriggerDescription$ Whenever you cast a non-Sliver creature spell, exile that spell. If you do, create a token that's a copy of a random non-Shapeshifter Sliver creature card with the same mana value as that spell. -SVar:TrigCopy:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | Fizzle$ True | RememberChanged$ True | SubAbility$ DBCopy +SVar:TrigCopy:DB$ ChangeZone | Defined$ TriggeredCardLKICopy | Origin$ Stack | Destination$ Exile | RememberChanged$ True | SubAbility$ DBCopy SVar:DBCopy:DB$ CopyPermanent | NumCopies$ 1 | ValidSupportedCopy$ Creature.Sliver+nonShapeshifter+cmcEQX | RandomCopied$ True | RandomNum$ 1 | ConditionCheckSVar$ RememberedSize | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:TriggeredCard$CardManaCost diff --git a/forge-gui/res/cardsfolder/s/smirking_spelljacker.txt b/forge-gui/res/cardsfolder/s/smirking_spelljacker.txt index b5edd37c856..4190afa0da3 100644 --- a/forge-gui/res/cardsfolder/s/smirking_spelljacker.txt +++ b/forge-gui/res/cardsfolder/s/smirking_spelljacker.txt @@ -5,7 +5,7 @@ PT:3/3 K:Flash K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target spell an opponent controls. -SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell.OppCtrl | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Mandatory$ True | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell an opponent controls +SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell.OppCtrl | ValidTgts$ Card | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell an opponent controls T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPlay | IsPresent$ Card.ExiledWithSource | PresentZone$ Exile | TriggerDescription$ Whenever CARDNAME attacks, if a card is exiled with it, you may cast the exiled card without paying its mana cost. SVar:TrigPlay:DB$ Play | Defined$ ExiledWithSource | Amount$ All | Controller$ You | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True SVar:HasAttackEffect:TRUE diff --git a/forge-gui/res/cardsfolder/s/spell_queller.txt b/forge-gui/res/cardsfolder/s/spell_queller.txt index 313849553e9..7592e38c045 100644 --- a/forge-gui/res/cardsfolder/s/spell_queller.txt +++ b/forge-gui/res/cardsfolder/s/spell_queller.txt @@ -6,7 +6,7 @@ K:Flash K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters, exile target spell with mana value 4 or less. T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigPlay | TriggerDescription$ When CARDNAME leaves the battlefield, the exiled card's owner may cast that card without paying its mana cost. -SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card.cmcLE4 | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Mandatory$ True | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell with mana value 4 or less | RememberChanged$ True +SVar:TrigExile:DB$ ChangeZone | TargetType$ Spell | ValidTgts$ Card.cmcLE4 | TgtZone$ Stack | Origin$ Stack | Destination$ Exile | IsCurse$ True | TgtPrompt$ Choose target spell with mana value 4 or less | RememberChanged$ True SVar:TrigPlay:DB$ Play | Defined$ Remembered.ExiledWithSource | Controller$ RememberedOwner | ValidSA$ Spell | WithoutManaCost$ True | Optional$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBCleanup T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard diff --git a/forge-gui/res/cardsfolder/s/spellscorn_coven_take_it_back.txt b/forge-gui/res/cardsfolder/s/spellscorn_coven_take_it_back.txt index 5287ee3e82b..c18d95d783f 100644 --- a/forge-gui/res/cardsfolder/s/spellscorn_coven_take_it_back.txt +++ b/forge-gui/res/cardsfolder/s/spellscorn_coven_take_it_back.txt @@ -14,5 +14,5 @@ ALTERNATE Name:Take It Back ManaCost:2 U Types:Instant Adventure -A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand. (Then exile this card. You may cast the creature later from exile.) +A:SP$ ChangeZone | ValidTgts$ Card.inZoneStack | TgtZone$ Stack | Origin$ Stack | Destination$ Hand | SpellDescription$ Return target spell to its owner's hand. (Then exile this card. You may cast the creature later from exile.) Oracle:Return target spell to its owner's hand. (Then exile this card. You may cast the creature later from exile.) diff --git a/forge-gui/res/cardsfolder/s/subtlety.txt b/forge-gui/res/cardsfolder/s/subtlety.txt index 90e721b7fd5..ce53b95b1e9 100644 --- a/forge-gui/res/cardsfolder/s/subtlety.txt +++ b/forge-gui/res/cardsfolder/s/subtlety.txt @@ -5,6 +5,6 @@ PT:3/3 K:Flash K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigTuck | TriggerDescription$ When CARDNAME enters, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library. -SVar:TrigTuck:DB$ ChangeZone | ValidTgts$ Card.inZoneStack+Creature,Card.inZoneStack+Planeswalker | TgtZone$ Stack | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target creature spell or planeswalker spell | AlternativeDecider$ TargetedOwner | Origin$ Stack | Fizzle$ True | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 +SVar:TrigTuck:DB$ ChangeZone | ValidTgts$ Card.inZoneStack+Creature,Card.inZoneStack+Planeswalker | TgtZone$ Stack | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select up to one target creature spell or planeswalker spell | AlternativeDecider$ TargetedOwner | Origin$ Stack | Destination$ Library | DestinationAlternative$ Library | LibraryPositionAlternative$ -1 K:Evoke:ExileFromHand<1/Card.Blue+Other/blue card> Oracle:Flash\nFlying\nWhen Subtlety enters, choose up to one target creature spell or planeswalker spell. Its owner puts it on the top or bottom of their library.\nEvoke—Exile a blue card from your hand. diff --git a/forge-gui/res/cardsfolder/s/summary_dismissal.txt b/forge-gui/res/cardsfolder/s/summary_dismissal.txt index efa579fec52..5fda71f322c 100644 --- a/forge-gui/res/cardsfolder/s/summary_dismissal.txt +++ b/forge-gui/res/cardsfolder/s/summary_dismissal.txt @@ -1,7 +1,7 @@ Name:Summary Dismissal ManaCost:2 U U Types:Instant -A:SP$ ChangeZoneAll | ChangeType$ Card.Other | Origin$ Stack | Destination$ Exile | Fizzle$ True | SubAbility$ DBCounter | SpellDescription$ Exile all other spells and counter all abilities. +A:SP$ ChangeZoneAll | ChangeType$ Card.Other | Origin$ Stack | Destination$ Exile | SubAbility$ DBCounter | SpellDescription$ Exile all other spells and counter all abilities. SVar:DBCounter:DB$ Counter | Defined$ ValidStack Activated,Triggered AI:RemoveDeck:All Oracle:Exile all other spells and counter all abilities. diff --git a/forge-gui/res/cardsfolder/t/talions_throneguard.txt b/forge-gui/res/cardsfolder/t/talions_throneguard.txt index f48a64e133a..4e0a52a0f6c 100644 --- a/forge-gui/res/cardsfolder/t/talions_throneguard.txt +++ b/forge-gui/res/cardsfolder/t/talions_throneguard.txt @@ -6,7 +6,7 @@ K:Flash K:Bargain K:Flying T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When CARDNAME enters, return up to one target spell or nonland permanent to its owner's hand. If CARDNAME was bargained, that card perpetually gains "This spell costs {2} more to cast." -SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Permanent.nonLand,Card.inZoneStack | TgtZone$ Stack,Battlefield | TargetMin$ 0 | TargetMax$ 1 | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | RememberChanged$ True | TgtPrompt$ Select up to one target spell or nonland permanent | SubAbility$ DBAnimate +SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Permanent.nonLand,Card.inZoneStack | TgtZone$ Stack,Battlefield | TargetMin$ 0 | TargetMax$ 1 | Origin$ Battlefield,Stack | Destination$ Hand | RememberChanged$ True | TgtPrompt$ Select up to one target spell or nonland permanent | SubAbility$ DBAnimate SVar:DBAnimate:DB$ Animate | Defined$ Remembered | ConditionDefined$ Self | ConditionPresent$ Card.bargained | staticAbilities$ RaiseCost | Duration$ Perpetual | SubAbility$ DBCleanup SVar:RaiseCost:Mode$ RaiseCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 2 | EffectZone$ All | Description$ This spell costs {2} more to cast. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/forge-gui/res/cardsfolder/u/unsubstantiate.txt b/forge-gui/res/cardsfolder/u/unsubstantiate.txt index c22fa4a2d66..8fad26fdf2c 100644 --- a/forge-gui/res/cardsfolder/u/unsubstantiate.txt +++ b/forge-gui/res/cardsfolder/u/unsubstantiate.txt @@ -1,5 +1,5 @@ Name:Unsubstantiate ManaCost:1 U Types:Instant -A:SP$ ChangeZone | ValidTgts$ Creature,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell or creature to its owner's hand. +A:SP$ ChangeZone | ValidTgts$ Creature,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand | SpellDescription$ Return target spell or creature to its owner's hand. Oracle:Return target spell or creature to its owner's hand. diff --git a/forge-gui/res/cardsfolder/v/venser_shaper_savant.txt b/forge-gui/res/cardsfolder/v/venser_shaper_savant.txt index 883d2f4f5d7..b3013d56489 100644 --- a/forge-gui/res/cardsfolder/v/venser_shaper_savant.txt +++ b/forge-gui/res/cardsfolder/v/venser_shaper_savant.txt @@ -4,5 +4,5 @@ Types:Legendary Creature Human Wizard PT:2/2 K:Flash T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ VensersBounce | TriggerDescription$ When CARDNAME enters, return target spell or permanent to its owner's hand. -SVar:VensersBounce:DB$ ChangeZone | ValidTgts$ Permanent,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand +SVar:VensersBounce:DB$ ChangeZone | ValidTgts$ Permanent,Card.inZoneStack | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Destination$ Hand Oracle:Flash\nWhen Venser, Shaper Savant enters, return target spell or permanent to its owner's hand. diff --git a/forge-gui/src/main/java/forge/gui/control/FControlGameEventHandler.java b/forge-gui/src/main/java/forge/gui/control/FControlGameEventHandler.java index a17250b56d3..82ada7213b5 100644 --- a/forge-gui/src/main/java/forge/gui/control/FControlGameEventHandler.java +++ b/forge-gui/src/main/java/forge/gui/control/FControlGameEventHandler.java @@ -451,12 +451,6 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { return processCards(cards, cardsRefreshDetails); } - public Void visit(final GameEventSpeedChanged event) { - Player p = event.player; - processPlayer(p, livesUpdate); - return processEvent(); - } - public Void visit(final GameEventLandPlayed event) { processPlayer(event.player, livesUpdate); matchController.handleLandPlayed(event.land);