mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 19:41:59 -08:00
Rework AsThough handling to allow choosing/affecting a specific alternate cast (#11114)
* Rework AsThoughEffect * some cleanup of MageIdentifer * refactor ActivationStatus * fix bolas's citadel * fix a couple of the Alternative Cost being applied too broadly. * fix Risen Executioneer * allow cancellation of AsThough choice. * fix One with the Multiverse * cleanup cards needing their own MageIdentifier * last couple of fixes * apply reviews for cleaner code. * some more cleanup
This commit is contained in:
parent
ba135abc78
commit
7c454fb24c
66 changed files with 1176 additions and 395 deletions
|
|
@ -0,0 +1,81 @@
|
|||
package org.mage.test.cards.abilities.other;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Alex-Vasile, Susucr
|
||||
*/
|
||||
public class MultipleAsThoughEffects extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Reported bug: https://github.com/magefree/mage/issues/8584
|
||||
*
|
||||
* If there are multiple effects which allow a player to cast a spell,
|
||||
* they should be able to choose which one they whish to use.
|
||||
*/
|
||||
@Test
|
||||
public void ChoosingAlternateCastingMethod() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// You may cast creature spells from the top of your library.
|
||||
addCard(Zone.HAND, playerA, "Vivien, Monsters' Advocate");
|
||||
// You may play lands and cast spells from the top of your library.
|
||||
// If you cast a spell this way, pay life equal to its mana value rather than pay its mana cost.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel");
|
||||
// Random creature card to play with mana value of 3
|
||||
addCard(Zone.LIBRARY, playerA, "Abzan Beastmaster",2);
|
||||
addCard(Zone.LIBRARY, playerA, "Grizzly Bears",1); // This one is drawn.
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest",5);
|
||||
// For the "cast from the top" abilities to work, Vivien or Bolas's Citadel
|
||||
// must be played and not be in battlefield as start. Or else the top of the library will
|
||||
// not be able to be cast during the test.
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Monsters' Advocate");
|
||||
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Abzan Beastmaster",true);
|
||||
setChoice(playerA, "Vivien");
|
||||
checkLife("Vivien not making pay life", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 20);
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Abzan Beastmaster");
|
||||
setChoice(playerA, "Bolas's");
|
||||
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Abzan Beastmaster", 2);
|
||||
assertTappedCount("Forest", true, 3);
|
||||
assertLife(playerA, 20 - 3); // 3 from casting Abzan Beastmaster with Bolas Citadel
|
||||
}
|
||||
|
||||
/**
|
||||
* Reported bug: https://github.com/magefree/mage/issues/2087
|
||||
*
|
||||
* If there are multiple effects which allow a player to cast a spell,
|
||||
* they should be able to choose which one they whish to use, even if one is single-use.
|
||||
*/
|
||||
@Test
|
||||
public void RisenExecutioner() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
// You may cast Risen Executioner from your graveyard if you pay {1} more to cast it for each other creature card in your graveyard.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Risen Executioner", 2);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears", 1);
|
||||
// During each of your turns, you may cast a Zombie creature spell from your graveyard.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Gisa and Geralf");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp",9); // Only enough mana to cast
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Risen Executioner", true); // Should cost {2}{B}{B} since cast with Gisa
|
||||
setChoice(playerA, "Gisa");
|
||||
checkPermanentTapped("Swamp tapped after cast with Gisa and Geralf", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Swamp", true, 4);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Risen Executioner"); // Should cost {3}{B}{B} when cast with own ability, there is another creature in the graveyard
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Risen Executioner", 2);
|
||||
assertTappedCount("Swamp", true, 4 + 5);
|
||||
}
|
||||
}
|
||||
|
|
@ -734,6 +734,7 @@ public class AdventureCardsTest extends CardTestPlayerBase {
|
|||
checkExileCount("after exile 3", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Curious Pair", 1);
|
||||
// play as adventure spell
|
||||
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Treats to Share");
|
||||
setChoice(playerA, "Hostage Taker"); // Not sure why there is an alternative there. No issue with using either. TODO: investigate?
|
||||
waitStackResolved(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
checkPermanentCount("after play 3", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Food Token", 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -96,11 +96,12 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
|
|||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
//
|
||||
// {1}{B}: Target attacking Zombie gains indestructible until end of turn.
|
||||
addCard(Zone.LIBRARY, playerA, "Accursed Horde", 1); // Creature Zombie {3}{B}
|
||||
addCard(Zone.LIBRARY, playerA, "Carrion Screecher", 1); // Creature Zombie {3}{B}
|
||||
//
|
||||
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 5); // Creature {1}{W}
|
||||
//
|
||||
|
|
@ -119,15 +120,64 @@ public class KaradorGhostChieftainTest extends CardTestPlayerBase {
|
|||
// you play any creatures due to two approve objects
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Silvercoat Lion", true);
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Accursed Horde", true);
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Carrion Screecher", true);
|
||||
|
||||
// cast zombie creature and approves by Karagar
|
||||
// cast zombie creature and approves by Karador
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Accursed Horde");
|
||||
setChoice(playerA, "Karador, Ghost Chieftain"); // choose the permitting object
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// you can't cast lion due to approving object (Gisa needs zombie)
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Silvercoat Lion", false);
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Accursed Horde", false);
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Carrion Screecher", true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_castFromGraveyardWithDifferentApproversOtherCast() {
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
//
|
||||
// {1}{B}: Target attacking Zombie gains indestructible until end of turn.
|
||||
addCard(Zone.LIBRARY, playerA, "Accursed Horde", 1); // Creature Zombie {3}{B}
|
||||
addCard(Zone.LIBRARY, playerA, "Carrion Screecher", 1); // Creature Zombie {3}{B}
|
||||
//
|
||||
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 5); // Creature {1}{W}
|
||||
//
|
||||
// Karador, Ghost Chieftain costs {1} less to cast for each creature card in your graveyard.
|
||||
// During each of your turns, you may cast one creature card from your graveyard.
|
||||
addCard(Zone.HAND, playerA, "Karador, Ghost Chieftain");// {5}{B}{G}{W}
|
||||
//
|
||||
// When Gisa and Geralf enters the battlefield, put the top four cards of your library into your graveyard.
|
||||
// During each of your turns, you may cast a Zombie creature card from your graveyard.
|
||||
addCard(Zone.HAND, playerA, "Gisa and Geralf"); // CREATURE {2}{U}{B} (4/4)
|
||||
|
||||
// prepare spels with same AsThough effects and puts creature to graveyard
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Karador, Ghost Chieftain", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Gisa and Geralf");
|
||||
|
||||
// you play any creatures due to two approve objects
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Silvercoat Lion", true);
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Accursed Horde", true);
|
||||
checkPlayableAbility("before", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Carrion Screecher", true);
|
||||
|
||||
// cast zombie creature and approves by Gisa and Geralf
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Accursed Horde");
|
||||
setChoice(playerA, "Gisa and Geralf"); // choose the permitting object
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// you can't cast lion due to approving object (Gisa needs zombie)
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Silvercoat Lion", true);
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Accursed Horde", false);
|
||||
checkPlayableAbility("after", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Carrion Screecher", true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,370 @@
|
|||
package org.mage.test.cards.single.bro;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Susucr
|
||||
*/
|
||||
public class OneWithTheMultiverseTest extends CardTestPlayerBase {
|
||||
|
||||
/** One with the Multiverse
|
||||
* {6}{U}{U}
|
||||
* Enchantment
|
||||
*
|
||||
* You may look at the top card of your library any time.
|
||||
* You may play lands and cast spells from the top of your library.
|
||||
* Once during each of your turns, you may cast a spell from your hand or the top of your library without paying its mana cost.
|
||||
*/
|
||||
private final String owtm = "One with the Multiverse";
|
||||
private final String ogre = "Gray Ogre"; // 2/2 {2}{R}
|
||||
private final String piker = "Goblin Piker"; // 2/1 {1}{R}
|
||||
|
||||
@Test
|
||||
public void castFromTopForFree() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 8);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 1);
|
||||
assertPermanentCount(playerA, piker, 0);
|
||||
assertLibraryCount(playerA, ogre, 2);
|
||||
assertHandCount(playerA, piker, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castFromHandForFree() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 8);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 0);
|
||||
assertPermanentCount(playerA, piker, 1);
|
||||
assertLibraryCount(playerA, ogre, 3);
|
||||
assertHandCount(playerA, piker, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castFromTopForFreeThenNormalFromTop() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 2);
|
||||
assertPermanentCount(playerA, piker, 0);
|
||||
assertLibraryCount(playerA, ogre, 1);
|
||||
assertHandCount(playerA, piker, 2);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castFromTopForFreeThenNormalFromHand() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 1);
|
||||
assertPermanentCount(playerA, piker, 1);
|
||||
assertLibraryCount(playerA, ogre, 2);
|
||||
assertHandCount(playerA, piker, 1);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castFromHandForFreeThenNormalFromHand() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 0);
|
||||
assertPermanentCount(playerA, piker, 2);
|
||||
assertLibraryCount(playerA, ogre, 3);
|
||||
assertHandCount(playerA, piker, 0);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castFromHandForFreeThenNormalFromTop() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 1);
|
||||
assertPermanentCount(playerA, piker, 1);
|
||||
assertLibraryCount(playerA, ogre, 2);
|
||||
assertHandCount(playerA, piker, 1);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castNormalFromTopThenFreeFromHand() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, owtm);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 1);
|
||||
assertPermanentCount(playerA, piker, 1);
|
||||
assertLibraryCount(playerA, ogre, 2);
|
||||
assertHandCount(playerA, piker, 1);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castNormalFromTopThenFreeFromTop() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, owtm);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 2);
|
||||
assertPermanentCount(playerA, piker, 0);
|
||||
assertLibraryCount(playerA, ogre, 1);
|
||||
assertHandCount(playerA, piker, 2);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castNormalFromHandThenFreeFromHand() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, piker);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 0);
|
||||
assertPermanentCount(playerA, piker, 2);
|
||||
assertLibraryCount(playerA, ogre, 3);
|
||||
assertHandCount(playerA, piker, 0);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castNormalFromHandThenFreeFromTop() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
// The "You may look at the top card of your library any time."
|
||||
// is not set up properly if starting directly on the battlefield.
|
||||
// So we do cast it in those tests.
|
||||
addCard(Zone.HAND, playerA, owtm);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 11);
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, ogre, 3);
|
||||
addCard(Zone.HAND, playerA, piker, 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, owtm, true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, piker, true);
|
||||
setChoice(playerA, piker);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", true);
|
||||
checkPlayableAbility("can cast for free", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ogre, true);
|
||||
setChoice(playerA, "Without paying manacost");
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Gray Ogre", false);
|
||||
checkPlayableAbility("can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Goblin Piker", false);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ogre, 1);
|
||||
assertPermanentCount(playerA, piker, 1);
|
||||
assertLibraryCount(playerA, ogre, 2);
|
||||
assertHandCount(playerA, piker, 1);
|
||||
assertTappedCount("Volcanic Island", true, 8 + 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,7 @@ public class ValkiGodOfLiesTest extends CardTestPlayerBase {
|
|||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: Exile the top card of each player's library.");
|
||||
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Plains");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Ephemerate", "Grizzly Bears");
|
||||
setChoice(playerA, "Emblem Tibalt");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
|
|||
|
|
@ -3161,22 +3161,22 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs) {
|
||||
computerPlayer.setCastSourceIdWithAlternateMana(sourceId, manaCosts, costs);
|
||||
public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs, MageIdentifier identifier) {
|
||||
computerPlayer.setCastSourceIdWithAlternateMana(sourceId, manaCosts, costs, identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getCastSourceIdWithAlternateMana() {
|
||||
public Map<UUID, Set<MageIdentifier>> getCastSourceIdWithAlternateMana() {
|
||||
return computerPlayer.getCastSourceIdWithAlternateMana();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, ManaCosts<ManaCost>> getCastSourceIdManaCosts() {
|
||||
public Map<UUID, Map<MageIdentifier,ManaCosts<ManaCost>>> getCastSourceIdManaCosts() {
|
||||
return computerPlayer.getCastSourceIdManaCosts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Costs<Cost>> getCastSourceIdCosts() {
|
||||
public Map<UUID, Map<MageIdentifier,Costs<Cost>>> getCastSourceIdCosts() {
|
||||
return computerPlayer.getCastSourceIdCosts();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.mage.test.stub;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.MageIdentifier;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.*;
|
||||
|
|
@ -1270,22 +1271,22 @@ public class PlayerStub implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getCastSourceIdWithAlternateMana() {
|
||||
public Map<UUID, Set<MageIdentifier>> getCastSourceIdWithAlternateMana() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts<ManaCost> manaCosts, Costs<Cost> costs) {
|
||||
public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts<ManaCost> manaCosts, Costs<Cost> costs, MageIdentifier identifier) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Costs<Cost>> getCastSourceIdCosts() {
|
||||
public Map<UUID, Map<MageIdentifier,Costs<Cost>>> getCastSourceIdCosts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, ManaCosts<ManaCost>> getCastSourceIdManaCosts() {
|
||||
public Map<UUID, Map<MageIdentifier, ManaCosts<ManaCost>>> getCastSourceIdManaCosts() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue