mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 11:32:00 -08:00
[NCC] Implement several cards (#9328)
Many associated refactors too. See full PR for detail.
This commit is contained in:
parent
b7151cfa58
commit
fd16f2a16b
104 changed files with 6091 additions and 1069 deletions
|
|
@ -0,0 +1,110 @@
|
|||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class CasualtyTest extends CardTestPlayerBase {
|
||||
|
||||
// Instant
|
||||
// {1}{U}
|
||||
// Casualty 1
|
||||
// Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
private static final String aLittleChat = "A Little Chat";
|
||||
// Planeswalker
|
||||
// {1}{B}{R}
|
||||
// Casualty X
|
||||
// The copy isn’t legendary and has starting loyalty X.
|
||||
// −7: Target player draws seven cards and loses 7 life.
|
||||
private static final String obNixilisTheAdversary = "Ob Nixilis, the Adversary";
|
||||
// 7/7 used as casualty
|
||||
private static final String aetherwindBasker = "Aetherwind Basker";
|
||||
|
||||
/**
|
||||
* Test Casualty on sorcery/instant.
|
||||
*/
|
||||
@Test
|
||||
public void testCasualtySorceryInstant() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.HAND, playerA, aLittleChat);
|
||||
addCard(Zone.LIBRARY, playerA, "Desert", 4);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aLittleChat);
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
addTarget(playerA, "Desert");
|
||||
addTarget(playerA, "Desert");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertHandCount(playerA, "Desert", 2);
|
||||
assertGraveyardCount(playerA, aetherwindBasker, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that casualty will only let you pay it once.
|
||||
*/
|
||||
@Test
|
||||
public void testCanOnlyPayCasualtyOnce() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.HAND, playerA, aLittleChat);
|
||||
addCard(Zone.LIBRARY, playerA, "Desert", 4);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aLittleChat);
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
// If a second target was possible, it would have prompted us for another and this test would fail when strict choose mode was on
|
||||
addTarget(playerA, "Desert");
|
||||
addTarget(playerA, "Desert");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, "Desert", 2);
|
||||
assertGraveyardCount(playerA, aetherwindBasker, 1);
|
||||
assertPermanentCount(playerA, aetherwindBasker, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Casualty on a creature.
|
||||
* Test variable casualty.
|
||||
*/
|
||||
@Test
|
||||
public void testVariableCasualtyOnCreature() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.HAND, playerA, obNixilisTheAdversary);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, obNixilisTheAdversary);
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertGraveyardCount(playerA, aetherwindBasker, 1);
|
||||
assertPermanentCount(playerA, obNixilisTheAdversary, 2); // 2 were created, but the token died when using its -7 ability
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "-7:"); // -7 life and draw 7 cards
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, obNixilisTheAdversary, 1);
|
||||
assertLife(playerA, 20 - 7);
|
||||
assertHandCount(playerA, 7);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package org.mage.test.cards.abilities.oneshot;
|
||||
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class PutCardFromOneOfTwoZonesOntoBattlefieldEffectTest extends CardTestPlayerBase {
|
||||
|
||||
// −5: You may put a creature card with mana value less than or equal to the number of lands you control onto the battlefield from your hand or graveyard with two +1/+1 counters on it.
|
||||
private static final String nissa = "Nissa of Shadowed Boughs";
|
||||
|
||||
// {4}{B}{R}
|
||||
// When Swift Warkite enters the battlefield, you may put a creature card with mana value 3 or less from your hand or graveyard onto the battlefield.
|
||||
// That creature gains haste.
|
||||
// Return it to your hand at the beginning of the next end step.
|
||||
private static final String swift = "Swift Warkite";
|
||||
|
||||
// Simple 1/1 for Swift Warkite to put on the battlefield with its ETB
|
||||
private static final String sliver = "Metallic Sliver";
|
||||
|
||||
// −2: You may put an Equipment card from your hand or graveyard onto the battlefield.
|
||||
private static final String nahiri = "Nahiri, the Lithomancer";
|
||||
|
||||
// Equipment cards for Nahiri
|
||||
private static final String vorpal = "Vorpal Sword";
|
||||
private static final String axe = "Bloodforged Battle-Axe";
|
||||
|
||||
/**
|
||||
* Test with no matching cards in hand or graveyard.
|
||||
*/
|
||||
@Test
|
||||
public void testNoMatches() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2");
|
||||
// The player should not be prompted for a choice
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with matching cards only in graveyard.
|
||||
*/
|
||||
@Test
|
||||
public void testOnlyGraveyardHasMatches() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
addCard(Zone.GRAVEYARD, playerA, vorpal);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2");
|
||||
setChoice(playerA, vorpal);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, vorpal, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with matching cards only in hand.
|
||||
*/
|
||||
@Test
|
||||
public void testOnlyHandHasMatches() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
addCard(Zone.HAND, playerA, vorpal);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2");
|
||||
setChoice(playerA, vorpal);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, vorpal, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test with matching cards in both hand and graveyard.
|
||||
*/
|
||||
@Test
|
||||
public void testBothHandAndGraveyardHaveMatches() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
addCard(Zone.HAND, playerA, vorpal);
|
||||
addCard(Zone.GRAVEYARD, playerA, axe);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2");
|
||||
setChoice(playerA, "Yes"); // For player this choice is "Hand" but tests require "Yes"
|
||||
setChoice(playerA, vorpal);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, vorpal, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link mage.cards.n.NissaOfShadowedBoughs Nissa of Shadowed Boughs}
|
||||
* Starting loyalty = 4
|
||||
* You may put a creature card with mana value less than or equal to the number of lands you control
|
||||
* onto the battlefield from your hand or graveyard
|
||||
* with two +1/+1 counters on it.
|
||||
*/
|
||||
@Test
|
||||
public void testNissaCanPlay() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nissa);
|
||||
addCard(Zone.HAND, playerA, swift); // {4}{B}{R}
|
||||
addCard(Zone.HAND, playerA, "Mountain", 5);
|
||||
addCard(Zone.HAND, playerA, "Mountain");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "-5");
|
||||
setChoice(playerA, swift);
|
||||
setChoice(playerA, "Yes"); // Say yes to Swift Warkite's ETB (no further choice needed since there are no possible options
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, nissa, 1);
|
||||
assertPermanentCount(playerA, swift, 1);
|
||||
assertCounterCount(swift, CounterType.P1P1, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link mage.cards.n.NissaOfShadowedBoughs Nissa of Shadowed Boughs}
|
||||
* Starting loyalty = 4
|
||||
* You may put a creature card with mana value less than or equal to the number of lands you control
|
||||
* onto the battlefield from your hand or graveyard
|
||||
* with two +1/+1 counters on it.
|
||||
*/
|
||||
@Test
|
||||
public void testNissaCantPlay() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nissa);
|
||||
addCard(Zone.HAND, playerA, swift); // {4}{B}{R}
|
||||
addCard(Zone.HAND, playerA, "Mountain");
|
||||
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "-5");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, nissa, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@link mage.cards.s.SwiftWarkite Swift Warkite}
|
||||
* When Swift Warkite enters the battlefield, you may put a creature card with converted mana cost 3 or less from your hand or graveyard onto the battlefield.
|
||||
* That creature gains haste.
|
||||
* Return it to your hand at the beginning of the next end step.
|
||||
*/
|
||||
@Test
|
||||
public void testSwiftWarkite() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
|
||||
addCard(Zone.HAND, playerA, swift);
|
||||
addCard(Zone.HAND, playerA, sliver);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, swift);
|
||||
setChoice(playerA, "Yes"); // Yes to activating Swift Warkite's ETB
|
||||
setChoice(playerA, sliver); // Pick the sliver for the ETB
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, sliver, 1);
|
||||
assertAbility(playerA, sliver, HasteAbility.getInstance(), true);
|
||||
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, sliver, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package org.mage.test.cards.single.gpt;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.d.DjinnIlluminatus Djinn Illuminatus}
|
||||
* <p>
|
||||
* Each instant and sorcery spell you cast has replicate.
|
||||
* The replicate cost is equal to its mana cost.
|
||||
* (When you cast it, copy it for each time you paid its replicate cost. You may choose new targets for the copies.)
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class DjinnIlluminatusTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String djinnIlluminatus = "Djinn Illuminatus";
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
private static final String mountain = "Mountain";
|
||||
|
||||
/**
|
||||
* Test that it works for you spells on your turn.
|
||||
*/
|
||||
@Test
|
||||
public void testYourSpellYourTurn() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, djinnIlluminatus);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain, 2);
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
setChoice(playerA, "Yes"); // Replicate
|
||||
setChoice(playerA, "No"); // Only replicate once
|
||||
setChoice(playerA, "No"); // Don't change the target
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertLife(playerB, 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it works for your spell on other's turn.
|
||||
*/
|
||||
@Test
|
||||
public void testYourSpellNotYourTurn() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, djinnIlluminatus);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain, 2);
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
setChoice(playerA, "Yes"); // Replicate
|
||||
setChoice(playerA, "No"); // Only replicate once
|
||||
setChoice(playerA, "No"); // Don't change the target
|
||||
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertLife(playerB, 14);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not copy other's spell.
|
||||
*/
|
||||
@Test
|
||||
public void testOthersSpell() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, djinnIlluminatus);
|
||||
addCard(Zone.BATTLEFIELD, playerB, mountain, 2);
|
||||
addCard(Zone.HAND, playerB, lightningBolt);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, lightningBolt, playerA);
|
||||
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertLife(playerA, 17);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.a.AnheloThePainter Anhelo, the Painter}
|
||||
* The first instant or sorcery spell you cast each turn has casualty 2.
|
||||
* (As you cast that spell, you may sacrifice a creature with power 2 or greater.
|
||||
* When you do, copy the spell and you may choose new targets for the copy.)
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class AnheloTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String anhelo = "Anhelo, the Painter"; // {U}{B}{R}
|
||||
private static final String lightningBolt = "Lightning Bolt"; // {R}
|
||||
private static final String solRing = "Sol Ring"; // {1}
|
||||
private static final String mountain = "Mountain";
|
||||
// MDFC Creature—Instant
|
||||
private static final String flamescrollCelebrant = "Flamescroll Celebrant"; // {1}{R}
|
||||
private static final String revelInSilence = "Revel in Silence"; // {W}{W}
|
||||
// 7/7 used as casualty
|
||||
private static final String aetherwindBasker = "Aetherwind Basker";
|
||||
// Instant
|
||||
// {1}{U}
|
||||
// Casualty 1
|
||||
// Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
private static final String aLittleChat = "A Little Chat";
|
||||
|
||||
/**
|
||||
* Test that it works for sorcery, but only the first one.
|
||||
*/
|
||||
@Test
|
||||
public void testWorksForFirstOnly() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker, 2);
|
||||
addCard(Zone.HAND, playerA, lightningBolt, 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
setChoice(playerA, "Yes"); // Cast with Casualty
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
setChoice(playerA, "No"); // Don't change targets
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerB, 20 - 2*3 - 3);
|
||||
assertPermanentCount(playerA, aetherwindBasker, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not trigger for non-sorcery/instant.
|
||||
*/
|
||||
@Test
|
||||
public void testNonSorceryOrInstant() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker);
|
||||
addCard(Zone.HAND, playerA, solRing);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, solRing);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, solRing, 1);
|
||||
assertPermanentCount(playerA, aetherwindBasker, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the instant side of an MDFC gains casualty
|
||||
*/
|
||||
@Test
|
||||
public void testInstantSideMDFC() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker);
|
||||
addCard(Zone.HAND, playerA, flamescrollCelebrant);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, revelInSilence);
|
||||
setChoice(playerA, "Yes"); // Cast with Casualty
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
// Spell has no targets, so not prompted to change them
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, aetherwindBasker, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the non-instant side of an MDFC (one which has an instant on the other side) does NOT gain casualty.
|
||||
*/
|
||||
@Test
|
||||
public void testNonInstantSideMDFC() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker);
|
||||
addCard(Zone.HAND, playerA, flamescrollCelebrant);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, flamescrollCelebrant);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, aetherwindBasker, 1);
|
||||
assertPermanentCount(playerA, flamescrollCelebrant, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it works for one you cast on someone else's turn.
|
||||
*/
|
||||
@Test
|
||||
public void testOnNotOwnTurn() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mountain, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker, 2);
|
||||
addCard(Zone.HAND, playerA, lightningBolt, 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
setChoice(playerA, "Yes"); // Cast with Casualty
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
setChoice(playerA, "No"); // Don't change targets
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerB, 20 - 2*3 - 3);
|
||||
assertPermanentCount(playerA, aetherwindBasker, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a card which already has Casualty will gain a second instance of Casualty and thus let you sacrifice twice in order to get 2 copies.
|
||||
*/
|
||||
@Test
|
||||
public void testGainsSecondCasualty() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aetherwindBasker, 2);
|
||||
addCard(Zone.HAND, playerA, aLittleChat);
|
||||
addCard(Zone.LIBRARY, playerA, "Desert", 6);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aLittleChat);
|
||||
setChoice(playerA, "Yes"); // First instance of casualty
|
||||
setChoice(playerA, "Yes"); // Second instance of casualty
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
setChoice(playerA, aetherwindBasker);
|
||||
setChoice(playerA, "When you do"); // Chose which of the two copies to put on the stack first
|
||||
addTarget(playerA, "Desert");
|
||||
addTarget(playerA, "Desert");
|
||||
addTarget(playerA, "Desert");
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertHandCount(playerA, 3);
|
||||
assertPermanentCount(playerA, aetherwindBasker, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not work for opponents on your turn or on their.
|
||||
*/
|
||||
@Test
|
||||
public void testOpponentCasts() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, anhelo);
|
||||
addCard(Zone.BATTLEFIELD, playerB, mountain, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, aetherwindBasker, 2);
|
||||
addCard(Zone.HAND, playerB, lightningBolt, 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, lightningBolt, playerA);
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, lightningBolt, playerA);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerA, 20 - 3 - 3);
|
||||
assertPermanentCount(playerB, aetherwindBasker, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.b.BessSoulNourisher Bess, Soul Nourisher}
|
||||
* <p>
|
||||
* Whenever one or more other creatures with base power and toughness 1/1 enter the battlefield under your control,
|
||||
* put a +1/+1 counter on Bess, Soul Nourisher.
|
||||
* <p>
|
||||
* Whenever Bess attacks, each other creature you control with base power and toughness 1/1 gets +X/+X until end of turn,
|
||||
* where X is the number of +1/+1 counters on Bess.
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class BessSoulNourisherTest extends CardTestPlayerBase {
|
||||
|
||||
// {1}{G}{W}
|
||||
private static final String bessSoulNourisher = "Bess, Soul Nourisher";
|
||||
// {3}{W}
|
||||
// Create three 1/1 white Soldier creature tokens.
|
||||
private static final String captainsCall = "Captain's Call";
|
||||
|
||||
/**
|
||||
* Test that it only triggers once for a group entering
|
||||
*/
|
||||
@Test
|
||||
public void testEntersGroup() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, bessSoulNourisher);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
addCard(Zone.HAND, playerA, captainsCall);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, captainsCall);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, "Soldier Token", 3);
|
||||
assertCounterCount(playerA, bessSoulNourisher, CounterType.P1P1, 1); // Should only get one +1/+1 since all soldiers tokens enter at once
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the boosting corectly affects only creatures with BASE power and toughness of 1/1.
|
||||
* Vodalian is a 1/1 so it should be buffed
|
||||
* Artic merfolk is a 1/1 buffed to a 2/2, but it still has BASE PT of 1/1, so it should be buffed.
|
||||
* Banewhip Punisher base 2/2 with a -1/-1 counter on it, so a 1/1, but its BASE is still 2/2, so it should not be buffed.
|
||||
*/
|
||||
@Test
|
||||
public void testBoost() {
|
||||
// 1/1
|
||||
// Other Merfolk you control get +1/+1.
|
||||
String vodalianHexcatcher = "Vodalian Hexcatcher";
|
||||
// 1/1
|
||||
String arcticMerfolk = "Arctic Merfolk";
|
||||
// 2/2
|
||||
// When Banewhip Punisher enters the battlefield, you may put a -1/-1 counter on target creature.
|
||||
String banewhipPunisher = "Banewhip Punisher";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bessSoulNourisher);
|
||||
addCard(Zone.BATTLEFIELD, playerA, arcticMerfolk);
|
||||
addCard(Zone.HAND, playerA, banewhipPunisher);
|
||||
addCard(Zone.HAND, playerA, vodalianHexcatcher);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, banewhipPunisher, true);
|
||||
setChoice(playerA, "Yes");
|
||||
addTarget(playerA, banewhipPunisher);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, vodalianHexcatcher);
|
||||
|
||||
attack(1, playerA, bessSoulNourisher);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertCounterCount(bessSoulNourisher, CounterType.P1P1, 1);
|
||||
assertLife(playerB, 20 - 2);
|
||||
assertPowerToughness(playerA, vodalianHexcatcher, 2, 2); // 1/1 + 1/1 from Bess
|
||||
assertPowerToughness(playerA, arcticMerfolk, 3, 3); // 1/1 + (1/1 from Bess) + (1/1 Vodalian)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.m.MariTheKillingQuill Mari, the Killing Quill} {1}{B}{B}
|
||||
* <p>
|
||||
* Whenever a creature an opponent controls dies, exile it with a hit counter on it.
|
||||
* <p>
|
||||
* Assassins, Mercenaries, and Rogues you control have deathtouch and
|
||||
* "Whenever this creature deals combat damage to a player, you may remove a hit counter from a card that player owns in exile.
|
||||
* If you do, draw a card and create two Treasure tokens."
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class MariTheKillingQuillTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String mari = "Mari, the Killing Quill";
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
// Sliver with no ability 1/1
|
||||
private static final String sliver = "Metallic Sliver";
|
||||
// Changeling 1/1
|
||||
private static final String automation = "Universal Automaton";
|
||||
|
||||
/**
|
||||
* Test that an opponent's creature will get exiled with a hit counter.
|
||||
* And that one of ours does not.
|
||||
*/
|
||||
@Test
|
||||
public void testExiledWithCounter() {
|
||||
addCard(Zone.HAND, playerA, lightningBolt, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mari);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, automation);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, sliver);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, sliver);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, automation);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, 0);
|
||||
assertGraveyardCount(playerA, automation, 1);
|
||||
|
||||
assertExileCount(playerB, sliver, 1);
|
||||
assertCounterOnExiledCardCount(sliver, CounterType.HIT, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an opponent's creature will get exiled with a hit counter.
|
||||
* And that one of ours does not.
|
||||
*/
|
||||
@Test
|
||||
public void testDrawAndTreasure() {
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
addCard(Zone.BATTLEFIELD, playerA, mari);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, automation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, sliver);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, sliver);
|
||||
attack(1, playerA, automation, playerB);
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, sliver);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 1);
|
||||
assertPermanentCount(playerA, "Treasure Token", 2);
|
||||
|
||||
assertExileCount(playerB, sliver, 1);
|
||||
assertCounterOnExiledCardCount(sliver, CounterType.HIT, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.r.ResourcefulDefense Resourceful Defense} {2}{W}
|
||||
* <p>
|
||||
* Whenever a permanent you control leaves the battlefield, if it had counters on it,
|
||||
* put those counters on target permanent you control.
|
||||
* <p>
|
||||
* {4}{W}: Move any number of counters from target permanent you control to another target permanent you control.
|
||||
*
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class ResourcefulDefenseTest extends CardTestPlayerBase {
|
||||
private static final String resourcefulDefense = "Resourceful Defense";
|
||||
// Vivid Creek enters the battlefield tapped with two charge counters on it.
|
||||
private static final String vividCreek = "Vivid Creek";
|
||||
private static final String everflowingChalice = "Everflowing Chalice";
|
||||
// Steelbane Hydra enters the battlefield with X +1/+1 counters on it.
|
||||
private static final String steelbaneHydra = "Steelbane Hydra"; // {X}{G}{G}
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
|
||||
/**
|
||||
* Move counters from a creature that died.
|
||||
*/
|
||||
@Test
|
||||
public void testMoveWhenDied() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archway Commons", 9);
|
||||
addCard(Zone.BATTLEFIELD, playerA, resourcefulDefense);
|
||||
addCard(Zone.BATTLEFIELD, playerA, everflowingChalice);
|
||||
addCard(Zone.HAND, playerA, steelbaneHydra);
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, steelbaneHydra);
|
||||
setChoice(playerA, "X=1");
|
||||
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, lightningBolt, steelbaneHydra);
|
||||
addTarget(playerA, everflowingChalice);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertCounterCount(everflowingChalice, CounterType.P1P1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move all of one counter from one permanent to another when the source only has one coutner type.
|
||||
*/
|
||||
@Test
|
||||
public void testMoveAllSingleCounters() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archway Commons", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, resourcefulDefense);
|
||||
addCard(Zone.BATTLEFIELD, playerA, vividCreek);
|
||||
addCard(Zone.BATTLEFIELD, playerA, everflowingChalice);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, vividCreek);
|
||||
addTarget(playerA, everflowingChalice);
|
||||
setChoiceAmount(playerA, 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertCounterCount(vividCreek, CounterType.CHARGE, 0);
|
||||
assertCounterCount(everflowingChalice, CounterType.CHARGE, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move some of one counter from one permanent to another when the source only has one coutner type.
|
||||
*/
|
||||
@Test
|
||||
public void testSomeAllSingleCounters() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archway Commons", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, resourcefulDefense);
|
||||
addCard(Zone.BATTLEFIELD, playerA, vividCreek);
|
||||
addCard(Zone.BATTLEFIELD, playerA, everflowingChalice);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, vividCreek);
|
||||
addTarget(playerA, everflowingChalice);
|
||||
setChoiceAmount(playerA, 1);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertCounterCount(vividCreek, CounterType.CHARGE, 1);
|
||||
assertCounterCount(everflowingChalice, CounterType.CHARGE, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move multiple counter types from one permanent to another.
|
||||
*
|
||||
* Also tests that when a creature without counters dies that you won't be prompted.
|
||||
* The hydra has no counters after the second activation and will die because toughtness==0, but we aren't prompted
|
||||
* for targets when it dies.
|
||||
*/
|
||||
@Test
|
||||
public void testMoveAllMultipleCounters() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archway Commons", 8);
|
||||
addCard(Zone.BATTLEFIELD, playerA, resourcefulDefense);
|
||||
addCard(Zone.BATTLEFIELD, playerA, vividCreek);
|
||||
addCard(Zone.HAND, playerA, steelbaneHydra);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, steelbaneHydra);
|
||||
setChoice(playerA, "X=1");
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, vividCreek);
|
||||
addTarget(playerA, steelbaneHydra);
|
||||
setChoiceAmount(playerA, 2);
|
||||
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, steelbaneHydra);
|
||||
addTarget(playerA, vividCreek);
|
||||
setChoiceAmount(playerA, 2);
|
||||
setChoiceAmount(playerA, 1);
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertCounterCount(vividCreek, CounterType.CHARGE, 2);
|
||||
assertCounterCount(vividCreek, CounterType.P1P1, 1);
|
||||
assertGraveyardCount(playerA, steelbaneHydra, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move multiple counter types from a creature that died.
|
||||
*/
|
||||
@Test
|
||||
public void testMoveMultipleWhenDied() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Archway Commons", 9);
|
||||
addCard(Zone.BATTLEFIELD, playerA, resourcefulDefense);
|
||||
addCard(Zone.BATTLEFIELD, playerA, everflowingChalice);
|
||||
addCard(Zone.BATTLEFIELD, playerA, vividCreek);
|
||||
addCard(Zone.HAND, playerA, steelbaneHydra);
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, steelbaneHydra);
|
||||
setChoice(playerA, "X=1");
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, vividCreek);
|
||||
addTarget(playerA, steelbaneHydra);
|
||||
setChoiceAmount(playerA, 2);
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, steelbaneHydra);
|
||||
addTarget(playerA, everflowingChalice);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertCounterCount(vividCreek, CounterType.CHARGE, 0);
|
||||
assertCounterCount(everflowingChalice, CounterType.CHARGE, 2);
|
||||
assertCounterCount(everflowingChalice, CounterType.P1P1, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.s.ShieldBroker Shield Broker}
|
||||
* {3}{U}{U}
|
||||
* Creature — Cephalid Advisor
|
||||
* When Shield Broker enters the battlefield, put a shield counter on target noncommander creature you don’t control.
|
||||
* You gain control of that creature for as long as it has a shield counter on it.
|
||||
* (If it would be dealt damage or destroyed, remove a shield counter from it instead.)
|
||||
*/
|
||||
public class ShieldBrokerTest extends CardTestCommander4Players {
|
||||
|
||||
private static final String shieldBroker = "Shield Broker";
|
||||
private static final String rograkh = "Rograkh, Son of Rohgahh";
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
|
||||
/**
|
||||
* Test that it works for non-commander creature.
|
||||
*/
|
||||
@Test
|
||||
public void testNonCommander() {
|
||||
addCard(Zone.BATTLEFIELD, playerD, rograkh); // {0}
|
||||
|
||||
addCard(Zone.HAND, playerA, shieldBroker); // {3}{U}{U}
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, shieldBroker);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(rograkh, CounterType.SHIELD, 1);
|
||||
assertPermanentCount(playerA, rograkh, 1);
|
||||
|
||||
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Mountain");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, lightningBolt, rograkh);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
assertCounterCount(rograkh, CounterType.SHIELD, 0);
|
||||
assertPermanentCount(playerA, rograkh, 0);
|
||||
assertPermanentCount(playerD, rograkh, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not work for commander creature.
|
||||
*/
|
||||
@Test
|
||||
public void testCommander() {
|
||||
addCard(Zone.COMMAND, playerD, rograkh); // {0}
|
||||
|
||||
addCard(Zone.HAND, playerA, shieldBroker); // {3}{U}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerD, rograkh);
|
||||
|
||||
castSpell(5, PhaseStep.PRECOMBAT_MAIN, playerA, shieldBroker);
|
||||
|
||||
setStopAt(5, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertCounterCount(rograkh, CounterType.SHIELD, 0);
|
||||
assertPermanentCount(playerA, rograkh, 0);
|
||||
assertPermanentCount(playerD, rograkh, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.keyword.SuspendAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.TimingRule;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.s.SinisterConcierge Sinister Concierge}
|
||||
* 2/1
|
||||
* When Sinister Concierge dies, you may exile it and put three time counters on it.
|
||||
* If you do, exile up to one target creature and put three time counters on it.
|
||||
* Each card exiled this way that doesn’t have suspend gains suspend.
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class SinisterConciergeTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String sinisterConcierge = "Sinister Concierge"; // 2/1
|
||||
private static final String bondedConstruct = "Bonded Construct"; // Simple 2/1
|
||||
private static final String lightningBolt = "Lightning Bolt"; // {R}
|
||||
|
||||
|
||||
/**
|
||||
* Test that both cards are exiled properly.
|
||||
*/
|
||||
@Test
|
||||
public void testWorking() {
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
addCard(Zone.BATTLEFIELD, playerA, sinisterConcierge);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, bondedConstruct);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, sinisterConcierge);
|
||||
setChoice(playerA, "Yes");
|
||||
addTarget(playerA, bondedConstruct);
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, sinisterConcierge, 1);
|
||||
assertCounterOnExiledCardCount(sinisterConcierge, CounterType.TIME, 3);
|
||||
|
||||
assertExileCount(playerB, bondedConstruct, 1);
|
||||
assertCounterOnExiledCardCount(bondedConstruct, CounterType.TIME, 3);
|
||||
|
||||
setStopAt(5, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, sinisterConcierge, 1);
|
||||
assertCounterOnExiledCardCount(sinisterConcierge, CounterType.TIME, 1);
|
||||
|
||||
assertExileCount(playerB, bondedConstruct, 1);
|
||||
assertCounterOnExiledCardCount(bondedConstruct, CounterType.TIME, 1);
|
||||
|
||||
setStopAt(6, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertExileCount(playerA, sinisterConcierge, 1);
|
||||
assertExileCount(playerB, bondedConstruct, 0);
|
||||
assertPermanentCount(playerB, bondedConstruct, 1);
|
||||
|
||||
setStopAt(7, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
assertExileCount(playerA, sinisterConcierge, 0);
|
||||
assertPermanentCount(playerA, sinisterConcierge, 1);
|
||||
assertExileCount(playerB, bondedConstruct, 0);
|
||||
assertPermanentCount(playerB, bondedConstruct, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.s.SkywayRobber Skyway Robber}
|
||||
* <p>
|
||||
* Escape—{3}{U}, Exile five other cards from your graveyard.
|
||||
* (You may cast this card from your graveyard for its escape cost.)
|
||||
* <p>
|
||||
* Skyway Robber escapes with
|
||||
* “Whenever Skyway Robber deals combat damage to a player,
|
||||
* you may cast an artifact, instant, or sorcery spell from among cards exiled with Skyway Robber
|
||||
* without paying its mana cost.”
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class SkywayRobberTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String skywayRobber = "Skyway Robber";
|
||||
|
||||
/**
|
||||
* Check that you are not given the option to cast anything if there are no valid choices.
|
||||
*/
|
||||
@Test
|
||||
public void testNoOption() {
|
||||
addCard(Zone.GRAVEYARD, playerA, skywayRobber);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Mountain", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + skywayRobber + " with Escape");
|
||||
|
||||
attack(3, playerA, skywayRobber);
|
||||
|
||||
setStopAt(3, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
assertExileCount(playerA, "Mountain", 5);
|
||||
assertLife(playerB, 17);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the cast works.
|
||||
*/
|
||||
@Test
|
||||
public void testCast() {
|
||||
addCard(Zone.GRAVEYARD, playerA, skywayRobber);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Mountain", 4);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Sol Ring" );
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + skywayRobber + " with Escape");
|
||||
|
||||
attack(3, playerA, skywayRobber);
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertExileCount(playerA, "Mountain", 4);
|
||||
assertPermanentCount(playerA, "Sol Ring", 1);
|
||||
assertLife(playerB, 17);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.t.ThreefoldSignal Threefold Signal}
|
||||
* <p>
|
||||
* Each spell you cast that’s exactly three colors has replicate {3}.
|
||||
* @author Alex-Vasile
|
||||
*/
|
||||
public class ThreefoldSignalTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String threefoldSignal = "Threefold Signal";
|
||||
// R
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
// WUBRG
|
||||
private static final String atogatog = "Atogatog";
|
||||
// WUB
|
||||
private static final String esperSojourners = "Esper Sojourners";
|
||||
|
||||
/**
|
||||
* Check that it works for three-colored spells
|
||||
*/
|
||||
@Test
|
||||
public void testShouldWork() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.HAND, playerA, esperSojourners);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, esperSojourners);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, false);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, esperSojourners, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that it does not trigger for spells with less than three colors.
|
||||
*/
|
||||
@Test
|
||||
public void testShouldNotWork1Color() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.HAND, playerA, lightningBolt);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, playerB);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerB, 17);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that it does not trigger for spells with more than three colors.
|
||||
*/
|
||||
@Test
|
||||
public void testShouldNotWork5Color() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.HAND, playerA, atogatog);
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, atogatog);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerA, atogatog, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that it does not trigger for spells opponents control.
|
||||
*/
|
||||
@Test
|
||||
public void testShouldNotWorkOpponent() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||
addCard(Zone.HAND, playerB, esperSojourners);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, esperSojourners);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertPermanentCount(playerB, esperSojourners, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that casting one half of a split card doesn't trigger it even if the whole split card has 3 colors.
|
||||
* Relevant ruling:
|
||||
* 709.3a Only the chosen half is evaluated to see if it can be cast.
|
||||
* Only that half is considered to be put onto the stack.
|
||||
* 709.3b While on the stack, only the characteristics of the half being cast exist.
|
||||
* The other half’s characteristics are treated as though they didn’t exist.
|
||||
*/
|
||||
@Test
|
||||
public void oneHalfOfSplitCardDoesntTrigger() {
|
||||
// {G}{U} / {4}{W}{U}
|
||||
// Beck: Whenever a creature enters the battlefield this turn, you may draw a card.
|
||||
// Call: Create four 1/1 white Bird creature tokens with flying.
|
||||
// Fuse
|
||||
String beckCall = "Beck // Call";
|
||||
addCard(Zone.HAND, playerA, beckCall);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4 + 3); // For generic costs and to have enough for replicate
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Call");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Bird Token", 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that casting a split card with fuse triggers if both halves together have 3 colors
|
||||
*/
|
||||
@Test
|
||||
public void fusedSplitCardTriggers() {
|
||||
// {G}{U} / {4}{W}{U}
|
||||
// Beck: Whenever a creature enters the battlefield this turn, you may draw a card.
|
||||
// Call: Create four 1/1 white Bird creature tokens with flying.
|
||||
// Fuse
|
||||
String beckCall = "Beck // Call";
|
||||
addCard(Zone.HAND, playerA, beckCall);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4 + 3); // For generic costs and to have enough for replicate
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "fused Beck // Call");
|
||||
setChoice(playerA, true); // Pay replicate once
|
||||
setChoice(playerA, false); // Don't pay replicate twice
|
||||
|
||||
// Copy resolves, first Beck then call
|
||||
setChoice(playerA, "Whenever", 3); // 4 triggers total, pick order for 3 and the 4th is auto-chosen
|
||||
setChoice(playerA, true, 4); // Draw cards 4 times
|
||||
|
||||
// Original resolves
|
||||
// There will be 8 ETB triggers. 4 creatures enter but there are 2 instances of Beck that were cast
|
||||
setChoice(playerA, "Whenever", 7); // 8 triggers total, pick order for 7 and the 8th is auto-chosen
|
||||
setChoice(playerA, true, 8); // Draw cards 8 times
|
||||
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Bird Token", 4 + 4);
|
||||
assertHandCount(playerA, 4 + (4+4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that casting a split card with fuse triggers if both halves together have 3 colors
|
||||
*/
|
||||
@Test
|
||||
public void fusedSplitCardTriggers2() {
|
||||
// {3}{B}{G} / {R}{G}
|
||||
// Flesh: Exile target creature card from a graveyard.
|
||||
// Put X +1/+1 counters on target creature, where X is the power of the card you exiled.
|
||||
// Blood: Target creature you control deals damage equal to its power to any target.
|
||||
// Fuse
|
||||
String fleshBlood = "Flesh // Blood";
|
||||
addCard(Zone.HAND, playerA, fleshBlood);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, threefoldSignal);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1+3 + 3); // For red + generic costs and to have enough for replicate
|
||||
|
||||
// All are 2/2
|
||||
String lion = "Silvercoat Lion";
|
||||
addCard(Zone.BATTLEFIELD, playerA, lion);
|
||||
String griffin = "Abbey Griffin";
|
||||
addCard(Zone.GRAVEYARD, playerA, griffin); // Exile with original cast
|
||||
String centaur = "Accursed Centaur";
|
||||
addCard(Zone.GRAVEYARD, playerA, centaur); // Exile with copy
|
||||
|
||||
setStrictChooseMode(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "fused Flesh // Blood");
|
||||
setChoice(playerA, true); // Pay replicate once
|
||||
setChoice(playerA, false); // Don't pay replicate twice
|
||||
// Flesh
|
||||
addTarget(playerA, griffin);
|
||||
addTarget(playerA, lion);
|
||||
// Blood
|
||||
addTarget(playerA, lion);
|
||||
addTarget(playerA, playerB);
|
||||
// Copy of Flesh
|
||||
setChoice(playerA, true); // Change the exile card from the Griffin
|
||||
addTarget(playerA, centaur);
|
||||
setChoice(playerA, false); // Don't change target from the lion
|
||||
// Copy of Blood
|
||||
setChoice(playerA, false); // Don't change target from lion
|
||||
setChoice(playerA, false); // Don't change target from PlayerB
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(lion, CounterType.P1P1, 4); // 2 from the copy and two from the original cast
|
||||
assertLife(playerB, 20 - (2+2) - (2+2+2));
|
||||
assertExileCount(playerA, griffin, 1);
|
||||
assertExileCount(playerA, centaur, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package org.mage.test.cards.single.ncc;
|
||||
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Weathered Sentinels
|
||||
* {3}
|
||||
* Artifact Creature — Wall
|
||||
* Defender, vigilance, reach, trample
|
||||
* Weathered Sentinels can attack players who attacked you during their last turn as though it didn’t have defender.
|
||||
* Whenever Weathered Sentinels attacks, it gets +3/+3 and gains indestructible until end of turn.
|
||||
*/
|
||||
public class WeatheredSentinelsTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String weatheredSentinels = "Weathered Sentinels";
|
||||
// 1/1 Haste attacker
|
||||
private static final String gingerBrute = "Gingerbrute";
|
||||
|
||||
/**
|
||||
* Should not be able to attack a player who did not attack you on their last turn
|
||||
*/
|
||||
@Test
|
||||
public void testCantAttackNonAttacker() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, weatheredSentinels);
|
||||
|
||||
attack(1, playerA, weatheredSentinels);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
try {
|
||||
execute();
|
||||
} catch (Throwable e) {
|
||||
if (!e.getMessage().contains("Player PlayerA must have 0 actions but found 1")) {
|
||||
Assert.fail("Should have had error about playerA not being able to attack, but got:\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be able to attack a player that attacked you on their last turn, and it should get +3/+3 and indestructible until end of turn.
|
||||
*/
|
||||
@Test
|
||||
public void testCanAttackAttacker() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, weatheredSentinels);
|
||||
addCard(Zone.BATTLEFIELD, playerB, gingerBrute);
|
||||
|
||||
// Attack playerA
|
||||
attack(2, playerB, gingerBrute);
|
||||
|
||||
// Attack back
|
||||
attack(3, playerA, weatheredSentinels);
|
||||
|
||||
// Check that Weathered Sentinels has a +3/+3 and indestructible
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertAbility(playerA, weatheredSentinels, IndestructibleAbility.getInstance(), true);
|
||||
assertPowerToughness(playerA, weatheredSentinels, 5, 8);
|
||||
|
||||
// Check that Weathered Sentinels lost the abilities next turn
|
||||
setStopAt(4, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package org.mage.test.utils;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class CardUtilTest extends CardTestPlayerBase {
|
||||
// Whenever you cast or copy an instant or sorcery spell, reveal the top card of your library.
|
||||
// If it’s a nonland card, you may cast it by paying {1} rather than paying its mana cost.
|
||||
// If it’s a land card, put it onto the battlefield.
|
||||
private static final String jadzi = "Jadzi, Oracle of Arcavios";
|
||||
// Whenever you discard a nonland card, you may cast it from your graveyard.
|
||||
private static final String oskar = "Oskar, Rubbish Reclaimer";
|
||||
// MDFC where the back side is a land "Akoum Teeth"
|
||||
private static final String akoumWarrior = "Akoum Warrior"; // {5}{R}
|
||||
// Discard your hand, then draw a card for each card you’ve discarded this turn.
|
||||
private static final String changeOfFortune = "Change of Fortune"; // {3}{R}
|
||||
// MDFC where both sides should be playable
|
||||
private static final String birgi = "Birgi, God of Storytelling"; // {2}{R}, frontside of Harnfel
|
||||
private static final String harnfel = "Harnfel, Horn of Bounty"; // {4}{R}, backside of Birgi
|
||||
|
||||
/**
|
||||
* Test that it will for trigger for discarding a MDFC but will only let you cast the nonland side.
|
||||
*/
|
||||
@Test
|
||||
public void cantPlayLandSideOfMDFC() {
|
||||
addCard(Zone.HAND, playerA, changeOfFortune);
|
||||
addCard(Zone.HAND, playerA, akoumWarrior);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, oskar);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
|
||||
|
||||
skipInitShuffling();
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, changeOfFortune);
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_ATTACKERS);
|
||||
execute();
|
||||
assertPermanentCount(playerA, akoumWarrior, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that when both sides of a MDFC card match, we can choose either side.
|
||||
*/
|
||||
@Test
|
||||
public void testFrontSideOfMDFC() {
|
||||
addCard(Zone.HAND, playerA, changeOfFortune);
|
||||
addCard(Zone.HAND, playerA, birgi, 2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, oskar);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 12);
|
||||
|
||||
skipInitShuffling();
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, changeOfFortune);
|
||||
setChoice(playerA, "Whenever you discard");
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Cast " + birgi);
|
||||
setChoice(playerA, "Yes");
|
||||
setChoice(playerA, "Cast " + harnfel);
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_ATTACKERS);
|
||||
execute();
|
||||
assertPermanentCount(playerA, birgi, 1);
|
||||
assertPermanentCount(playerA, harnfel, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that with Jadzi, you are able to play the nonland side of a MDFC, and that the alternative cost works properly.
|
||||
*/
|
||||
@Test
|
||||
public void testJadziPlayingLandAndCast() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadzi);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1+1+1);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
|
||||
addCard(Zone.LIBRARY, playerA, "Cragcrown Pathway");
|
||||
addCard(Zone.LIBRARY, playerA, akoumWarrior);
|
||||
|
||||
skipInitShuffling();
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
setChoice(playerA, "Yes");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_ATTACKERS);
|
||||
execute();
|
||||
assertPermanentCount(playerA, akoumWarrior, 1);
|
||||
assertPermanentCount(playerA, "Cragcrown Pathway", 1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue