From 21f92239818e7238547111bca1e990e0c628fe7c Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Thu, 29 Dec 2022 09:34:05 +0800 Subject: [PATCH] fix Adventure cards in exile lose "may be cast" when rewinding casting - closes #2176 --- .../java/forge/game/ability/SpellAbilityEffect.java | 9 +++++++++ .../forge/game/ability/effects/EffectEffect.java | 2 ++ .../main/java/forge/game/card/CardFactoryUtil.java | 2 +- .../src/main/java/forge/game/zone/PlayerZone.java | 12 +++++++++++- 4 files changed, 23 insertions(+), 2 deletions(-) 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 6ec34b5119b..e978eef4454 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -400,6 +400,15 @@ public abstract class SpellAbilityEffect { addedTrigger.setIntrinsic(true); } + protected static void addExileOnCastTrigger(final Card card) { + String trig = "Mode$ SpellCast | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True"; + String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; + final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); + parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card)); + final Trigger addedTrigger = card.addTrigger(parsedTrigger); + addedTrigger.setIntrinsic(true); + } + protected static void addExileOnCounteredTrigger(final Card card) { String trig = "Mode$ Countered | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True"; String effect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"; diff --git a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java index 51da7b83dc2..444b16d26b9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/EffectEffect.java @@ -227,6 +227,8 @@ public class EffectEffect extends SpellAbilityEffect { addForgetOnCastTrigger(eff); } else if (sa.hasParam("ExileOnMoved")) { addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved")); + } else if (sa.hasParam("ExileOnCast")) { + addExileOnCastTrigger(eff); } if (sa.hasParam("ForgetOnPhasedIn")) { addForgetOnPhasedInTrigger(eff); diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 51917427525..8abadb26bfd 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3855,7 +3855,7 @@ public class CardFactoryUtil { SpellAbility saExile = AbilityFactory.getAbility(abExile, card); - String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnMoved$ Exile | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell"; + String abEffect = "DB$ Effect | RememberObjects$ Self | StaticAbilities$ Play | ExileOnCast$ True | Duration$ Permanent | ConditionDefined$ Self | ConditionPresent$ Card.nonCopiedSpell"; AbilitySub saEffect = (AbilitySub)AbilityFactory.getAbility(abEffect, card); StringBuilder sbPlay = new StringBuilder(); diff --git a/forge-game/src/main/java/forge/game/zone/PlayerZone.java b/forge-game/src/main/java/forge/game/zone/PlayerZone.java index ab52d23fee0..53770ab025d 100644 --- a/forge-game/src/main/java/forge/game/zone/PlayerZone.java +++ b/forge-game/src/main/java/forge/game/zone/PlayerZone.java @@ -20,6 +20,7 @@ package forge.game.zone; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; +import forge.card.CardStateName; import forge.game.card.Card; import forge.game.card.CardCollectionView; import forge.game.card.CardLists; @@ -63,7 +64,7 @@ public class PlayerZone extends Zone { boolean graveyardCastable = c.hasKeyword(Keyword.FLASHBACK) || c.hasKeyword(Keyword.RETRACE) || c.hasKeyword(Keyword.JUMP_START) || c.hasKeyword(Keyword.ESCAPE) || c.hasKeyword(Keyword.DISTURB); - boolean exileCastable = (c.isAdventureCard() || c.isForetold()) && c.isInZone(ZoneType.Exile); + boolean exileCastable = c.isForetold() || isOnAdventure(c); for (final SpellAbility sa : c.getSpellAbilities()) { final ZoneType restrictZone = sa.getRestrictions().getZone(); @@ -92,6 +93,15 @@ public class PlayerZone extends Zone { return false; } } + private boolean isOnAdventure(Card c) { + if (!c.isAdventureCard()) + return false; + if (c.getExiledWith() == null) + return false; + if (!CardStateName.Adventure.equals(c.getExiledWith().getCurrentStateName())) + return false; + return true; + } private final Player player;