From 2fceafda9388efa574947e1eb5463c9d151b76c1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 25 Feb 2018 21:53:47 +0100 Subject: [PATCH] * Fixed a bug that mana in the mana pool could not be used to pay mana costs that could only be payed with "you may spend mana as thought" effects (fixes #2581). --- Mage.Sets/src/mage/cards/h/HostageTaker.java | 6 +-- .../cards/asthough/SpendOtherManaTest.java | 30 +++++++++++++++ Mage/src/main/java/mage/Mana.java | 38 ++++++++++++++++--- Mage/src/main/java/mage/players/ManaPool.java | 13 ++++++- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java index 92605814ab2..73bc0f278c1 100644 --- a/Mage.Sets/src/mage/cards/h/HostageTaker.java +++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java @@ -41,10 +41,10 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AsThoughEffectType; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.ManaType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; @@ -118,8 +118,8 @@ class HostageTakerExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent card = game.getPermanent(targetPointer.getFirst(game, source)); - Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent card = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null && card != null) { Player controller = game.getPlayer(card.getControllerId()); if (controller != null) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java index a71cef7116f..76d22a2f123 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/asthough/SpendOtherManaTest.java @@ -134,4 +134,34 @@ public class SpendOtherManaTest extends CardTestPlayerBase { assertHandCount(playerA, "Nissa, Voice of Zendikar", 0); assertPermanentCount(playerA, "Nissa, Voice of Zendikar", 1); } + + @Test + public void testUseSpendManaAsThoughWithManaFromPool() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "Island", 1); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); + + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // Creature {1}{W} + + // When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. + // You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell. + addCard(Zone.HAND, playerA, "Hostage Taker"); // {2}{U}{B} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker"); + setChoice(playerA, "Silvercoat Lion"); + + activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R} to your mana pool."); // red mana to pool + activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R} to your mana pool."); // red mana to pool + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Silvercoat Lion"); // cast it from exile with red mana from pool + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Hostage Taker", 1); + assertTappedCount("Mountain", true, 4); + + assertPermanentCount(playerA, "Silvercoat Lion", 1); + + } + } diff --git a/Mage/src/main/java/mage/Mana.java b/Mage/src/main/java/mage/Mana.java index b2461d2b367..0e9aaf28253 100644 --- a/Mage/src/main/java/mage/Mana.java +++ b/Mage/src/main/java/mage/Mana.java @@ -131,6 +131,35 @@ public class Mana implements Comparable, Serializable, Copyable { } } + public Mana(final ManaType manaType) { + Objects.requireNonNull(manaType, "The passed in ManaType can not be null"); + switch (manaType) { + case GREEN: + green = 1; + break; + case RED: + red = 1; + break; + case BLACK: + black = 1; + break; + case BLUE: + blue = 1; + break; + case WHITE: + white = 1; + break; + case COLORLESS: + colorless = 1; + break; + case GENERIC: + generic = 1; + break; + default: + throw new IllegalArgumentException("Unknown manaType: " + manaType); + } + } + /** * Creates a {@link Mana} object with the passed in {@code num} of Red mana. * {@code num} can not be a negative value. Negative values will be logged @@ -222,13 +251,12 @@ public class Mana implements Comparable, Serializable, Copyable { } /** - * Creates a {@link Mana} object with the passed in {@code num} of Any - * mana. {@code num} can not be a negative value. Negative values will be - * logged and set to 0. + * Creates a {@link Mana} object with the passed in {@code num} of Any mana. + * {@code num} can not be a negative value. Negative values will be logged + * and set to 0. * * @param num value of Any mana to create. - * @return a {@link Mana} object with the passed in {@code num} of Any - * mana. + * @return a {@link Mana} object with the passed in {@code num} of Any mana. */ public static Mana AnyMana(int num) { return new Mana(0, 0, 0, 0, 0, 0, notNegative(num, "Any"), 0); diff --git a/Mage/src/main/java/mage/players/ManaPool.java b/Mage/src/main/java/mage/players/ManaPool.java index 62ddedf6d6b..565e96cac21 100644 --- a/Mage/src/main/java/mage/players/ManaPool.java +++ b/Mage/src/main/java/mage/players/ManaPool.java @@ -118,10 +118,19 @@ public class ManaPool implements Serializable { // if manual payment and the needed mana type was not unlocked, nothing will be paid return false; } + ManaType possibleAsThoughtPoolManaType = null; if (autoPayment && autoPaymentRestricted && !wasManaAddedBeyondStock() && manaType != unlockedManaType) { // if automatic restricted payment and there is already mana in the pool // and the needed mana type was not unlocked, nothing will be paid - return false; + if (unlockedManaType != null) { + ManaPoolItem checkItem = new ManaPoolItem(); + checkItem.add(unlockedManaType, 1); + possibleAsThoughtPoolManaType = game.getContinuousEffects().asThoughMana(manaType, checkItem, ability.getSourceId(), ability, ability.getControllerId(), game); + } + // Check if it's possible to use mana as thought for the unlocked manatype in the mana pool for this ability + if (possibleAsThoughtPoolManaType == null || possibleAsThoughtPoolManaType != unlockedManaType) { + return false; // if it's not possible return + } } if (getConditional(manaType, ability, filter, game, costToPay) > 0) { @@ -138,7 +147,7 @@ public class ManaPool implements Serializable { } } } - if (manaType != unlockedManaType && autoPayment && autoPaymentRestricted && mana.count() == mana.getStock()) { + if (possibleAsThoughtPoolManaType == null && manaType != unlockedManaType && autoPayment && autoPaymentRestricted && mana.count() == mana.getStock()) { // no mana added beyond the stock so don't auto pay this continue; }