From 503857f1d82e29a17d475b0f8a35e6bb0d0dd0c3 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Mon, 16 Jan 2023 18:16:05 +0100 Subject: [PATCH] Improve trigger --- .../main/java/forge/game/cost/CostExert.java | 27 ++++++++++++++----- .../main/java/forge/game/cost/CostPart.java | 6 ++--- .../game/staticability/StaticAbility.java | 12 +++++++++ .../StaticAbilityCantAttackBlock.java | 2 +- .../res/cardsfolder/a/ahn_crop_crasher.txt | 5 ++-- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/forge-game/src/main/java/forge/game/cost/CostExert.java b/forge-game/src/main/java/forge/game/cost/CostExert.java index 0e8087baefd..421e7b4fa69 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExert.java +++ b/forge-game/src/main/java/forge/game/cost/CostExert.java @@ -17,13 +17,18 @@ */ package forge.game.cost; -import forge.game.ability.AbilityFactory; -import forge.game.ability.AbilityUtils; +import java.util.Map; + +import com.google.common.collect.Maps; + import forge.game.card.Card; import forge.game.card.CardCollectionView; import forge.game.card.CardLists; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.trigger.Trigger; +import forge.game.trigger.TriggerHandler; +import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; /** @@ -98,10 +103,20 @@ public class CostExert extends CostPartWithList { @Override protected Card doPayment(SpellAbility ability, Card targetCard, final boolean effect) { - if (trigger != null) { - SpellAbility trig = AbilityFactory.getAbility(targetCard.getSVar(trigger), targetCard); - trig.setActivatingPlayer(ability.getActivatingPlayer()); - AbilityUtils.resolve(trig); + if (payingTrigSA != null) { + Map mapParams = Maps.newHashMap(); + mapParams.put("TriggerDescription", payingTrigSA.getParam("SpellDescription")); + mapParams.put("Mode", TriggerType.Immediate.name()); + + SpellAbility sa = payingTrigSA.copy(targetCard, ability.getActivatingPlayer(), false); + + final Trigger immediateTrig = TriggerHandler.parseTrigger(mapParams, targetCard, sa.isIntrinsic(), null); + immediateTrig.setSpawningAbility(ability); // make the StaticAbility the Spawning one? + + immediateTrig.setOverridingAbility(sa); + + // Instead of registering this, add to the delayed triggers as an immediate trigger type? Which means it'll fire as soon as possible + targetCard.getGame().getTriggerHandler().registerDelayedTrigger(immediateTrig); } targetCard.exert(); return targetCard; diff --git a/forge-game/src/main/java/forge/game/cost/CostPart.java b/forge-game/src/main/java/forge/game/cost/CostPart.java index 769867b2a03..134006ff767 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPart.java +++ b/forge-game/src/main/java/forge/game/cost/CostPart.java @@ -41,7 +41,7 @@ public abstract class CostPart implements Comparable, Cloneable, Seria private final String originalType, originalTypeDescription; private String typeDescription, type; - protected String trigger; + protected transient SpellAbility payingTrigSA; /** * Instantiates a new cost part. @@ -156,8 +156,8 @@ public abstract class CostPart implements Comparable, Cloneable, Seria return AbilityUtils.calculateAmount(ability.getHostCard(), getAmount(), ability); } - public void setTrigger(String trig) { - trigger = trig; + public void setTrigger(SpellAbility sa) { + payingTrigSA = sa; } /** 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 cea08f058cd..7b0dc6b67fd 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -31,6 +31,7 @@ import forge.game.Game; import forge.game.GameEntity; import forge.game.GameStage; import forge.game.IIdentifiable; +import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardCollection; @@ -41,6 +42,7 @@ import forge.game.cost.Cost; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.Player; +import forge.game.spellability.SpellAbility; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.CardTranslation; @@ -63,6 +65,8 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone private final List ignoreEffectPlayers = Lists.newArrayList(); private int mayPlayTurn = 0; + private SpellAbility payingTrigSA; + @Override public final int getId() { return id; @@ -78,6 +82,14 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone return obj instanceof StaticAbility && this.id == ((StaticAbility) obj).id; } + public SpellAbility getPayingTrigSA() { + // already cached? + if (payingTrigSA == null) { + payingTrigSA = AbilityFactory.getAbility(getSVar(getParam("Trigger")), getHostCard()); + } + return payingTrigSA; + } + /** *

* Getter for the field mapParams. diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java index f6d2a7eb51b..d3616157dd7 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCantAttackBlock.java @@ -188,7 +188,7 @@ public class StaticAbilityCantAttackBlock { Cost cost = new Cost(costString, true); if (stAb.hasParam("Trigger")) { - cost.getCostParts().get(0).setTrigger(stAb.getParam("Trigger")); + cost.getCostParts().get(0).setTrigger(stAb.getPayingTrigSA()); } return cost; diff --git a/forge-gui/res/cardsfolder/a/ahn_crop_crasher.txt b/forge-gui/res/cardsfolder/a/ahn_crop_crasher.txt index 8b0e88b69f8..6b28dc37c12 100644 --- a/forge-gui/res/cardsfolder/a/ahn_crop_crasher.txt +++ b/forge-gui/res/cardsfolder/a/ahn_crop_crasher.txt @@ -3,7 +3,6 @@ ManaCost:2 R Types:Creature Minotaur Warrior PT:3/2 K:Haste -S:Mode$ CantAttackUnless | ValidCard$ Card.Self | Trigger$ TrigExert | Cost$ Exert<1/CARDNAME> | Description$ You may exert CARDNAME as it attacks. When you do, target creature can't block this turn. -SVar:TrigExert:DB$ ImmediateTrigger | Execute$ TrigCanNotBlock | TriggerDescription$ When you exert CARDNAME, target creature can't block this turn. -SVar:TrigCanNotBlock:DB$ Pump | ValidTgts$ Creature | KW$ HIDDEN CARDNAME can't block. | TgtPrompt$ Select target creature. | IsCurse$ True | SpellDescription$ Target creature can't block this turn. +S:Mode$ CantAttackUnless | ValidCard$ Card.Self | Trigger$ TrigCanNotBlock | Cost$ Exert<1/CARDNAME> | Description$ You may exert CARDNAME as it attacks. When you do, target creature can't block this turn. +SVar:TrigCanNotBlock:DB$ Pump | ValidTgts$ Creature | KW$ HIDDEN CARDNAME can't block. | TgtPrompt$ Select target creature. | IsCurse$ True | SpellDescription$ When you do, target creature can't block this turn. Oracle:Haste\nYou may exert Ahn-Crop Crasher as it attacks. When you do, target creature can't block this turn. (An exerted creature won't untap during your next untap step.)