diff --git a/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java index f32e5a1770..20e98faf09 100644 --- a/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/k/KrrikSonOfYawgmoth.java @@ -94,13 +94,7 @@ class KrrikSonOfYawgmothPhyrexianEffect extends ContinuousEffectImpl { phyrexianBlack.setBlack(true); if (controller != null && sourcePermanent != null) { - for (UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) - { - player.addPhyrexianToColors(phyrexianBlack); - } - } + controller.addPhyrexianToColors(phyrexianBlack); return true; } return false; diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/phyrexian/PhyrexianManaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/phyrexian/PhyrexianManaTest.java index 56099f7329..69e7f6d90e 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/phyrexian/PhyrexianManaTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/phyrexian/PhyrexianManaTest.java @@ -28,5 +28,97 @@ public class PhyrexianManaTest extends CardTestPlayerBase { // can be played only through life pay Assert.assertTrue(life == 20 && hand == 1 || life == 18 && hand == 0); } + + @Test + public void testKrrikOnlyUsableByController() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth"); + addCard(Zone.HAND, playerA, "Banehound"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + addCard(Zone.HAND, playerB, "Banehound"); + setChoice(playerA, "Yes"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Banehound"); + setChoice(playerB, "Yes"); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banehound"); + setStopAt(2, PhaseStep.END_TURN); + execute(); + + //PlayerA pays life but PlayerB cannot + assertLife(playerA, 18); + assertLife(playerB, 20); + assertPermanentCount(playerA, "Banehound", 1); + assertPermanentCount(playerB, "Banehound", 1); + } + + @Test + public void testKrrikTriggeredAbility() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4); + addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth"); + addCard(Zone.HAND, playerA, "Banehound"); + addCard(Zone.HAND, playerA, "Crypt Ghast"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + + setChoice(playerA, "Yes"); //yes to pay 2 life to cast Crypt Ghast + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Crypt Ghast"); //3 mana used, 2 life paid (18 life total) + setChoice(playerA, "Yes"); //yes to pay 2 life to cast Banehound + setChoice(playerA, "Yes"); //yes to Extort + setChoice(playerA, "Yes"); //yes to pay 2 life to Extort + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Banehound"); //0 mana used, 4 life paid, 1 life gained (15 life total) + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 15); + assertLife(playerB, 19); + assertPermanentCount(playerA, "Banehound", 1); + assertPermanentCount(playerA, "Crypt Ghast", 1); + } + + @Test + public void testKrrikActivatedAbility() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth"); + addCard(Zone.BATTLEFIELD, playerA, "Frozen Shade"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + + setChoice(playerA, "Yes"); //yes to pay 2 life to activate Frozen Shade's +1/+1 ability + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}: {this} gets +1/+1 until end of turn."); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 18); + assertLife(playerB, 20); + assertPowerToughness(playerA, "Frozen Shade", 1, 2); + } + + @Test + public void testKrrikTrinispherePostPay() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth"); + addCard(Zone.BATTLEFIELD, playerA, "Trinisphere"); + addCard(Zone.HAND, playerA, "Dismember"); + + addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1); + addCard(Zone.BATTLEFIELD, playerB, "Banehound"); + + setChoice(playerA, "No"); //don't pay 2 life for Dismember's Phyrexian cost + setChoice(playerA, "No"); //don't pay 2 life for Dismember's Phyrexian cost + setChoice(playerA, "Yes"); //yes to pay 2 life for Dismember's {B} cost via K'rrik + setChoice(playerA, "Yes"); //yes to pay 2 life for Dismember's {B} cost via K'rrik + + //Dismember costs {1} now + life paid. Normally this would be {3} + life paid with true Phyrexian mana and Trinisphere active. + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dismember", "Banehound"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertLife(playerA, 16); + assertLife(playerB, 20); + assertTappedCount("Swamp", true, 1); + assertGraveyardCount(playerA, "Dismember", 1); + assertGraveyardCount(playerB, "Banehound", 1); + } } diff --git a/Mage/src/main/java/mage/abilities/AbilityImpl.java b/Mage/src/main/java/mage/abilities/AbilityImpl.java index d56a18262a..5ae344cb49 100644 --- a/Mage/src/main/java/mage/abilities/AbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/AbilityImpl.java @@ -549,10 +549,6 @@ public abstract class AbilityImpl implements Ability { Iterator costIterator = manaCostsToPay.iterator(); while (costIterator.hasNext()) { ManaCost cost = costIterator.next(); - PhyrexianManaCost tempPhyrexianCost = null; - Mana mana = cost.getMana(); - - FilterMana phyrexianColors = controller.getPhyrexianColors(); if (cost instanceof PhyrexianManaCost) { PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost) cost; @@ -563,37 +559,6 @@ public abstract class AbilityImpl implements Ability { costs.add(payLifeCost); } } - /* K'rrik, Son of Yawgmoth ability check */ - else if (phyrexianColors != null) { - int phyrexianEnabledPips = mana.count(phyrexianColors); - if (phyrexianEnabledPips > 0) { - /* find which color mana is in the cost and set it in the temp Phyrexian cost */ - if (phyrexianColors.isWhite() && mana.getWhite() > 0) { - tempPhyrexianCost = new PhyrexianManaCost(ColoredManaSymbol.W); - } - else if (phyrexianColors.isBlue() && mana.getBlue() > 0) { - tempPhyrexianCost = new PhyrexianManaCost(ColoredManaSymbol.U); - } - else if (phyrexianColors.isBlack() && mana.getBlack() > 0) { - tempPhyrexianCost = new PhyrexianManaCost(ColoredManaSymbol.B); - } - else if (phyrexianColors.isRed() && mana.getRed() > 0) { - tempPhyrexianCost = new PhyrexianManaCost(ColoredManaSymbol.R); - } - else if (phyrexianColors.isGreen() && mana.getGreen() > 0) { - tempPhyrexianCost = new PhyrexianManaCost(ColoredManaSymbol.G); - } - - if (tempPhyrexianCost != null) { - PayLifeCost payLifeCost = new PayLifeCost(2); - if (payLifeCost.canPay(this, sourceId, controller.getId(), game) - && controller.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + tempPhyrexianCost.getBaseText() + '?', this, game)) { - costIterator.remove(); - costs.add(payLifeCost); - } - } - } - } } } diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java index 7cdfead1aa..a66d7a5702 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java @@ -118,6 +118,7 @@ public class ManaCostsImpl extends ArrayList implements M } Player player = game.getPlayer(controllerId); + handleKrrikPhyrexianManaCosts(controllerId, ability, game); if (!player.getManaPool().isForcedToPay()) { assignPayment(game, ability, player.getManaPool(), this); } @@ -181,8 +182,27 @@ public class ManaCostsImpl extends ArrayList implements M tempCosts.add(payLifeCost); } } + } + + tempCosts.pay(source, game, source.getSourceId(), player.getId(), false, null); + } + + private void handleKrrikPhyrexianManaCosts(UUID payingPlayerId, Ability source, Game game) { + Player player = game.getPlayer(payingPlayerId); + if (this == null || player == null) { + return; // nothing to be done without any mana costs. prevents NRE from occurring here + } + Iterator manaCostIterator = this.iterator(); + Costs tempCosts = new CostsImpl<>(); + + while (manaCostIterator.hasNext()) { + ManaCost manaCost = manaCostIterator.next(); + Mana mana = manaCost.getMana(); + PhyrexianManaCost tempPhyrexianCost = null; + FilterMana phyrexianColors = player.getPhyrexianColors(); + /* K'rrik, Son of Yawgmoth ability check */ - else if (phyrexianColors != null) { + if (phyrexianColors != null) { int phyrexianEnabledPips = mana.count(phyrexianColors); if (phyrexianEnabledPips > 0) { /* find which color mana is in the cost and set it in the temp Phyrexian cost */ @@ -205,7 +225,7 @@ public class ManaCostsImpl extends ArrayList implements M if (tempPhyrexianCost != null) { PayLifeCost payLifeCost = new PayLifeCost(2); if (payLifeCost.canPay(source, source.getSourceId(), player.getId(), game) - && player.chooseUse(Outcome.LoseLife, "Pay 2 life instead of " + tempPhyrexianCost.getBaseText() + '?', source, game)) { + && player.chooseUse(Outcome.LoseLife, "Pay 2 life (using an active ability) instead of " + tempPhyrexianCost.getBaseText() + '?', source, game)) { manaCostIterator.remove(); tempCosts.add(payLifeCost); }