Phyrexian mana now correctly a payment choice.

Per rule 601.2b, it is not determined at the pay costs step,
but at the "choice" step, long before costs are determined.

This fixes trinisphere interactions and should be consistent with the
rules.
This commit is contained in:
Nathaniel Brandes 2017-03-08 20:03:28 -08:00
parent 209e2d13c1
commit ce1f4a3bf8
47 changed files with 234 additions and 222 deletions

View file

@ -51,10 +51,10 @@ public class HideousEndTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Plains");
addCard(Zone.BATTLEFIELD, playerB, "Copper Myr");
// Target artifact or creature you control gains protection from artifacts or from the color of your choice until end of turn.
addCard(Zone.HAND, playerB, "Apostle's Blessing");
addCard(Zone.HAND, playerB, "Blessed Breath");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hideous End", "Copper Myr");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Apostle's Blessing", "Copper Myr");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Blessed Breath", "Copper Myr");
setChoice(playerB, "Black");
setStopAt(1, PhaseStep.BEGIN_COMBAT);

View file

@ -88,7 +88,7 @@ public class MimicVatTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Phyrexian Vault", 1);
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
addCard(Zone.HAND, playerA, "Phyrexian Metamorph", 1);// Creature {3}{UP}
addCard(Zone.HAND, playerA, "Phyrexian Metamorph", 1);// Creature {3}{U/P}
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);

View file

@ -44,7 +44,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
addCard(Zone.HAND, playerA, "Cloudshift");
//Flying
@ -64,7 +64,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 24);
assertLife(playerA, 22);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Cloudshift", 1);
@ -87,7 +87,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
// Flying
// When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
@ -109,7 +109,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
setStopAt(3, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerA, 18);
assertLife(playerB, 18);
assertPermanentCount(playerA, "Ponyback Brigade", 1);
@ -128,7 +128,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{U/P}
addCard(Zone.BATTLEFIELD, playerB, "Alloy Myr", 1);
addCard(Zone.BATTLEFIELD, playerB, "Kitesail", 1);

View file

@ -57,7 +57,7 @@ public class CostModificationTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
// Look at target player's hand.
// Draw a card.
addCard(Zone.HAND, playerB, "Gitaxian Probe"); // Sorcery {UP}
addCard(Zone.HAND, playerB, "Gitaxian Probe"); // Sorcery {U/P}
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Gitaxian Probe", playerA);
setStopAt(2, PhaseStep.BEGIN_COMBAT);

View file

@ -1,111 +0,0 @@
package org.mage.test.cards.single;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Created by goesta on 12/02/2017. Modified by jeffwadsworth
*/
public class SpellskiteTest extends CardTestPlayerBase {
@Test
public void testThatSpellSkiteCantBeTargetedTwiceOrMore() {
/* According to rules, the same object can be a legal target only
once for each instances of the word target in the text
of a spell or ability. In this case, the target can't be changed
due to Spellskite already being a target.
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
addTarget(playerA, "Scute Mob");
setChoice(playerA, "X=1");
addTarget(playerA, "Spellskite");
setChoice(playerA, "X=4");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 2);
}
public void testThatSplitDamageCanGetRedirected() {
/* Standard redirect test
The Spellskite should die from the 5 damage that was redirected to it
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob"); // 1/1 creauture
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
addTarget(playerA, "Scute Mob");
setChoice(playerA, "X=5");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 1);
assertPermanentCount(playerB, "Scute Mob", 1);
}
public void testThatSplitDamageGetsRedirectedFromTheCorrectChoice() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
addCard(Zone.BATTLEFIELD, playerB, "Memnite"); // 1/1 creauture
addCard(Zone.BATTLEFIELD, playerB, "Royal Assassin");
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit");
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
addTarget(playerA, "Memnite");
setChoice(playerA, "X=1");
addTarget(playerA, "Royal Assassin");
setChoice(playerA, "X=1");
addTarget(playerA, "Blinking Spirit");
setChoice(playerA, "X=1");
addTarget(playerA, "Pearled Unicorn");
setChoice(playerA, "X=2");//the unicorn deserves it
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "No");
setChoice(playerA, "No");
setChoice(playerA, "No");
setChoice(playerA, "Yes"); //of course
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 3);
assertPermanentCount(playerB, "Pearled Unicorn", 1);//it lives on
assertPowerToughness(playerB, "Spellskite", 0, 2);
}
}

View file

@ -52,13 +52,13 @@ public class BecomesTheTargetTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{WP},{T}: Tap target creature", "Silvercoat Lion");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{W/P},{T}: Tap target creature", "Silvercoat Lion");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertLife(playerB, 18);
assertPermanentCount(playerA, "Silvercoat Lion", 0);
assertTapped("Silvercoat Lion", true);

View file

@ -157,7 +157,7 @@ public class SacredGroundTest extends CardTestPlayerBase {
// Choose target card in a graveyard other than a basic land card. Search its owner's graveyard,
// hand, and library for any number of cards with the same name as that card and exile them.
// Then that player shuffles his or her library.
addCard(Zone.HAND, playerA, "Surgical Extraction"); // Instant {BP}
addCard(Zone.HAND, playerA, "Surgical Extraction"); // Instant {B/P}
addCard(Zone.BATTLEFIELD, playerB, "Caves of Koilos", 1);
/**
@ -177,7 +177,7 @@ public class SacredGroundTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Surgical Extraction", 1);
assertExileCount("Caves of Koilos", 1);
assertLife(playerA, 20);
assertLife(playerA, 18);
assertLife(playerB, 18);
}

View file

@ -52,7 +52,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{UP}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U/P}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -60,7 +60,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 1);
assertPermanentCount(playerA, "Spellskite", 1);
assertLife(playerA, 20);
assertLife(playerA, 18);
assertLife(playerB, 20);
assertPowerToughness(playerA, "Spellskite", 3, 7);
@ -90,7 +90,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Vedalken Shackles", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 6);
// {UP}: Change a target of target spell or ability to Spellskite.
// {U/P}: Change a target of target spell or ability to Spellskite.
addCard(Zone.BATTLEFIELD, playerB, "Spellskite", 1);
// {4}{U}{U}
// Whenever Frost Titan becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays 2.
@ -102,7 +102,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Frost Titan");
addTarget(playerB, "Silvercoat Lion");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{UP}: Change a target", "stack ability (Whenever {this} enters ");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "{U/P}: Change a target", "stack ability (Whenever {this} enters ");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
@ -141,7 +141,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
setModeChoice(playerA, "1"); // Counter target spell
setModeChoice(playerA, "2"); // return target permanent to its owner's hand
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Cryptic Command", "Cryptic Command");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Cryptic Command", "Cryptic Command");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -154,7 +154,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertLife(playerA, 20);
assertLife(playerB, 20);
assertLife(playerB, 18);
}
@ -182,7 +182,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
setModeChoice(playerA, "2"); // return target permanent to its owner's hand
setModeChoice(playerA, "3"); // tap all creatures your opponents control
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Cryptic Command");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Cryptic Command");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
@ -194,7 +194,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertTapped("Silvercoat Lion", true);
assertLife(playerA, 20);
assertLife(playerB, 20);
assertLife(playerB, 18);
}
@ -214,7 +214,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target of target spell or ability to {this}.", "Lightning Bolt");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -222,7 +222,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Lightning Bolt", 1);
assertLife(playerA, 20);
assertLife(playerB, 20);
assertLife(playerB, 18);
}
@ -250,4 +250,102 @@ public class SpellskiteTest extends CardTestPlayerBase {
assertPowerToughness(playerB, "Spellskite", 3, 7);
}
@Test
public void testThatSpellSkiteCantBeTargetedTwiceOrMore() {
/* According to rules, the same object can be a legal target only
once for each instances of the word target in the text
of a spell or ability. In this case, the target can't be changed
due to Spellskite already being a target.
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
addTarget(playerA, "Scute Mob");
setChoice(playerA, "X=1");
addTarget(playerA, "Spellskite");
setChoice(playerA, "X=4");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 2);
}
public void testThatSplitDamageCanGetRedirected() {
/* Standard redirect test
The Spellskite should die from the 5 damage that was redirected to it
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
addCard(Zone.BATTLEFIELD, playerB, "Scute Mob"); // 1/1 creauture
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
addTarget(playerA, "Scute Mob");
setChoice(playerA, "X=5");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 1);
assertPermanentCount(playerB, "Scute Mob", 1);
}
public void testThatSplitDamageGetsRedirectedFromTheCorrectChoice() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerB, "Spellskite");// 0/4 creature
addCard(Zone.BATTLEFIELD, playerB, "Memnite"); // 1/1 creauture
addCard(Zone.BATTLEFIELD, playerB, "Royal Assassin");
addCard(Zone.BATTLEFIELD, playerB, "Blinking Spirit");
addCard(Zone.BATTLEFIELD, playerB, "Pearled Unicorn");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
addTarget(playerA, "Memnite");
setChoice(playerA, "X=1");
addTarget(playerA, "Royal Assassin");
setChoice(playerA, "X=1");
addTarget(playerA, "Blinking Spirit");
setChoice(playerA, "X=1");
addTarget(playerA, "Pearled Unicorn");
setChoice(playerA, "X=2");//the unicorn deserves it
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{UP}: Change a target of target spell or ability to {this}.", "Fiery Justice", "Fiery Justice");
setChoice(playerA, "No");
setChoice(playerA, "No");
setChoice(playerA, "No");
setChoice(playerA, "Yes"); //of course
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, 3);
assertPermanentCount(playerB, "Pearled Unicorn", 1);//it lives on
assertPowerToughness(playerB, "Spellskite", 0, 2);
}
}

View file

@ -18,7 +18,7 @@ public class PostMortemLungeTest extends CardTestPlayerBase {
public void testExilesCreatureAtEndStep() {
/*
{P}{X} - Sorcery
{X}{B/P} - Sorcery
Return target creature card with converted mana cost X from your graveyard to the battlefield.
It gains haste. Exile it at the beginning of the next end step.
*/

View file

@ -43,7 +43,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
/**
* Test if a Thragtusk is copied by a PhyrexianMetamorph that both triggers
* cotrrect work
* correct work
*/
@Test
public void testPhyrexianMetamorph() {
@ -69,7 +69,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Phyrexian Metamorph", 1);
assertGraveyardCount(playerB, "Public Execution", 1);
assertLife(playerA, 25);
assertLife(playerA, 23);
assertLife(playerB, 20); // Thragtusk ETB ability does not trigger if set to battlefield on test game start
assertPermanentCount(playerA, "Beast", 1);
@ -116,7 +116,7 @@ public class ThragtuskTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, "Phyrexian Metamorph", 1);
assertGraveyardCount(playerB, "Public Execution", 1);
assertLife(playerA, 25);
assertLife(playerA, 23);
assertLife(playerB, 20); // Thragtusk ETB ability does not trigger if set to battlefield on test game start
assertPermanentCount(playerA, "Beast", 0);