mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
* Copy spell - improved support for some cards and abilities (#8074);
This commit is contained in:
parent
6e0184a38d
commit
530cd627cc
5 changed files with 108 additions and 50 deletions
|
@ -240,7 +240,6 @@ public class ManaWasSpentToCastTest extends CardTestPlayerBase {
|
||||||
assertPermanentCount(playerA, "Sliver Construct", 1);
|
assertPermanentCount(playerA, "Sliver Construct", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore // currently fails
|
|
||||||
@Test
|
@Test
|
||||||
public void testManaDrainCopied() {
|
public void testManaDrainCopied() {
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 11);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 11);
|
||||||
|
|
|
@ -24,13 +24,15 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Sorcery — Adventure
|
* Sorcery — Adventure
|
||||||
* Create a Food token.
|
* Create a Food token.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
assertExileCount(playerA, "Curious Pair", 1);
|
assertExileCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -61,14 +63,17 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCastCuriousPair() {
|
public void testCastCuriousPair() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 0);
|
assertPermanentCount(playerA, "Food", 0);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -78,16 +83,19 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCastTreatsToShareAndCuriousPair() {
|
public void testCastTreatsToShareAndCuriousPair() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -103,16 +111,19 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Whenever you cast a creature spell that has an Adventure, draw a card.
|
* Whenever you cast a creature spell that has an Adventure, draw a card.
|
||||||
* 1/1
|
* 1/1
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 0);
|
assertPermanentCount(playerA, "Curious Pair", 0);
|
||||||
|
@ -122,14 +133,18 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCastCuriousPairWithEdgewallInnkeeper() {
|
public void testCastCuriousPairWithEdgewallInnkeeper() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 1);
|
assertHandCount(playerA, 1);
|
||||||
assertPermanentCount(playerA, "Food", 0);
|
assertPermanentCount(playerA, "Food", 0);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -139,17 +154,20 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCastTreatsToShareAndCuriousPairWithEdgewallInnkeeper() {
|
public void testCastTreatsToShareAndCuriousPairWithEdgewallInnkeeper() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 1);
|
assertHandCount(playerA, 1);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -159,17 +177,17 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCastCuriousPairWithMysteriousPathlighter() {
|
public void testCastCuriousPairWithMysteriousPathlighter() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mysterious Pathlighter");
|
addCard(Zone.BATTLEFIELD, playerA, "Mysterious Pathlighter");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 0);
|
assertPermanentCount(playerA, "Food", 0);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -186,20 +204,22 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
|
* Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
|
||||||
* You may put a card that has an Adventure that player owns from exile into that player's graveyard.
|
* You may put a card that has an Adventure that player owns from exile into that player's graveyard.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
addCard(Zone.HAND, playerA, "Opt");
|
addCard(Zone.HAND, playerA, "Opt");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
//
|
||||||
|
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
|
||||||
addCard(Zone.HAND, playerB, "Memory Theft");
|
addCard(Zone.HAND, playerB, "Memory Theft");
|
||||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Memory Theft", playerA);
|
|
||||||
playerB.addChoice("Opt");
|
|
||||||
playerB.addChoice("Curious Pair");
|
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Memory Theft", playerA);
|
||||||
|
setChoice(playerB, "Opt");
|
||||||
|
setChoice(playerB, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
@ -216,12 +236,13 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Artifact
|
* Artifact
|
||||||
* Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy.
|
* Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Lucky Clover");
|
addCard(Zone.BATTLEFIELD, playerA, "Lucky Clover");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
@ -240,15 +261,16 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Instant
|
* Instant
|
||||||
* Copy target instant or sorcery spell, except that the copy is red. You may choose new targets for the copy.
|
* Copy target instant or sorcery spell, except that the copy is red. You may choose new targets for the copy.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
addCard(Zone.HAND, playerA, "Fork");
|
addCard(Zone.HAND, playerA, "Fork");
|
||||||
|
|
||||||
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 1);
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fork", "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fork", "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
@ -269,15 +291,16 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Instant
|
* Instant
|
||||||
* Counter target spell.
|
* Counter target spell.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
addCard(Zone.HAND, playerB, "Counterspell");
|
addCard(Zone.HAND, playerB, "Counterspell");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
@ -300,7 +323,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Target opponent reveals their hand. You choose a nonland card from that player's graveyard or hand and exile it.
|
* Target opponent reveals their hand. You choose a nonland card from that player's graveyard or hand and exile it.
|
||||||
* You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
|
* You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
|
||||||
|
@ -313,10 +335,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertHandCount(playerB, 0);
|
assertHandCount(playerB, 0);
|
||||||
assertPermanentCount(playerB, 0);
|
assertPermanentCount(playerB, 0);
|
||||||
|
@ -346,7 +369,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Target creature gets +2/+0 until end of turn.
|
* Target creature gets +2/+0 until end of turn.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Eager Cadet");
|
addCard(Zone.BATTLEFIELD, playerA, "Eager Cadet");
|
||||||
addCard(Zone.HAND, playerA, "Rimrock Knight", 2);
|
addCard(Zone.HAND, playerA, "Rimrock Knight", 2);
|
||||||
|
@ -356,10 +378,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Rimrock Knight", 2);
|
assertPermanentCount(playerA, "Rimrock Knight", 2);
|
||||||
assertPermanentCount(playerA, "Eager Cadet", 1);
|
assertPermanentCount(playerA, "Eager Cadet", 1);
|
||||||
|
@ -370,16 +393,16 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRimrockKnightPermanentText() {
|
public void testRimrockKnightPermanentText() {
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
addCard(Zone.HAND, playerA, "Rimrock Knight");
|
addCard(Zone.HAND, playerA, "Rimrock Knight");
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Rimrock Knight", 1);
|
assertPermanentCount(playerA, "Rimrock Knight", 1);
|
||||||
assertExileCount(playerA, 0);
|
assertExileCount(playerA, 0);
|
||||||
|
@ -414,7 +437,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* Whenever you cast an instant or sorcery spell from your library, copy it. You may choose new targets for the copy.
|
* Whenever you cast an instant or sorcery spell from your library, copy it. You may choose new targets for the copy.
|
||||||
* 2/4
|
* 2/4
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
|
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
removeAllCardsFromLibrary(playerA);
|
removeAllCardsFromLibrary(playerA);
|
||||||
|
@ -422,10 +444,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, 4);
|
assertPermanentCount(playerA, 4);
|
||||||
assertPermanentCount(playerA, "Food", 2);
|
assertPermanentCount(playerA, "Food", 2);
|
||||||
|
@ -465,7 +488,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* You may cast the top card of your library if it's a creature card.
|
* You may cast the top card of your library if it's a creature card.
|
||||||
* 7/7
|
* 7/7
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
|
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||||
removeAllCardsFromLibrary(playerA);
|
removeAllCardsFromLibrary(playerA);
|
||||||
|
@ -473,10 +495,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 0);
|
assertPermanentCount(playerA, "Food", 0);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 1);
|
assertPermanentCount(playerA, "Curious Pair", 1);
|
||||||
|
@ -516,7 +539,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* −7: You get an emblem with "Instant and sorcery cards in your graveyard have retrace."
|
* −7: You get an emblem with "Instant and sorcery cards in your graveyard have retrace."
|
||||||
* Loyalty: 3
|
* Loyalty: 3
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Wrenn and Six");
|
addCard(Zone.BATTLEFIELD, playerA, "Wrenn and Six");
|
||||||
addCard(Zone.GRAVEYARD, playerA, "Curious Pair");
|
addCard(Zone.GRAVEYARD, playerA, "Curious Pair");
|
||||||
|
@ -531,10 +553,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
|
||||||
setChoice(playerA, "Forest");
|
setChoice(playerA, "Forest");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
assertPermanentCount(playerA, "Curious Pair", 0);
|
assertPermanentCount(playerA, "Curious Pair", 0);
|
||||||
|
@ -555,7 +578,6 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
* −3: Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card.
|
* −3: Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card.
|
||||||
* Loyalty: 4
|
* Loyalty: 4
|
||||||
*/
|
*/
|
||||||
setStrictChooseMode(true);
|
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Time Raveler");
|
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Time Raveler");
|
||||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||||
addCard(Zone.HAND, playerA, "Curious Pair");
|
addCard(Zone.HAND, playerA, "Curious Pair");
|
||||||
|
@ -565,10 +587,11 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
||||||
// showAvailableAbilities("abils", 1, PhaseStep.BEGIN_COMBAT, playerA);
|
// showAvailableAbilities("abils", 1, PhaseStep.BEGIN_COMBAT, playerA);
|
||||||
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Treats to Share");
|
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Treats to Share");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
assertAllCommandsUsed();
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
assertHandCount(playerA, 0);
|
assertHandCount(playerA, 0);
|
||||||
assertPermanentCount(playerA, 3);
|
assertPermanentCount(playerA, 3);
|
||||||
assertPermanentCount(playerA, "Food", 1);
|
assertPermanentCount(playerA, "Food", 1);
|
||||||
|
|
|
@ -65,7 +65,6 @@ import mage.util.MessageToClient;
|
||||||
import mage.util.RandomUtil;
|
import mage.util.RandomUtil;
|
||||||
import mage.util.functions.CopyApplier;
|
import mage.util.functions.CopyApplier;
|
||||||
import mage.watchers.Watcher;
|
import mage.watchers.Watcher;
|
||||||
import mage.watchers.Watchers;
|
|
||||||
import mage.watchers.common.*;
|
import mage.watchers.common.*;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@ -2051,6 +2050,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
// to exist the next time state-based actions are checked.
|
// to exist the next time state-based actions are checked.
|
||||||
//
|
//
|
||||||
// Copied cards can be stored in GameState.copiedCards or in game state value (until LKI rework)
|
// Copied cards can be stored in GameState.copiedCards or in game state value (until LKI rework)
|
||||||
|
// Copied cards list contains all parts of split/adventure/mdfc
|
||||||
Set<Card> allCopiedCards = new HashSet<>();
|
Set<Card> allCopiedCards = new HashSet<>();
|
||||||
allCopiedCards.addAll(this.getState().getCopiedCards());
|
allCopiedCards.addAll(this.getState().getCopiedCards());
|
||||||
Map<String, Object> stateSavedCopiedCards = this.getState().getValues(GameState.COPIED_CARD_KEY);
|
Map<String, Object> stateSavedCopiedCards = this.getState().getValues(GameState.COPIED_CARD_KEY);
|
||||||
|
@ -2060,6 +2060,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
|
Set<Card> copiedCardsToRemove = new HashSet<>();
|
||||||
for (Card copiedCard : allCopiedCards) {
|
for (Card copiedCard : allCopiedCards) {
|
||||||
// 1. Zone must be checked from main card only cause mdf parts can have different zones
|
// 1. Zone must be checked from main card only cause mdf parts can have different zones
|
||||||
// (one side on battlefield, another side on outside)
|
// (one side on battlefield, another side on outside)
|
||||||
|
@ -2070,13 +2071,25 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
Zone zone = state.getZone(copiedCard.getMainCard().getId());
|
Zone zone = state.getZone(copiedCard.getMainCard().getId());
|
||||||
// TODO: remember LKI of copied cards here after LKI rework
|
// TODO: remember LKI of copied cards here after LKI rework
|
||||||
switch (zone) {
|
switch (zone) {
|
||||||
case BATTLEFIELD:
|
case OUTSIDE:
|
||||||
|
case BATTLEFIELD: {
|
||||||
|
// keep in battlefield
|
||||||
|
// keep in outside (it's a final zone for all copied cards)
|
||||||
continue;
|
continue;
|
||||||
case STACK:
|
}
|
||||||
if (getStack().getStackObject(copiedCard.getId()) != null) {
|
|
||||||
|
case STACK: {
|
||||||
|
// copied cards aren't moves and keeps in Stack zone after resolve,
|
||||||
|
// so it must be moved manually as SBA (see Outside zone change at the end)
|
||||||
|
MageObject object = getStack().getStackObject(copiedCard.getId());
|
||||||
|
if (object != null) {
|
||||||
|
// keep in stack until resolve
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case GRAVEYARD:
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GRAVEYARD: {
|
||||||
for (Player player : getPlayers().values()) {
|
for (Player player : getPlayers().values()) {
|
||||||
if (player.getGraveyard().contains(copiedCard.getId())) {
|
if (player.getGraveyard().contains(copiedCard.getId())) {
|
||||||
player.getGraveyard().remove(copiedCard);
|
player.getGraveyard().remove(copiedCard);
|
||||||
|
@ -2084,7 +2097,9 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HAND:
|
}
|
||||||
|
|
||||||
|
case HAND: {
|
||||||
for (Player player : getPlayers().values()) {
|
for (Player player : getPlayers().values()) {
|
||||||
if (player.getHand().contains(copiedCard.getId())) {
|
if (player.getHand().contains(copiedCard.getId())) {
|
||||||
player.getHand().remove(copiedCard);
|
player.getHand().remove(copiedCard);
|
||||||
|
@ -2092,7 +2107,9 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIBRARY:
|
}
|
||||||
|
|
||||||
|
case LIBRARY: {
|
||||||
for (Player player : getPlayers().values()) {
|
for (Player player : getPlayers().values()) {
|
||||||
if (player.getLibrary().getCard(copiedCard.getId(), this) != null) {
|
if (player.getLibrary().getCard(copiedCard.getId(), this) != null) {
|
||||||
player.getLibrary().remove(copiedCard.getId(), this);
|
player.getLibrary().remove(copiedCard.getId(), this);
|
||||||
|
@ -2100,15 +2117,30 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXILED:
|
}
|
||||||
|
|
||||||
|
case EXILED: {
|
||||||
getExile().removeCard(copiedCard, this);
|
getExile().removeCard(copiedCard, this);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case COMMAND:
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove copied card info
|
// copied card can be removed to Outside
|
||||||
this.getState().getCopiedCards().remove(copiedCard);
|
copiedCardsToRemove.add(copiedCard);
|
||||||
this.getState().removeValue(GameState.COPIED_CARD_KEY + copiedCard.getId().toString());
|
|
||||||
}
|
}
|
||||||
|
// real remove
|
||||||
|
copiedCardsToRemove.forEach(card -> {
|
||||||
|
card.setZone(Zone.OUTSIDE, this);
|
||||||
|
this.getState().getCopiedCards().remove(card);
|
||||||
|
// must keep card in game state as LKI alternative until LKI rework, so don't remove from it
|
||||||
|
// TODO: change after LKI rework
|
||||||
|
//this.getState().removeValue(GameState.COPIED_CARD_KEY + copiedCard.getId().toString());
|
||||||
|
});
|
||||||
|
|
||||||
List<Permanent> legendary = new ArrayList<>();
|
List<Permanent> legendary = new ArrayList<>();
|
||||||
List<Permanent> worldEnchantment = new ArrayList<>();
|
List<Permanent> worldEnchantment = new ArrayList<>();
|
||||||
|
|
|
@ -233,7 +233,10 @@ public class Spell extends StackObjectImpl implements Card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) {
|
if (game.getState().getZone(card.getMainCard().getId()) == Zone.STACK) {
|
||||||
if (!isCopy()) {
|
if (isCopy()) {
|
||||||
|
// copied spell, only remove from stack
|
||||||
|
game.getStack().remove(this, game);
|
||||||
|
} else {
|
||||||
controller.moveCards(card, Zone.GRAVEYARD, ability, game);
|
controller.moveCards(card, Zone.GRAVEYARD, ability, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,7 +441,7 @@ public class Spell extends StackObjectImpl implements Card {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Copied spell, only remove from stack
|
// copied spell, only remove from stack
|
||||||
game.getStack().remove(this, game);
|
game.getStack().remove(this, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -847,6 +850,7 @@ public class Spell extends StackObjectImpl implements Card {
|
||||||
@Override
|
@Override
|
||||||
public boolean moveToExile(UUID exileId, String name, Ability source, Game game, List<UUID> appliedEffects) {
|
public boolean moveToExile(UUID exileId, String name, Ability source, Game game, List<UUID> appliedEffects) {
|
||||||
if (this.isCopy()) {
|
if (this.isCopy()) {
|
||||||
|
// copied spell, only remove from stack
|
||||||
game.getStack().remove(this, game);
|
game.getStack().remove(this, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4472,7 +4472,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
} else if (card instanceof Spell) {
|
} else if (card instanceof Spell) {
|
||||||
final Spell spell = (Spell) card;
|
final Spell spell = (Spell) card;
|
||||||
if (spell.isCopy()) {
|
if (spell.isCopy()) {
|
||||||
// Copied spell, only remove from stack
|
// copied spell, only remove from stack
|
||||||
game.getStack().remove(spell, game);
|
game.getStack().remove(spell, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue