From aa66eee6de69d942b47e8a53123c048f8d0581cc Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Mon, 3 Jan 2022 15:02:11 +0100 Subject: [PATCH] Haunt fixes --- .../forge/ai/ability/CopyPermanentAi.java | 2 +- .../game/ability/effects/CounterEffect.java | 26 +++++++++---------- .../game/ability/effects/HauntEffect.java | 10 +++---- .../java/forge/game/card/CardFactoryUtil.java | 7 +++-- .../game/trigger/TriggerChangesZone.java | 6 +++++ .../main/java/forge/game/zone/MagicStack.java | 6 ++--- 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java index c18d777bc9a..f74fa8115ed 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -187,7 +187,7 @@ public class CopyPermanentAi extends SpellAbilityAi { } if (choice == null) { // can't find anything left - if (!sa.isTargetNumberValid() || (sa.getTargets().size() == 0)) { + if (!sa.isTargetNumberValid() || sa.getTargets().size() == 0) { sa.resetTargets(); return false; } else { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java index cd7993acd90..4efbf6744cd 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CounterEffect.java @@ -298,7 +298,8 @@ public class CounterEffect extends SpellAbilityEffect { private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, CardZoneTable triggerList) { final Game game = tgtSA.getActivatingPlayer().getGame(); Card movedCard = null; - final Zone originZone = tgtSA.getHostCard().getZone(); + final Card c = tgtSA.getHostCard(); + final Zone originZone = c.getZone(); // Run any applicable replacement effects. final Map repParams = AbilityKey.mapFromAffected(tgtSA.getHostCard()); @@ -310,8 +311,8 @@ public class CounterEffect extends SpellAbilityEffect { game.getStack().remove(si); // if the target card on stack was a spell with Bestow, then unbestow it - if (tgtSA.getHostCard() != null && tgtSA.getHostCard().isBestowed()) { - tgtSA.getHostCard().unanimateBestow(true); + if (c.isBestowed()) { + c.unanimateBestow(true); } Map params = AbilityKey.newMap(); @@ -327,33 +328,32 @@ public class CounterEffect extends SpellAbilityEffect { // For Ability-targeted counterspells - do not move it anywhere, // even if Destination$ is specified. } else if (destination.equals("Graveyard")) { - movedCard = game.getAction().moveToGraveyard(tgtSA.getHostCard(), srcSA, params); + movedCard = game.getAction().moveToGraveyard(c, srcSA, params); } else if (destination.equals("Exile")) { - movedCard = game.getAction().exile(tgtSA.getHostCard(), srcSA, params); + movedCard = game.getAction().exile(c, srcSA, params); } else if (destination.equals("TopOfLibrary")) { - movedCard = game.getAction().moveToLibrary(tgtSA.getHostCard(), srcSA, params); + movedCard = game.getAction().moveToLibrary(c, srcSA, params); } else if (destination.equals("Hand")) { - movedCard = game.getAction().moveToHand(tgtSA.getHostCard(), srcSA, params); + movedCard = game.getAction().moveToHand(c, srcSA, params); } else if (destination.equals("Battlefield")) { if (tgtSA instanceof SpellPermanent) { - Card c = tgtSA.getHostCard(); c.setController(srcSA.getActivatingPlayer(), 0); movedCard = game.getAction().moveToPlay(c, srcSA.getActivatingPlayer(), srcSA, params); } else { - movedCard = game.getAction().moveToPlay(tgtSA.getHostCard(), srcSA.getActivatingPlayer(), srcSA, params); + movedCard = game.getAction().moveToPlay(c, srcSA.getActivatingPlayer(), srcSA, params); movedCard.setController(srcSA.getActivatingPlayer(), 0); } } else if (destination.equals("BottomOfLibrary")) { - movedCard = game.getAction().moveToBottomOfLibrary(tgtSA.getHostCard(), srcSA, params); + movedCard = game.getAction().moveToBottomOfLibrary(c, srcSA, params); } else if (destination.equals("ShuffleIntoLibrary")) { - movedCard = game.getAction().moveToBottomOfLibrary(tgtSA.getHostCard(), srcSA, params); - tgtSA.getHostCard().getController().shuffle(srcSA); + movedCard = game.getAction().moveToBottomOfLibrary(c, srcSA, params); + c.getController().shuffle(srcSA); } else { throw new IllegalArgumentException("AbilityFactory_CounterMagic: Invalid Destination argument for card " + srcSA.getHostCard().getName()); } // Run triggers - final Map runParams = AbilityKey.mapFromCard(tgtSA.getHostCard()); + final Map runParams = AbilityKey.mapFromCard(c); runParams.put(AbilityKey.Player, tgtSA.getActivatingPlayer()); runParams.put(AbilityKey.Cause, srcSA.getHostCard()); runParams.put(AbilityKey.CounteredSA, tgtSA); diff --git a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java index 230d1d12f48..c912877686c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/HauntEffect.java @@ -9,13 +9,13 @@ public class HauntEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { - Card card = sa.getHostCard(); - final Game game = card.getGame(); - card = game.getCardState(card, null); + Card host = sa.getHostCard(); + final Game game = host.getGame(); + Card card = game.getCardState(host, null); if (card == null) { return; - } else if (sa.usesTargeting() && !card.isToken()) { - // haunt target but only if card is no token + } else if (sa.usesTargeting() && !card.isToken() && host.equalsWithTimestamp(card)) { + // haunt target but only if card is no token and still in grave final Card copy = game.getAction().exile(card, sa); sa.getTargets().getFirstTargetedCard().addHauntedBy(copy); } else if (!sa.usesTargeting() && card.getHaunting() != null) { 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 9bee4a88830..dc8a17e7239 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -1293,13 +1293,12 @@ public class CardFactoryUtil { triggers.add(haunterETB); } - // First, create trigger that runs when the haunter goes to the - // graveyard + // First, create trigger that runs when the haunter goes to the graveyard final StringBuilder sbHaunter = new StringBuilder(); sbHaunter.append("Mode$ ChangesZone | Origin$ "); - sbHaunter.append(card.isCreature() ? "Battlefield" : "Stack"); + sbHaunter.append(card.isCreature() ? "Battlefield" : "Stack | ResolvedCard$ True"); sbHaunter.append(" | Destination$ Graveyard | ValidCard$ Card.Self"); - sbHaunter.append(" | Static$ True | Secondary$ True | TriggerDescription$ Blank"); + sbHaunter.append(" | Secondary$ True | TriggerDescription$ " + inst.getReminderText()); final Trigger haunterDies = TriggerHandler.parseTrigger(sbHaunter.toString(), card, intrinsic); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java index c599bf2d919..d830ec9033c 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerChangesZone.java @@ -130,6 +130,12 @@ public class TriggerChangesZone extends Trigger { } } + if (hasParam("ResolvedCard")) { + if (!runParams.containsKey(AbilityKey.Fizzle)) { + return false; + } + } + // Check number of lands ETB this turn on triggered card's controller if (hasParam("CheckOnTriggeredCard")) { final String[] condition = getParam("CheckOnTriggeredCard").split(" ", 2); diff --git a/forge-game/src/main/java/forge/game/zone/MagicStack.java b/forge-game/src/main/java/forge/game/zone/MagicStack.java index 50b148ccf1c..f80d241cec7 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -253,7 +253,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable