* Fixed a problem that conditional mana could not be correctly used with AsThoughEffects (fixes #6880).

This commit is contained in:
LevelX2 2020-07-25 22:11:30 +02:00
parent 202e25208e
commit 85d18899b1
4 changed files with 117 additions and 16 deletions

View file

@ -2,6 +2,7 @@ package org.mage.test.cards.asthough;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
@ -200,4 +201,60 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
assertLife(playerA, 20); assertLife(playerA, 20);
assertLife(playerB, 20 - 1); assertLife(playerB, 20 - 1);
} }
/**
* Chromatic Orrery allows it's controller to spend mana of any color as
* though it were mana of any color. With mana from Food Chain I should be
* able to cast creature spells using abritrary color of mana. But the game
* still requires to pay appropriate color as though there was no Orrery on
* my side of battlefield.
*/
@Test
public void testFoodChainWithChromaticOrrery() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, "Adriana, Captain of the Guard", 1); // Creature {3}{R}{W}
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1); // Creature {3}{W}
// Exile a creature you control: Add X mana of any one color, where X is the exiled creature's converted mana cost plus one.
// Spend this mana only to cast creature spells.
addCard(Zone.BATTLEFIELD, playerA, "Food Chain"); // Enchantment {2}{G}
// You may spend mana as though it were mana of any color.
// {T}: Add {C}{C}{C}{C}{C}.
// {5}, {T}: Draw a card for each color among permanents you control.
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Orrery"); // Artifact {7}
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile a creature you control");
setChoice(playerA, "Pillarfield Ox");
setChoice(playerA, "Red");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Adriana, Captain of the Guard");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
Assert.assertTrue("Mana pool of conditional mana has to be empty", playerA.getManaPool().getConditionalMana().isEmpty());
assertExileCount("Pillarfield Ox", 1);
assertPermanentCount(playerA, "Adriana, Captain of the Guard", 1);
}
@Test
public void testChromaticOrrery() {
setStrictChooseMode(true);
addCard(Zone.HAND, playerA, "Adriana, Captain of the Guard", 1); // Creature {3}{R}{W}
// You may spend mana as though it were mana of any color.
// {T}: Add {C}{C}{C}{C}{C}.
// {5}, {T}: Draw a card for each color among permanents you control.
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Orrery"); // Artifact {7}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Adriana, Captain of the Guard");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Adriana, Captain of the Guard", 1);
}
} }

View file

@ -296,4 +296,22 @@ public class TappedForManaRelatedTest extends CardTestPlayerBase {
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{B}{B}{Any}{Any}{Any}{Any}", manaOptions); assertManaOptions("{B}{B}{Any}{Any}{Any}{Any}", manaOptions);
} }
@Test
public void TestChromaticOrrery() {
setStrictChooseMode(true);
// You may spend mana as though it were mana of any color.
// {T}: Add {C}{C}{C}{C}{C}.
// {5}, {T}: Draw a card for each color among permanents you control.
addCard(Zone.BATTLEFIELD, playerA, "Chromatic Orrery", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
assertManaOptions("{C}{C}{C}{C}{C}", manaOptions);
}
} }

View file

@ -88,15 +88,14 @@ public class ManaPool implements Serializable {
* @return * @return
*/ */
public boolean pay(ManaType manaType, Ability ability, Filter filter, Game game, Cost costToPay, Mana usedManaToPay) { public boolean pay(ManaType manaType, Ability ability, Filter filter, Game game, Cost costToPay, Mana usedManaToPay) {
if (!isAutoPayment() if (!isAutoPayment() && manaType != unlockedManaType) {
&& manaType != unlockedManaType) {
// if manual payment and the needed mana type was not unlocked, nothing will be paid // if manual payment and the needed mana type was not unlocked, nothing will be paid
return false; return false;
} }
ManaType possibleAsThoughPoolManaType = null; ManaType possibleAsThoughPoolManaType = null;
if (isAutoPayment() if (isAutoPayment()
&& isAutoPaymentRestricted() && isAutoPaymentRestricted()
&& !wasManaAddedBeyondStock() && !wasManaAddedBeyondStock() // was not more mana added than at the start of casting something
&& manaType != unlockedManaType) { && manaType != unlockedManaType) {
// if automatic restricted payment and there is already mana in the pool // if automatic restricted payment and there is already mana in the pool
// and the needed mana type was not unlocked, nothing will be paid // and the needed mana type was not unlocked, nothing will be paid
@ -111,9 +110,10 @@ public class ManaPool implements Serializable {
return false; // if it's not possible return return false; // if it's not possible return
} }
} }
// first try to pay from conditional mana (the returned manaType can be changed if AsThoughEffects are active)
if (getConditional(manaType, ability, filter, game, costToPay) > 0) { ManaType conditionalManaType = getConditional(manaType, ability, filter, game, costToPay, possibleAsThoughPoolManaType);
removeConditional(manaType, ability, game, costToPay, usedManaToPay); if (conditionalManaType != null) {
removeConditional(conditionalManaType, ability, game, costToPay, usedManaToPay);
lockManaType(); // pay only one mana if mana payment is set to manually lockManaType(); // pay only one mana if mana payment is set to manually
return true; return true;
} }
@ -160,21 +160,33 @@ public class ManaPool implements Serializable {
return getMana().get(manaType); return getMana().get(manaType);
} }
private int getConditional(ManaType manaType, Ability ability, Filter filter, Game game, Cost costToPay) { private ManaType getConditional(ManaType manaType, Ability ability, Filter filter, Game game, Cost costToPay, ManaType possibleAsThoughPoolManaType) {
if (ability == null || getConditionalMana().isEmpty()) { if (ability == null || getConditionalMana().isEmpty()) {
return 0; return null;
} }
for (ManaPoolItem mana : manaItems) { for (ManaPoolItem mana : manaItems) {
if (mana.isConditional() if (mana.isConditional()) {
&& mana.getConditionalMana().get(manaType) > 0 ManaType manaTypeToUse = null;
&& mana.getConditionalMana().apply(ability, game, mana.getSourceId(), costToPay)) { if (mana.getConditionalMana().get(manaType) > 0) {
manaTypeToUse = manaType;
} else {
if (possibleAsThoughPoolManaType == null) {
possibleAsThoughPoolManaType = game.getContinuousEffects().asThoughMana(manaType, mana, ability.getSourceId(), ability, ability.getControllerId(), game);
}
if (possibleAsThoughPoolManaType != null && mana.getConditionalMana().get(possibleAsThoughPoolManaType) > 0) {
manaTypeToUse = possibleAsThoughPoolManaType;
}
}
if (manaTypeToUse != null && mana.getConditionalMana().apply(ability, game, mana.getSourceId(), costToPay)) {
if (filter == null if (filter == null
|| filter.match(mana.getSourceObject(), game)) { || filter.match(mana.getSourceObject(), game)) {
return mana.getConditionalMana().get(manaType); return manaTypeToUse;
} }
} }
} }
return 0; }
return null;
} }
public int getConditionalCount(Ability ability, Game game, FilterMana filter, Cost costToPay) { public int getConditionalCount(Ability ability, Game game, FilterMana filter, Cost costToPay) {

View file

@ -1,4 +1,3 @@
package mage.players; package mage.players;
import java.io.Serializable; import java.io.Serializable;
@ -205,6 +204,21 @@ public class ManaPoolItem implements Serializable {
} else if (colorless > 0) { } else if (colorless > 0) {
return ManaType.COLORLESS; return ManaType.COLORLESS;
} }
if (conditionalMana != null) {
if (conditionalMana.getBlack() > 0) {
return ManaType.BLACK;
} else if (conditionalMana.getBlue() > 0) {
return ManaType.BLUE;
} else if (conditionalMana.getGreen() > 0) {
return ManaType.GREEN;
} else if (conditionalMana.getRed() > 0) {
return ManaType.RED;
} else if (conditionalMana.getWhite() > 0) {
return ManaType.WHITE;
} else if (conditionalMana.getColorless() > 0) {
return ManaType.COLORLESS;
}
}
return null; return null;
} }