From 5c479eb9194e4d11106eed8451c6fae31b2cbbad Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 6 Jun 2013 17:37:49 +0200 Subject: [PATCH] Fixed a bug that x spells that need black mana to pay for x (e.g. Consume Spirit) could be paid with all kind of mana. --- .../sets/avacynrestored/BurnAtTheStake.java | 13 +++ .../src/mage/sets/innistrad/HarvestPyre.java | 13 +++ .../mage/sets/odyssey/SkeletalScrying.java | 13 +++ .../riseoftheeldrazi/DevastatingSummons.java | 13 +++ .../src/mage/sets/weatherlight/Firestorm.java | 13 +++ Mage/src/mage/abilities/AbilityImpl.java | 83 ++++++++++++++----- .../mage/abilities/costs/VariableCost.java | 1 + .../costs/common/PayVariableLoyaltyCost.java | 13 +++ .../RemoveVariableCountersSourceCost.java | 13 +++ .../RemoveVariableCountersTargetCost.java | 13 +++ .../costs/common/TapVariableTargetCost.java | 13 +++ .../costs/mana/VariableManaCost.java | 5 ++ 12 files changed, 184 insertions(+), 22 deletions(-) diff --git a/Mage.Sets/src/mage/sets/avacynrestored/BurnAtTheStake.java b/Mage.Sets/src/mage/sets/avacynrestored/BurnAtTheStake.java index 2a41b8c5591..89c2908d830 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/BurnAtTheStake.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/BurnAtTheStake.java @@ -129,10 +129,23 @@ class BurnAtTheStakeCost extends CostImpl implements Variabl return this.amountPaid; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public void setAmount(int amount) { this.amountPaid = amount; diff --git a/Mage.Sets/src/mage/sets/innistrad/HarvestPyre.java b/Mage.Sets/src/mage/sets/innistrad/HarvestPyre.java index e5e0206f861..f2d5fc62bad 100644 --- a/Mage.Sets/src/mage/sets/innistrad/HarvestPyre.java +++ b/Mage.Sets/src/mage/sets/innistrad/HarvestPyre.java @@ -120,10 +120,23 @@ class HarvestPyreCost extends CostImpl implements VariableCost return amountPaid; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public HarvestPyreCost copy() { return new HarvestPyreCost(this); diff --git a/Mage.Sets/src/mage/sets/odyssey/SkeletalScrying.java b/Mage.Sets/src/mage/sets/odyssey/SkeletalScrying.java index 74e25275e6e..f3a47ac2918 100644 --- a/Mage.Sets/src/mage/sets/odyssey/SkeletalScrying.java +++ b/Mage.Sets/src/mage/sets/odyssey/SkeletalScrying.java @@ -121,10 +121,23 @@ class ExileXFromGraveyardCost extends CostImpl implemen return amountPaid; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public ExileXFromGraveyardCost copy() { return new ExileXFromGraveyardCost(this); diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/DevastatingSummons.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/DevastatingSummons.java index a5eb67c5d9f..a665398dfd4 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/DevastatingSummons.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/DevastatingSummons.java @@ -117,10 +117,23 @@ class DevastatingSummonsCost extends CostImpl implements return amountPaid; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public DevastatingSummonsCost copy() { return new DevastatingSummonsCost(this); diff --git a/Mage.Sets/src/mage/sets/weatherlight/Firestorm.java b/Mage.Sets/src/mage/sets/weatherlight/Firestorm.java index 7bce7a945b7..236828fed18 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/Firestorm.java +++ b/Mage.Sets/src/mage/sets/weatherlight/Firestorm.java @@ -166,10 +166,23 @@ class FirestormCost extends CostImpl implements VariableCost { return amountPaid; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public FirestormCost copy() { return new FirestormCost(this); diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 55cae31eb5b..1a851a19d8b 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -196,28 +196,7 @@ public abstract class AbilityImpl> implements Ability { // 20121001 - 601.2b // If the spell has a variable cost that will be paid as it's being cast (such as an {X} in // its mana cost; see rule 107.3), the player announces the value of that variable. - // TODO: Handle announcing other variable costs here like: RemoveVariableCountersSourceCost - VariableManaCost variableManaCost = null; - for (ManaCost cost: manaCostsToPay) { - if (cost instanceof VariableManaCost) { - variableManaCost = (VariableManaCost) cost; - break; // only one VariableManCost per spell (or is it possible to have more?) - } - } - if (variableManaCost != null) { - int xValue; - if (!variableManaCost.isPaid()) { // should only happen for human players - if (!noMana) { - xValue = game.getPlayer(this.controllerId).announceXMana(variableManaCost.getMinX(), Integer.MAX_VALUE, "Announce the value for " + variableManaCost.getText(), game, this); - int amountMana = xValue * variableManaCost.getMultiplier(); - manaCostsToPay.add(new ManaCostsImpl(new StringBuilder("{").append(amountMana).append("}").toString())); - manaCostsToPay.setX(amountMana); - } - variableManaCost.setPaid(); - } - xValue = getManaCostsToPay().getX(); - game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString()); - } + VariableManaCost variableManaCost = handleXCosts(game, noMana); //20121001 - 601.2c // 601.2c The player announces his or her choice of an appropriate player, object, or zone for @@ -298,6 +277,66 @@ public abstract class AbilityImpl> implements Ability { return true; } + /** + * Handles the announcement of X mana costs and sets manaCostsToPay. + * + * @param game + * @param noMana + * @return variableManaCost for late check + */ + protected VariableManaCost handleXCosts(Game game, boolean noMana) { + // 20121001 - 601.2b + // If the spell has a variable cost that will be paid as it's being cast (such as an {X} in + // its mana cost; see rule 107.3), the player announces the value of that variable. + // TODO: Handle announcing other variable costs here like: RemoveVariableCountersSourceCost + VariableManaCost variableManaCost = null; + for (ManaCost cost: manaCostsToPay) { + if (cost instanceof VariableManaCost) { + variableManaCost = (VariableManaCost) cost; + break; // only one VariableManCost per spell (or is it possible to have more?) + } + } + if (variableManaCost != null) { + int xValue; + if (!variableManaCost.isPaid()) { // should only happen for human players + if (!noMana) { + xValue = game.getPlayer(this.controllerId).announceXMana(variableManaCost.getMinX(), Integer.MAX_VALUE, "Announce the value for " + variableManaCost.getText(), game, this); + int amountMana = xValue * variableManaCost.getMultiplier(); + StringBuilder manaString = new StringBuilder(); + if (variableManaCost.getFilter() == null || variableManaCost.getFilter().isColorless()) { + manaString.append("{").append(amountMana).append("}"); + } else { + String manaSymbol = null; + if (variableManaCost.getFilter().isBlack()) { + manaSymbol = "B"; + } else if (variableManaCost.getFilter().isRed()) { + manaSymbol = "R"; + } else if (variableManaCost.getFilter().isBlue()) { + manaSymbol = "U"; + } else if (variableManaCost.getFilter().isGreen()) { + manaSymbol = "G"; + } else if (variableManaCost.getFilter().isWhite()) { + manaSymbol = "W"; + } + if (manaSymbol == null) { + throw new UnsupportedOperationException("ManaFilter is not supported: " +this.toString() ); + } + for (int i = 0; i < amountMana; i++) { + manaString.append("{").append(manaSymbol).append("}"); + } + } + manaCostsToPay.add(new ManaCostsImpl(manaString.toString())); + manaCostsToPay.setX(amountMana); + } + variableManaCost.setPaid(); + } + xValue = getManaCostsToPay().getX(); + game.informPlayers(new StringBuilder(game.getPlayer(this.controllerId).getName()).append(" announced a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString()); + } + + return variableManaCost; + } + @Override public void reset(Game game) {} diff --git a/Mage/src/mage/abilities/costs/VariableCost.java b/Mage/src/mage/abilities/costs/VariableCost.java index ebcf234a317..a82bcebc3ba 100644 --- a/Mage/src/mage/abilities/costs/VariableCost.java +++ b/Mage/src/mage/abilities/costs/VariableCost.java @@ -39,4 +39,5 @@ public interface VariableCost { int getAmount(); void setAmount(int amount); void setFilter(FilterMana filter); + FilterMana getFilter(); } diff --git a/Mage/src/mage/abilities/costs/common/PayVariableLoyaltyCost.java b/Mage/src/mage/abilities/costs/common/PayVariableLoyaltyCost.java index 4d5443eef27..b16f1445309 100644 --- a/Mage/src/mage/abilities/costs/common/PayVariableLoyaltyCost.java +++ b/Mage/src/mage/abilities/costs/common/PayVariableLoyaltyCost.java @@ -93,10 +93,23 @@ public class PayVariableLoyaltyCost extends CostImpl imp amountPaid = amount; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public PayVariableLoyaltyCost copy() { return new PayVariableLoyaltyCost(this); diff --git a/Mage/src/mage/abilities/costs/common/RemoveVariableCountersSourceCost.java b/Mage/src/mage/abilities/costs/common/RemoveVariableCountersSourceCost.java index 2c4a0c93c70..8de3941e674 100644 --- a/Mage/src/mage/abilities/costs/common/RemoveVariableCountersSourceCost.java +++ b/Mage/src/mage/abilities/costs/common/RemoveVariableCountersSourceCost.java @@ -103,10 +103,23 @@ public class RemoveVariableCountersSourceCost extends CostImpl imple amountPaid = amount; } + /** + * Not Supported + * @param filter + */ @Override public void setFilter(FilterMana filter) { } + /** + * Not supported + * @return + */ + @Override + public FilterMana getFilter() { + return new FilterMana(); + } + @Override public TapVariableTargetCost copy() { return new TapVariableTargetCost(this); diff --git a/Mage/src/mage/abilities/costs/mana/VariableManaCost.java b/Mage/src/mage/abilities/costs/mana/VariableManaCost.java index 99fc604d4a3..7617386f10d 100644 --- a/Mage/src/mage/abilities/costs/mana/VariableManaCost.java +++ b/Mage/src/mage/abilities/costs/mana/VariableManaCost.java @@ -115,6 +115,11 @@ public class VariableManaCost extends ManaCostImpl implements this.filter = filter; } + @Override + public FilterMana getFilter() { + return filter; + } + @Override public VariableManaCost copy() { return new VariableManaCost(this);