From d32cde8889f8c339bb4a79a7c7f0d17551ca44ce Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Fri, 28 Jul 2023 17:51:15 +0200 Subject: [PATCH] Clean up train continues --- .../java/forge/game/ability/AbilityUtils.java | 4 +- .../game/ability/effects/ChangeXEffect.java | 13 +- .../java/forge/game/card/CardProperty.java | 2 +- .../SpellAbilityStackInstance.java | 122 ++---------------- .../main/java/forge/game/zone/MagicStack.java | 29 +++-- ...aster_combat_dj_blaster_morale_booster.txt | 2 +- .../upcoming/glorfindel_dauntless_rescuer.txt | 6 +- .../forge/player/HumanPlaySpellAbility.java | 5 - 8 files changed, 35 insertions(+), 148 deletions(-) diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index c196753fc1d..7dd54b37a25 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -1715,12 +1715,12 @@ public class AbilityUtils { && ZoneType.Battlefield.name().equals(t.getParam("Destination"))) { return doXMath(c.getXManaCostPaid(), expr, c, ctb); } else if (TriggerType.SpellCast.equals(t.getMode())) { - // Cast Trigger like Hydroid Krasis, use SI because Unbound Flourishing might change X + // Cast Trigger like Hydroid Krasis SpellAbilityStackInstance castSI = (SpellAbilityStackInstance) root.getTriggeringObject(AbilityKey.StackInstance); if (castSI == null) { return doXMath(0, expr, c, ctb); } - return doXMath(castSI.getXManaPaid(), expr, c, ctb); + return doXMath(castSI.getSpellAbility(false).getXManaCostPaid(), expr, c, ctb); } else if (TriggerType.Cycled.equals(t.getMode())) { SpellAbility cycleSA = (SpellAbility) sa.getTriggeringObject(AbilityKey.Cause); if (cycleSA == null || cycleSA.getXManaCostPaid() == null) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeXEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeXEffect.java index 9f60b026306..8e5c65c69fd 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeXEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeXEffect.java @@ -3,10 +3,7 @@ package forge.game.ability.effects; import java.util.List; import forge.game.ability.SpellAbilityEffect; -import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import forge.game.spellability.SpellAbilityStackInstance; -import forge.game.zone.MagicStack; public class ChangeXEffect extends SpellAbilityEffect { @@ -19,21 +16,13 @@ public class ChangeXEffect extends SpellAbilityEffect { // even if they are in the Triggered Objects final List sas = getTargetSpells(sa); - final Player activator = sa.getActivatingPlayer(); - - final MagicStack stack = activator.getGame().getStack(); for (final SpellAbility tgtSA : sas) { // for Unbound Flourishing, can't go over SpellAbilityStackInstances because the x is in cast SA copy SpellAbility castSA = tgtSA.getHostCard().getCastSA(); if (castSA != null && tgtSA.equals(castSA) && castSA.getXManaCostPaid() != null) { castSA.setXManaCostPaid(castSA.getXManaCostPaid() * 2); } - // fall back to other potential cards - SpellAbilityStackInstance si = stack.getInstanceMatchingSpellAbilityID(tgtSA); - if (si != null) { - // currently hard coded, no nicer way to get the xManaPaid from that Spell/Card - si.setXManaPaid(si.getXManaPaid() * 2); - } + tgtSA.setXManaCostPaid(castSA.getXManaCostPaid() * 2); } } } diff --git a/forge-game/src/main/java/forge/game/card/CardProperty.java b/forge-game/src/main/java/forge/game/card/CardProperty.java index 8dc3c7b965b..df41c11c188 100644 --- a/forge-game/src/main/java/forge/game/card/CardProperty.java +++ b/forge-game/src/main/java/forge/game/card/CardProperty.java @@ -721,7 +721,7 @@ public class CardProperty { if (castSA == null) { return false; } - List payingMana = castSA.getPayingMana(); + List payingMana = castSA.getSpellAbility(false).getPayingMana(); // even if the cost was raised, we only care about mana from activation part // since this can only be 1 currently with Protective Sphere, let's just assume it's the first shard spent for easy handling if (payingMana.isEmpty() || !card.getColor().hasAnyColor(payingMana.get(0).getColor())) { diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java index 51e07935263..893dd5b3600 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityStackInstance.java @@ -17,27 +17,19 @@ */ package forge.game.spellability; -import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; -import org.apache.commons.lang3.StringUtils; - -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.google.common.collect.TreeBasedTable; import forge.game.GameObject; import forge.game.IIdentifiable; import forge.game.ability.AbilityKey; import forge.game.ability.ApiType; import forge.game.card.Card; -import forge.game.card.CardCollection; import forge.game.card.CardView; import forge.game.card.IHasCardView; -import forge.game.mana.Mana; import forge.game.player.Player; import forge.game.trigger.TriggerType; import forge.game.trigger.WrappedAbility; @@ -71,32 +63,8 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { private final SpellAbilityStackInstance subInstance; private Player activatingPlayer; - // When going to a SubAbility that SA has a Instance Choice object - private TargetChoices tc = new TargetChoices(); - private CardCollection splicedCards = null; - private String stackDescription = null; - // Adjusted Mana Cost - // private String adjustedManaCost = ""; - - // Paid Mana Cost - private List payingMana; - // private ArrayList paidAbilities = new ArrayList(); - private Integer xManaPaid = null; - - // Other Paid things - private final TreeBasedTable paidHash; - - // Additional info - // is Kicked, is Buyback - - // Triggers - private final Map triggeringObjects; - private final List triggerRemembered; - - private final Map storedSVars = Maps.newHashMap(); - private final Map playersWithValidTargets; private final StackItemView view; @@ -108,46 +76,18 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { stackDescription = sa.getStackDescription(); activatingPlayer = sa.getActivatingPlayer(); - // Payment info - paidHash = TreeBasedTable.create(ability.getPaidHash()); - ability.resetPaidHash(); - splicedCards = sa.getSplicedCards(); - - xManaPaid = sa.getXManaCostPaid(); - payingMana = Lists.newArrayList(sa.getPayingMana()); - - // Triggering info - triggeringObjects = sa.getTriggeringObjects(); - triggerRemembered = sa.getTriggerRemembered(); - subInstance = ability.getSubAbility() == null ? null : new SpellAbilityStackInstance(ability.getSubAbility()); - // Targeting info -- 29/06/11 Moved to after taking care of SubAbilities - // because otherwise AF_DealDamage SubAbilities that use Defined$ - // Targeted breaks (since it's parents target is reset) - if (sa.usesTargeting()) { - tc = ability.getTargets(); - ability.resetTargets(); - } - final Card source = ability.getHostCard(); - // We probably should be storing SA svars too right? - if (!sa.isWrapper()) { - for (final Entry e : sa.getDirectSVars().entrySet()) { - final String value = e.getValue(); - if (!StringUtils.isEmpty(value)) { - storedSVars.put(e.getKey(), value); - } - } - } - - if (ApiType.SetState == sa.getApi() && !storedSVars.containsKey("StoredTransform")) { + final Map sVars = (ability.isWrapper() ? ((WrappedAbility) ability).getWrappedAbility() : ability).getDirectSVars(); + if (ApiType.SetState == sa.getApi() && !sVars.containsKey("StoredTransform")) { // Record current state of Transformation if the ability might change state - storedSVars.put("StoredTransform", String.valueOf(source.getTransformedTimestamp())); + sVars.put("StoredTransform", String.valueOf(source.getTransformedTimestamp())); } //store zones to open and players to open them for at the time the SpellAbility first goes on the stack based on the selected targets + TargetChoices tc = ability.getTargets(); if (tc == null) { playersWithValidTargets = null; } else { @@ -172,33 +112,12 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { // Perhaps lets move the refresh logic to a separate function called only when necessary public final SpellAbility getSpellAbility(boolean refresh) { if (refresh) { - ability.setTargets(tc); ability.setActivatingPlayer(activatingPlayer); // Saved sub-SA needs to be reset on the way out if (subInstance != null) { ability.setSubAbility((AbilitySub) subInstance.getSpellAbility(true)); } - - // Set Cost specific things here - ability.setPaidHash(paidHash); - ability.setSplicedCards(splicedCards); - ability.setXManaCostPaid(xManaPaid); - ability.setPayingMana(payingMana); - - // Triggered - ability.setTriggeringObjects(triggeringObjects); - ability.setTriggerRemembered(triggerRemembered); - - // Add SVars back in - final SpellAbility sa = ability.isWrapper() ? ((WrappedAbility) ability).getWrappedAbility() : ability; - for (final String store : storedSVars.keySet()) { - final String value = storedSVars.get(store); - - if (!StringUtils.isEmpty(value)) { - sa.setSVar(store, value); - } - } } return ability; } @@ -211,13 +130,6 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { public final Card getSourceCard() { return ability.getHostCard(); } - - public final int getXManaPaid() { - return xManaPaid == null ? 0 : xManaPaid; - } - public final void setXManaPaid(int x) { - xManaPaid = x; - } public final boolean isSpell() { return ability.isSpell(); @@ -244,7 +156,7 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { } public final TargetChoices getTargetChoices() { - return tc; + return ability.getTargets(); } public final Map getPlayersWithValidTargets() { @@ -253,9 +165,8 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { public void updateTarget(TargetChoices target, Card cause) { if (target != null) { - TargetChoices oldTarget = tc; - tc = target; - ability.setTargets(tc); + TargetChoices oldTarget = ability.getTargets(); + ability.setTargets(target); stackDescription = ability.getStackDescription(); view.updateTargetCards(this); view.updateTargetPlayers(this); @@ -293,26 +204,21 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { } public boolean addTriggeringObject(AbilityKey trigObj, Object value) { - if (!triggeringObjects.containsKey(trigObj)) { - triggeringObjects.put(trigObj, value); + if (!ability.hasTriggeringObject(trigObj)) { + ability.setTriggeringObject(trigObj, value); return true; } return false; } - public boolean updateTriggeringObject(AbilityKey trigObj, Object value) { - if (triggeringObjects.containsKey(trigObj)) { - triggeringObjects.replace(trigObj, value); + if (ability.hasTriggeringObject(trigObj)) { + ability.setTriggeringObject(trigObj, value); return true; } return false; } - public Object getTriggeringObject(AbilityKey trigObj) { - if (triggeringObjects.containsKey(trigObj)) { - return triggeringObjects.get(trigObj); - } - return null; + return ability.getTriggeringObject(trigObj); } public Player getActivatingPlayer() { @@ -327,10 +233,6 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView { } } - public List getPayingMana() { - return payingMana; - } - @Override public String toString() { return TextUtil.concatNoSpace(getSourceCard().toString(), "->", getStackDescription()); 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 62eb0d38012..34b40668a16 100644 --- a/forge-game/src/main/java/forge/game/zone/MagicStack.java +++ b/forge-game/src/main/java/forge/game/zone/MagicStack.java @@ -159,8 +159,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable runParams = AbilityKey.mapFromPlayer(sp.getHostCard().getController()); @@ -444,7 +446,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable