diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java index 3949a11ee0..f5b8e3b141 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ChaliceOfTheVoidTest.java @@ -40,17 +40,18 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { /** * Theres a Chalice of the Void with 1 counter in play under my control. - * Then I cast second chalice with x=1. For spells on the stack the cmc is the base CMC + X value * {X} in casting costs on top right of card. - * So cmc should be 2 in this case, it shouldnt be countered. + * Then I cast second chalice with x=1. For spells on the stack the cmc is + * the base CMC + X value * {X} in casting costs on top right of card. So + * cmc should be 2 in this case, it shouldnt be countered. * http://boardgames.stackexchange.com/questions/7327/what-is-the-converted-mana-cost-of-a-spell-with-x-when-cast-with-the-miracle-m */ - @Test public void testX1CountsFor2CMC() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + // Chalice of the Void enters the battlefield with X charge counters on it. + // Whenever a player casts a spell with converted mana cost equal to the number of charge counters on Chalice of the Void, counter that spell. addCard(Zone.HAND, playerA, "Chalice of the Void", 2); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); setChoice(playerA, "X=1"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); @@ -62,10 +63,10 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Chalice of the Void", 2); } - + /* If X=1 the cmc of Chalice on the stack is 2. So it can't be countered by Mental Misstep - */ + */ @Test public void testCantBeCounteredByMentalMisstep() { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); @@ -94,6 +95,8 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); addCard(Zone.HAND, playerA, "Chalice of the Void", 1); + // Conflagrate deals X damage divided as you choose among any number of target creatures and/or players. + // Flashback-{R}{R}, Discard X cards. addCard(Zone.GRAVEYARD, playerB, "Conflagrate", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2); addCard(Zone.HAND, playerB, "Mountain", 1); @@ -101,7 +104,6 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void"); setChoice(playerA, "X=1"); - activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flashback {R}{R}"); setChoice(playerB, "X=1"); addTarget(playerB, playerA); @@ -109,13 +111,12 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase { setStopAt(2, PhaseStep.BEGIN_COMBAT); execute(); - assertLife(playerA, 19); - assertLife(playerB, 20); - assertExileCount(playerB, "Conflagrate", 1); //TODO: Apparently there are two mountains in the graveyard at the end of the test now. - //assertGraveyardCount(playerB, "Mountain", 1); + assertGraveyardCount(playerB, "Mountain", 1); + assertLife(playerA, 19); + assertLife(playerB, 20); } - + } diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index cc30fc971f..4fc787292b 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -27,6 +27,10 @@ */ package mage.abilities; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; import mage.MageObject; import mage.MageObjectReference; import mage.Mana; @@ -59,11 +63,6 @@ import mage.util.ThreadLocalStringBuilder; import mage.watchers.Watcher; import org.apache.log4j.Logger; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.UUID; - /** * @author BetaSteward_at_googlemail.com */ @@ -489,7 +488,7 @@ public abstract class AbilityImpl implements Ability { protected String handleOtherXCosts(Game game, Player controller) { StringBuilder announceString = new StringBuilder(); for (VariableCost variableCost : this.costs.getVariableCosts()) { - if (!(variableCost instanceof VariableManaCost)) { + if (!(variableCost instanceof VariableManaCost) && !((Cost) variableCost).isPaid()) { int xValue = variableCost.announceXValue(this, game); Cost fixedCost = variableCost.getFixedCostsFromAnnouncedValue(xValue); if (fixedCost != null) { @@ -506,19 +505,20 @@ public abstract class AbilityImpl implements Ability { } /** - * 601.2b - * If a cost that will be paid as the spell is being cast includes Phyrexian mana symbols, - * the player announces whether he or she intends to pay 2 life or the corresponding colored mana cost for each of those symbols. + * 601.2b If a cost that will be paid as the spell is being cast includes + * Phyrexian mana symbols, the player announces whether he or she intends to + * pay 2 life or the corresponding colored mana cost for each of those + * symbols. */ private void handlePhyrexianManaCosts(Game game, UUID sourceId, Player controller) { Iterator costIterator = manaCostsToPay.iterator(); - while(costIterator.hasNext()) { + while (costIterator.hasNext()) { ManaCost cost = costIterator.next(); - if(cost instanceof PhyrexianManaCost) { - PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost)cost; + if (cost instanceof PhyrexianManaCost) { + PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost) cost; PayLifeCost payLifeCost = new PayLifeCost(2); - if(payLifeCost.canPay(this, sourceId, controller.getId(), game) && - controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + '?', this, game)) { + if (payLifeCost.canPay(this, sourceId, controller.getId(), game) + && controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + phyrexianManaCost.getBaseText() + '?', this, game)) { costIterator.remove(); costs.add(payLifeCost); } diff --git a/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java b/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java index f0f6f2e946..83a785a8fa 100644 --- a/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/VariableCostImpl.java @@ -29,6 +29,7 @@ package mage.abilities.costs; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.keyword.FlashbackAbility; import mage.game.Game; import mage.game.stack.StackObject; import mage.players.Player; @@ -170,7 +171,7 @@ public abstract class VariableCostImpl implements Cost, VariableCost { Player controller = game.getPlayer(source.getControllerId()); StackObject stackObject = game.getStack().getStackObject(source.getId()); if (controller != null - && stackObject != null) { + && (source instanceof FlashbackAbility || stackObject != null)) { xValue = controller.announceXCost(getMinValue(source, game), getMaxValue(source, game), "Announce the number of " + actionText, game, source, this); } diff --git a/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java index 51c084654b..e41df6c899 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/DiscardXTargetCost.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.costs.common; import mage.abilities.Ability; @@ -40,7 +39,6 @@ import mage.target.common.TargetCardInHand; * * @author LevelX2 */ - public class DiscardXTargetCost extends VariableCostImpl { protected FilterCard filter; @@ -50,9 +48,8 @@ public class DiscardXTargetCost extends VariableCostImpl { } public DiscardXTargetCost(FilterCard filter, boolean additionalCostText) { - super(new StringBuilder(filter.getMessage()).append(" to discard").toString()); - this.text = new StringBuilder(additionalCostText ? "As an additional cost to cast {source}, discard ":"Discard ") - .append(xText).append(' ').append(filter.getMessage()).toString(); + super(filter.getMessage() + " to discard"); + this.text = (additionalCostText ? "As an additional cost to cast {source}, discard " : "Discard ") + xText + ' ' + filter.getMessage(); this.filter = filter; }