* Fixed a problem with flashback ability and variable non mana costs (related to #2436).

This commit is contained in:
LevelX2 2017-04-02 10:11:25 +02:00
parent a49f79cfc3
commit 15c1c7f8c0
4 changed files with 31 additions and 32 deletions

View file

@ -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");
@ -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);
}
}

View file

@ -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,9 +505,10 @@ 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<ManaCost> costIterator = manaCostsToPay.iterator();
@ -517,8 +517,8 @@ public abstract class AbilityImpl implements Ability {
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);
}

View file

@ -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);
}

View file

@ -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;
}