From b17c106d10ec18d6d47e2214eaa24aa54d531cea Mon Sep 17 00:00:00 2001 From: Northmoc Date: Sun, 30 Oct 2022 10:02:14 -0400 Subject: [PATCH] improve handling for multiple defilers of same color --- .../main/java/forge/game/GameActionUtil.java | 1 + .../java/forge/game/cost/CostAdjustment.java | 19 ++------- .../forge/game/spellability/OptionalCost.java | 39 ++++++++++++------- .../game/spellability/OptionalCostValue.java | 5 ++- .../forge/game/spellability/SpellAbility.java | 20 ++++++---- 5 files changed, 45 insertions(+), 39 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index e1f4bd077b3..10e671b8ebf 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -936,6 +936,7 @@ public final class GameActionUtil { ability.setHostCard(oldCard); ability.setXManaCostPaid(null); ability.setSpendPhyrexianMana(false); + ability.clearPipsToReduce(); ability.setPaidLife(0); if (ability.hasParam("Announce")) { for (final String aVar : ability.getParam("Announce").split(",")) { diff --git a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java index acf85b5d268..6493c8138fd 100644 --- a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java +++ b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java @@ -4,7 +4,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import forge.game.spellability.OptionalCost; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Strings; @@ -209,20 +208,10 @@ public class CostAdjustment { // need to reduce generic extra because of 2 hybrid mana cost.decreaseGenericMana(sumGeneric); - if (sa.isSpell() && sa.isOptionalCostPaid(OptionalCost.ReduceW)) { - cost.decreaseShard(ManaCostShard.parseNonGeneric("W"), 1); - } - if (sa.isSpell() && sa.isOptionalCostPaid(OptionalCost.ReduceU)) { - cost.decreaseShard(ManaCostShard.parseNonGeneric("U"), 1); - } - if (sa.isSpell() && sa.isOptionalCostPaid(OptionalCost.ReduceB)) { - cost.decreaseShard(ManaCostShard.parseNonGeneric("B"), 1); - } - if (sa.isSpell() && sa.isOptionalCostPaid(OptionalCost.ReduceR)) { - cost.decreaseShard(ManaCostShard.parseNonGeneric("R"), 1); - } - if (sa.isSpell() && sa.isOptionalCostPaid(OptionalCost.ReduceG)) { - cost.decreaseShard(ManaCostShard.parseNonGeneric("G"), 1); + if (sa.isSpell() && !sa.getPipsToReduce().isEmpty()) { + for (String pip : sa.getPipsToReduce()) { + cost.decreaseShard(ManaCostShard.parseNonGeneric(pip), 1); + } } if (sa.isSpell() && sa.isOffering()) { // cost reduction from offerings diff --git a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java index 73c2053de80..8098fcc3036 100644 --- a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java +++ b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java @@ -5,25 +5,27 @@ package forge.game.spellability; * */ public enum OptionalCost { - Buyback("Buyback"), - Entwine("Entwine"), - Kicker1("Kicker"), - Kicker2("Kicker"), - Retrace("Retrace"), - Jumpstart("Jump-start"), - ReduceW("(to reduce white mana)"), - ReduceU("(to reduce blue mana)"), - ReduceB("(to reduce black mana)"), - ReduceR("(to reduce red mana)"), - ReduceG("(to reduce green mana)"), - AltCost(""), - Flash("Flash"), // used for Pay Extra for Flash - Generic("Generic"); // used by "Dragon Presence" and pseudo-kicker cards + Buyback("Buyback", ""), + Entwine("Entwine", ""), + Kicker1("Kicker", ""), + Kicker2("Kicker", ""), + Retrace("Retrace", ""), + Jumpstart("Jump-start", ""), + ReduceW("(to reduce white mana)", "W"), + ReduceU("(to reduce blue mana)", "U"), + ReduceB("(to reduce black mana)", "B"), + ReduceR("(to reduce red mana)", "R"), + ReduceG("(to reduce green mana)", "G"), + AltCost("", ""), + Flash("Flash", ""), // used for Pay Extra for Flash + Generic("Generic", ""); // used by "Dragon Presence" and pseudo-kicker cards private String name; + private String pip; - OptionalCost(String name) { + OptionalCost(String name, String pip) { this.name = name; + this.pip = pip; } /** @@ -32,4 +34,11 @@ public enum OptionalCost { public String getName() { return name; } + + /** + * @return the pip + */ + public String getPip() { + return pip; + } } diff --git a/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java b/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java index aa2e20e6851..4375a6c956f 100644 --- a/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java +++ b/forge-game/src/main/java/forge/game/spellability/OptionalCostValue.java @@ -51,12 +51,13 @@ public class OptionalCostValue implements Serializable { @Override public String toString() { StringBuilder sb = new StringBuilder(); - if (type != OptionalCost.Generic && !type.getName().startsWith("(to reduce")) { + boolean isTag = type.getName().startsWith("("); + if (type != OptionalCost.Generic && !isTag) { sb.append(type.getName()); sb.append(" "); } sb.append(cost.toSimpleString()); - sb.append(type.getName().startsWith("(to reduce") ? " " + type.getName() : ""); + sb.append(isTag ? " " + type.getName() : ""); return sb.toString(); } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index 58b65519477..e791812c8bc 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -17,13 +17,7 @@ */ package forge.game.spellability; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -159,6 +153,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private EnumMap replacingObjects = AbilityKey.newMap(); + private final List pipsToReduce = new ArrayList<>(); + private List chosenList = null; private CardCollection tappedForConvoke = new CardCollection(); private Card sacrificedAsOffering; @@ -716,6 +712,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit // Thus, to protect the original's set from changes, we make a copy right here. optionalCosts = EnumSet.copyOf(optionalCosts); optionalCosts.add(cost); + if (!cost.getPip().equals("")) { + pipsToReduce.add(cost.getPip()); + } } public boolean isBuyBackAbility() { @@ -1484,6 +1483,13 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return isAlternativeCost(AlternativeCost.Spectacle); } + public List getPipsToReduce() { + return pipsToReduce; + } + public final void clearPipsToReduce() { + pipsToReduce.clear(); + } + public CardCollection getTappedForConvoke() { return tappedForConvoke; }