mirror of
https://github.com/correl/mage.git
synced 2024-11-25 11:09:53 +00:00
K'rrik fixes, payment for triggered abilities (#6060)
* K'rrik fixes, payment for triggered abilities K'rrik's Phyrexian ability is now handled separately from actual Phyrexian mana costs. It can now be used to pay for triggered abilities like Extort. * K'rrik tests added Tests include: - only usable by 1 player - usable with activated/triggered abilities - usable as an alternative to true Phyrexian mana, getting around Trinisphere
This commit is contained in:
parent
95d749648e
commit
e437577b5a
4 changed files with 115 additions and 44 deletions
|
@ -94,13 +94,7 @@ class KrrikSonOfYawgmothPhyrexianEffect extends ContinuousEffectImpl {
|
||||||
|
|
||||||
phyrexianBlack.setBlack(true);
|
phyrexianBlack.setBlack(true);
|
||||||
if (controller != null && sourcePermanent != null) {
|
if (controller != null && sourcePermanent != null) {
|
||||||
for (UUID playerId: game.getState().getPlayersInRange(controller.getId(), game)) {
|
controller.addPhyrexianToColors(phyrexianBlack);
|
||||||
Player player = game.getPlayer(playerId);
|
|
||||||
if (player != null)
|
|
||||||
{
|
|
||||||
player.addPhyrexianToColors(phyrexianBlack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -28,5 +28,97 @@ public class PhyrexianManaTest extends CardTestPlayerBase {
|
||||||
// can be played only through life pay
|
// can be played only through life pay
|
||||||
Assert.assertTrue(life == 20 && hand == 1 || life == 18 && hand == 0);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,10 +549,6 @@ public abstract class AbilityImpl implements Ability {
|
||||||
Iterator<ManaCost> costIterator = manaCostsToPay.iterator();
|
Iterator<ManaCost> costIterator = manaCostsToPay.iterator();
|
||||||
while (costIterator.hasNext()) {
|
while (costIterator.hasNext()) {
|
||||||
ManaCost cost = costIterator.next();
|
ManaCost cost = costIterator.next();
|
||||||
PhyrexianManaCost tempPhyrexianCost = null;
|
|
||||||
Mana mana = cost.getMana();
|
|
||||||
|
|
||||||
FilterMana phyrexianColors = controller.getPhyrexianColors();
|
|
||||||
|
|
||||||
if (cost instanceof PhyrexianManaCost) {
|
if (cost instanceof PhyrexianManaCost) {
|
||||||
PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost) cost;
|
PhyrexianManaCost phyrexianManaCost = (PhyrexianManaCost) cost;
|
||||||
|
@ -563,37 +559,6 @@ public abstract class AbilityImpl implements Ability {
|
||||||
costs.add(payLifeCost);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
||||||
}
|
}
|
||||||
|
|
||||||
Player player = game.getPlayer(controllerId);
|
Player player = game.getPlayer(controllerId);
|
||||||
|
handleKrrikPhyrexianManaCosts(controllerId, ability, game);
|
||||||
if (!player.getManaPool().isForcedToPay()) {
|
if (!player.getManaPool().isForcedToPay()) {
|
||||||
assignPayment(game, ability, player.getManaPool(), this);
|
assignPayment(game, ability, player.getManaPool(), this);
|
||||||
}
|
}
|
||||||
|
@ -181,8 +182,27 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
||||||
tempCosts.add(payLifeCost);
|
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<T> manaCostIterator = this.iterator();
|
||||||
|
Costs<PayLifeCost> 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 */
|
/* K'rrik, Son of Yawgmoth ability check */
|
||||||
else if (phyrexianColors != null) {
|
if (phyrexianColors != null) {
|
||||||
int phyrexianEnabledPips = mana.count(phyrexianColors);
|
int phyrexianEnabledPips = mana.count(phyrexianColors);
|
||||||
if (phyrexianEnabledPips > 0) {
|
if (phyrexianEnabledPips > 0) {
|
||||||
/* find which color mana is in the cost and set it in the temp Phyrexian cost */
|
/* find which color mana is in the cost and set it in the temp Phyrexian cost */
|
||||||
|
@ -205,7 +225,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
|
||||||
if (tempPhyrexianCost != null) {
|
if (tempPhyrexianCost != null) {
|
||||||
PayLifeCost payLifeCost = new PayLifeCost(2);
|
PayLifeCost payLifeCost = new PayLifeCost(2);
|
||||||
if (payLifeCost.canPay(source, source.getSourceId(), player.getId(), game)
|
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();
|
manaCostIterator.remove();
|
||||||
tempCosts.add(payLifeCost);
|
tempCosts.add(payLifeCost);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue