mirror of
https://github.com/magefree/mage.git
synced 2026-01-22 19:29:59 -08:00
Merge branch 'master' into feature/implement-spdr-piloted-by-peni
This commit is contained in:
commit
04bc7b8b2a
1185 changed files with 32207 additions and 8890 deletions
|
|
@ -116,7 +116,7 @@ public class CopyAITest extends CardTestPlayerBaseWithAIHelps {
|
|||
//
|
||||
addCard(Zone.GRAVEYARD, playerB, "Balduvian Bears", 1); // 2/2
|
||||
|
||||
// copy (AI must choose most valueable permanent - own)
|
||||
// copy (AI must choose most valuable permanent - own)
|
||||
aiPlayPriority(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ import java.util.List;
|
|||
* <p>
|
||||
* TODO: add tests and implement best choice selection on timeout
|
||||
* (AI must make any good/bad choice on timeout with game log - not a skip)
|
||||
*
|
||||
* TODO: AI do not support game sims from triggered (it's run, but do not use results)
|
||||
* <p>
|
||||
* TODO: AI do not support game simulations for target options in triggered
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
|
@ -213,4 +214,30 @@ public class SimulationPerformanceAITest extends CardTestPlayerBaseAI {
|
|||
// 4 damage to x2 bears and 1 damage to damaged bear
|
||||
runManyTargetOptionsInActivate("5 target creatures with one damaged", 5, 3, true, 20);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // TODO: enable and fix random error with too many sim nodes (depends on machine performance?)
|
||||
public void test_ElderDeepFiend_TooManyUpToChoices() {
|
||||
// bug: game freeze with 100% CPU usage
|
||||
// https://github.com/magefree/mage/issues/9518
|
||||
int cardsCount = 2; // 2+ cards will generate too much target options for simulations
|
||||
|
||||
// Boulderfall deals 5 damage divided as you choose among any number of targets.
|
||||
// Flash
|
||||
// Emerge {5}{U}{U} (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's mana value.)
|
||||
// When you cast this spell, tap up to four target permanents.
|
||||
addCard(Zone.HAND, playerA, "Elder Deep-Fiend", cardsCount); // {8}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 8 * cardsCount);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Kitesail Corsair", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Alpha Tyrranax", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Abbey Griffin", 2);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Elder Deep-Fiend", cardsCount); // ai must cast it
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ public class SimulationStabilityAITest extends CardTestPlayerBaseWithAIHelps {
|
|||
|
||||
@Before
|
||||
public void prepare() {
|
||||
// WARNING, for some reason java 8 sometime can't compile and run test with updated AI settings, so it's ok to freeze on it
|
||||
|
||||
// comment it to enable AI code debug
|
||||
Assert.assertFalse("AI stability tests must be run under release config", ComputerPlayer.COMPUTER_DISABLE_TIMEOUT_IN_GAME_SIMULATIONS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package org.mage.test.AI.basic;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||
|
||||
/**
|
||||
* Make sure AI can simulate priority with triggers resolve
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class SimulationTriggersAITest extends CardTestPlayerBaseWithAIHelps {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// TODO: trigger's target options supported on priority sim, but do not used for some reason
|
||||
// see addTargetOptions, node.children, ComputerPlayer6->targets, etc
|
||||
public void test_DeepglowSkate_MustBeSimulated() {
|
||||
// make sure targets choosing on trigger use same game sims and best results
|
||||
|
||||
// When Deepglow Skate enters the battlefield, double the number of each kind of counter on any number
|
||||
// of target permanents.
|
||||
addCard(Zone.HAND, playerA, "Deepglow Skate", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Adversary of Tyrants", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Caller of the Pride", 1); // x4 loyalty
|
||||
//
|
||||
// This creature enters with a -1/-1 counter on it.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bloodied Ghost", 1); // 3/3
|
||||
//
|
||||
// Players can't activate planeswalkers' loyalty abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Immortal Sun", 1); // disable planeswalkers usage by AI
|
||||
|
||||
// AI must cast boost and ignore doubling of -1/-1 counters on own creatures due bad score
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Deepglow Skate", 1);
|
||||
assertCounterCount(playerA, "Ajani, Adversary of Tyrants", CounterType.LOYALTY, 4 * 2);
|
||||
assertCounterCount(playerA, "Ajani, Caller of the Pride", CounterType.LOYALTY, 4 * 2);
|
||||
assertCounterCount(playerA, "Bloodied Ghost", CounterType.M1M1, 1); // make sure AI will not double bad counters
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_DeepglowSkate_PerformanceOnTooManyChoices() {
|
||||
// bug: game freeze with 100% CPU usage
|
||||
// https://github.com/magefree/mage/issues/9438
|
||||
int cardsCount = 2; // 2+ cards will generate too much target options for simulations
|
||||
int boostMultiplier = (int) Math.pow(2, cardsCount);
|
||||
|
||||
// When Deepglow Skate enters the battlefield, double the number of each kind of counter on any number
|
||||
// of target permanents.
|
||||
addCard(Zone.HAND, playerA, "Deepglow Skate", cardsCount); // {4}{U}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5 * cardsCount);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Adversary of Tyrants", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ajani, Caller of the Pride", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ajani Goldmane", 1); // x4 loyalty
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ajani, Inspiring Leader", 1); // x5 loyalty
|
||||
//
|
||||
// Players can't activate planeswalkers' loyalty abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "The Immortal Sun", 1); // disable planeswalkers usage by AI
|
||||
|
||||
// AI must cast multiple booster spells and double only own counters and only good
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Deepglow Skate", cardsCount);
|
||||
assertCounterCount(playerA, "Ajani, Adversary of Tyrants", CounterType.LOYALTY, 4 * boostMultiplier);
|
||||
assertCounterCount(playerA, "Ajani, Caller of the Pride", CounterType.LOYALTY, 4 * boostMultiplier);
|
||||
assertCounterCount(playerB, "Ajani Goldmane", CounterType.LOYALTY, 4);
|
||||
assertCounterCount(playerB, "Ajani, Inspiring Leader", CounterType.LOYALTY, 5);
|
||||
}
|
||||
}
|
||||
|
|
@ -69,6 +69,7 @@ public class ValakutTheMoltenPinnacleTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scapeshift");
|
||||
setChoice(playerA, "Forest^Forest^Forest^Forest^Forest^Forest"); // to sac
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
addTarget(playerA, "Mountain^Mountain^Mountain^Mountain^Mountain^Mountain"); // to search
|
||||
setChoice(playerA, "Whenever a Mountain", 6 - 1); // x6 triggers from valakut
|
||||
addTarget(playerA, playerB, 6); // to deal damage
|
||||
|
|
|
|||
|
|
@ -337,4 +337,20 @@ public class BargainTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20 + 3);
|
||||
assertTappedCount("Forest", true, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantBargainWithRestriction() {
|
||||
setStrictChooseMode(true);
|
||||
// Players can’t pay life or sacrifice nonland permanents to cast spells or activate abilities.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Yasharn, Implacable Earth");
|
||||
addCard(Zone.HAND, playerA, glutton);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, relic);
|
||||
|
||||
checkPlayableAbility("restricted by Yasharn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hamlet Glutton", false);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,32 +61,37 @@ public class CumulativeUpkeepTest extends CardTestPlayerBase {
|
|||
// Whenever Kor Celebrant or another creature you control enters, you gain 1 life.
|
||||
addCard(Zone.HAND, playerB, "Kor Celebrant", 1); // Creature {2}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||
//
|
||||
// Cumulative upkeep {2}
|
||||
// When Illusions of Grandeur enters the battlefield, you gain 20 life.
|
||||
// At the beginning of your upkeep, put an age counter on this permanent,
|
||||
// then sacrifice it unless you pay its upkeep cost for each age counter on it.
|
||||
// When Illusions of Grandeur leaves the battlefield, you lose 20 life.
|
||||
addCard(Zone.HAND, playerA, "Illusions of Grandeur"); // Enchantment {3}{U}
|
||||
|
||||
// At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||
//
|
||||
// At the beginning of your upkeep, you may exchange control of target nonland permanent you control
|
||||
// and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
|
||||
addCard(Zone.HAND, playerA, "Puca's Mischief"); // Enchantment {3}{U}
|
||||
|
||||
|
||||
// turn 1, 2 - prepare cumulative upkeep and gain life triggers
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Illusions of Grandeur");
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Kor Celebrant");
|
||||
|
||||
// Illusions of Grandeur - CumulativeUpkeepAbility: Cumulative upkeep {2}
|
||||
setChoice(playerA, true); // Pay {2}?
|
||||
|
||||
|
||||
// turn 3 - upkeep trigger and prepare control card
|
||||
setChoice(playerA, true); // use upkeep cost {2}
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Puca's Mischief");
|
||||
|
||||
setChoice(playerA, "Cumulative upkeep"); // Triggered list (total 2) which trigger goes first on the stack
|
||||
addTarget(playerA, "Illusions of Grandeur"); // Own target permanent of Puca's Mischief
|
||||
addTarget(playerA, "Kor Celebrant"); // Opponent's target permanent of Puca's Mischief
|
||||
|
||||
setChoice(playerA, true); // At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
|
||||
setChoice(playerA, false); // Pay {2}{2}?
|
||||
|
||||
// turn 5 - multiple upkeep triggers
|
||||
// first put upkeep, then put change control - so control will be resolved before upkeep cost
|
||||
setChoice(playerA, "Cumulative upkeep");
|
||||
|
||||
// resolve change control first
|
||||
addTarget(playerA, "Illusions of Grandeur"); // own target
|
||||
addTarget(playerA, "Kor Celebrant"); // opponent target
|
||||
setChoice(playerA, true); // yes, resolve change control
|
||||
|
||||
// resolve upkeep
|
||||
setChoice(playerA, false); // no, do not pay upkeep cost
|
||||
|
||||
checkPermanentCounters("Age counters", 5, PhaseStep.PRECOMBAT_MAIN, playerB, "Illusions of Grandeur", CounterType.AGE, 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public class DisguiseTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dog Walker using Disguise");
|
||||
runCode("face up on stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
Assert.assertEquals("stack, server - can't find spell", 1, currentGame.getStack().size());
|
||||
SpellAbility spellAbility = (SpellAbility) currentGame.getStack().getFirst().getStackAbility();
|
||||
SpellAbility spellAbility = (SpellAbility) currentGame.getStack().getFirstOrNull().getStackAbility();
|
||||
Assert.assertEquals("stack, server - can't find spell", "Cast Dog Walker using Disguise", spellAbility.getName());
|
||||
CardView spellView = getGameView(playerA).getStack().values().stream().findFirst().orElse(null);
|
||||
Assert.assertNotNull("stack, client: can't find spell", spellView);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class DisturbTest extends CardTestPlayerBase {
|
|||
checkStackObject("on stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hook-Haunt Drifter using Disturb", 1);
|
||||
runCode("check stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
// Stack must contain another card side, so spell/card characteristics must be diff from main side (only mana value is same)
|
||||
Spell spell = (Spell) game.getStack().getFirst();
|
||||
Spell spell = (Spell) game.getStack().getFirstOrNull();
|
||||
Assert.assertEquals("Hook-Haunt Drifter", spell.getName());
|
||||
Assert.assertEquals(1, spell.getCardType(game).size());
|
||||
Assert.assertEquals(CardType.CREATURE, spell.getCardType(game).get(0));
|
||||
|
|
@ -91,7 +91,7 @@ public class DisturbTest extends CardTestPlayerBase {
|
|||
checkStackObject("on stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Waildrifter using Disturb", 1);
|
||||
runCode("check stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
// Stack must contain another card side, so spell/card characteristics must be diff from main side (only mana value is same)
|
||||
Spell spell = (Spell) game.getStack().getFirst();
|
||||
Spell spell = (Spell) game.getStack().getFirstOrNull();
|
||||
Assert.assertEquals("Waildrifter", spell.getName());
|
||||
Assert.assertEquals(1, spell.getCardType(game).size());
|
||||
Assert.assertEquals(CardType.CREATURE, spell.getCardType(game).get(0));
|
||||
|
|
@ -187,7 +187,7 @@ public class DisturbTest extends CardTestPlayerBase {
|
|||
// cast with disturb
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Hook-Haunt Drifter using Disturb");
|
||||
runCode("check stack", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
Spell spell = (Spell) game.getStack().getFirst();
|
||||
Spell spell = (Spell) game.getStack().getFirstOrNull();
|
||||
Assert.assertEquals("mana value must be from main side", 2, spell.getManaValue());
|
||||
Assert.assertEquals("mana cost to pay must be modified", "{U}", spell.getSpellAbility().getManaCostsToPay().getText());
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package org.mage.test.cards.abilities.keywords;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -27,7 +28,9 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Savage Alliance", "mode=2Silvercoat Lion");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
|
|
@ -52,7 +55,9 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Collective Defiance", playerB);
|
||||
setModeChoice(playerA, "3"); // deal 3 dmg to opponent
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -78,10 +83,12 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Collective Defiance"); // {1}{R}{R} sorcery
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Collective Defiance", "mode=2Gaddock Teeg");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Collective Defiance", "mode=2Gaddock Teeg^mode=3targetPlayer=PlayerB");
|
||||
setModeChoice(playerA, "2"); // deal 4 dmg to target creature (gaddock teeg)
|
||||
setModeChoice(playerA, "3"); // deal 3 dmg to opponent
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -109,8 +116,6 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
addCard(Zone.HAND, playerA, "Collective Defiance"); // {1}{R}{R} sorcery
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Collective Defiance", "mode=2Wall of Omens");
|
||||
setModeChoice(playerA, "1"); // opponent discards hand and draws that many
|
||||
setModeChoice(playerA, "2"); // deal 4 dmg to target creature (Wall of Omens)
|
||||
|
|
@ -120,6 +125,8 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Spell Queller");
|
||||
addTarget(playerB, "Collective Defiance");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.mage.test.cards.abilities.keywords;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -81,4 +82,243 @@ public class ForetellTest extends CardTestPlayerBase {
|
|||
assertExileCount(playerA, "Lightning Bolt", 1); // foretold card in exile
|
||||
assertPowerToughness(playerA, "Dream Devourer", 2, 3); // +2 power boost from trigger due to foretell of Lightning Bolt
|
||||
}
|
||||
|
||||
|
||||
// Tests needed to check watcher scope issue (see issue #7493 and issue #13774)
|
||||
|
||||
private static final String scornEffigy = "Scorn Effigy"; // {3} 2/3 foretell {0}
|
||||
private static final String poisonCup = "Poison the Cup"; // {1}{B}{B} instant destroy target creature
|
||||
// Foretell {1}{B}, if spell was foretold, scry 2
|
||||
private static final String flamespeaker = "Flamespeaker Adept"; // {2}{R} 2/3
|
||||
// Whenever you scry, gets +2/+0 and first strike until end of turn
|
||||
private static final String chancemetElves = "Chance-Met Elves"; // {2}{G} 3/2
|
||||
// Whenever you scry, gets a +1/+1 counter, triggers once per turn
|
||||
|
||||
private static final String cardE = "Elite Vanguard";
|
||||
private static final String cardD = "Devilthorn Fox";
|
||||
private static final String cardC = "Canopy Gorger";
|
||||
private static final String cardB = "Barbtooth Wurm";
|
||||
private static final String cardA = "Alaborn Trooper";
|
||||
|
||||
private void setupLibrariesEtc() {
|
||||
// make a library of 5 cards, bottom : E D C B A : top
|
||||
skipInitShuffling();
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
addCard(Zone.LIBRARY, playerA, cardE);
|
||||
addCard(Zone.LIBRARY, playerA, cardD);
|
||||
addCard(Zone.LIBRARY, playerA, cardC);
|
||||
addCard(Zone.LIBRARY, playerA, cardB);
|
||||
addCard(Zone.LIBRARY, playerA, cardA);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
addCard(Zone.LIBRARY, playerB, cardE);
|
||||
addCard(Zone.LIBRARY, playerB, cardD);
|
||||
addCard(Zone.LIBRARY, playerB, cardC);
|
||||
addCard(Zone.LIBRARY, playerB, cardB);
|
||||
addCard(Zone.LIBRARY, playerB, cardA);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, flamespeaker);
|
||||
addCard(Zone.BATTLEFIELD, playerB, chancemetElves);
|
||||
addCard(Zone.HAND, playerA, scornEffigy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForetellWatcherPlayerA() {
|
||||
setupLibrariesEtc();
|
||||
addCard(Zone.HAND, playerA, poisonCup);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, scornEffigy);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell");
|
||||
checkExileCount("foretold in exile", 2, PhaseStep.PRECOMBAT_MAIN, playerA, poisonCup, 1);
|
||||
// turn 3, draw card A
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell {1}{B}", chancemetElves);
|
||||
// foretold, so scry 2 (cards B and C)
|
||||
addTarget(playerA, cardB); // scrying B bottom (C remains on top)
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, scornEffigy, 2, 3);
|
||||
assertGraveyardCount(playerA, poisonCup, 1);
|
||||
assertGraveyardCount(playerB, chancemetElves, 1);
|
||||
assertPowerToughness(playerA, flamespeaker, 4, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForetellWatcherPlayerB() {
|
||||
setupLibrariesEtc();
|
||||
addCard(Zone.HAND, playerB, poisonCup);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, scornEffigy);
|
||||
// turn 2, draw card A
|
||||
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Foretell");
|
||||
checkExileCount("foretold in exile", 2, PhaseStep.PRECOMBAT_MAIN, playerB, poisonCup, 1);
|
||||
// turn 4, draw card B
|
||||
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Foretell {1}{B}", flamespeaker);
|
||||
// foretold, so scry 2 (cards C and D)
|
||||
addTarget(playerB, cardD); // scrying D bottom (C remains on top)
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(4, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, scornEffigy, 2, 3);
|
||||
assertGraveyardCount(playerB, poisonCup, 1);
|
||||
assertGraveyardCount(playerA, flamespeaker, 1);
|
||||
assertPowerToughness(playerB, chancemetElves, 4, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRanar() {
|
||||
skipInitShuffling();
|
||||
String ranar = "Ranar the Ever-Watchful"; // 2WU 2/3 Flying Vigilance
|
||||
// The first card you foretell each turn costs {0} to foretell.
|
||||
// Whenever one or more cards are put into exile from your hand or a spell or ability you control exiles
|
||||
// one or more permanents from the battlefield, create a 1/1 white Spirit creature token with flying.
|
||||
addCard(Zone.BATTLEFIELD, playerA, ranar);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sage of the Falls"); // may loot on creature ETB
|
||||
addCard(Zone.HAND, playerA, poisonCup);
|
||||
addCard(Zone.LIBRARY, playerA, scornEffigy);
|
||||
addCard(Zone.HAND, playerA, "Wastes");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); // poison the cup
|
||||
setChoice(playerA, true); // yes to loot
|
||||
setChoice(playerA, "Wastes"); // discard
|
||||
|
||||
checkExileCount("Poison the Cup foretold", 1, PhaseStep.BEGIN_COMBAT, playerA, poisonCup, 1);
|
||||
checkHandCardCount("scorn effigy drawn", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, scornEffigy, 1);
|
||||
checkPlayableAbility("can't foretell another for free", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell", false);
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell"); // scorn effigy
|
||||
setChoice(playerA, false); // no loot
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Spirit Token", 2);
|
||||
assertExileCount(playerA, 2);
|
||||
assertGraveyardCount(playerA, "Wastes", 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCosmosCharger() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Cosmos Charger");
|
||||
// Foretelling cards from your hand costs {1} less and can be done on any player’s turn.
|
||||
|
||||
addCard(Zone.HAND, playerA, scornEffigy);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Wastes");
|
||||
|
||||
activateAbility(2, PhaseStep.UPKEEP, playerA, "Foretell");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, scornEffigy, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlrund() {
|
||||
String alrund = "Alrund, God of the Cosmos";
|
||||
// Alrund gets +1/+1 for each card in your hand and each foretold card you own in exile.
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, alrund); // 1/1
|
||||
addCard(Zone.HAND, playerA, scornEffigy);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Cadaverous Bloom");
|
||||
// Exile a card from your hand: Add {B}{B} or {G}{G}.
|
||||
|
||||
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Exile a card from your hand: Add {B}{B}");
|
||||
setChoice(playerA, "Lightning Bolt");
|
||||
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Foretell");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 0);
|
||||
assertExileCount(playerA, scornEffigy, 1);
|
||||
assertPowerToughness(playerA, alrund, 2, 2);
|
||||
}
|
||||
|
||||
private static final String valkyrie = "Ethereal Valkyrie"; // 4/4 flying
|
||||
// Whenever this creature enters or attacks, draw a card, then exile a card from your hand face down.
|
||||
// It becomes foretold. Its foretell cost is its mana cost reduced by {2}.
|
||||
|
||||
@Test
|
||||
public void testEtherealValkyrie() {
|
||||
skipInitShuffling();
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
String saga = "Niko Defies Destiny";
|
||||
// I - You gain 2 life for each foretold card you own in exile.
|
||||
// II - Add {W}{U}. Spend this mana only to foretell cards or cast spells that have foretell.
|
||||
String crab = "Fortress Crab"; // 3U 1/6
|
||||
String puma = "Stonework Puma"; // {3} 2/2
|
||||
addCard(Zone.BATTLEFIELD, playerA, valkyrie);
|
||||
addCard(Zone.HAND, playerA, saga);
|
||||
addCard(Zone.HAND, playerA, crab);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tundra", 5);
|
||||
addCard(Zone.LIBRARY, playerA, "Wastes");
|
||||
addCard(Zone.LIBRARY, playerA, puma);
|
||||
|
||||
attack(1, playerA, valkyrie, playerB);
|
||||
addTarget(playerA, crab); // exile becomes foretold
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, saga); // gain 2 life
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
checkExileCount("crab foretold", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, crab, 1);
|
||||
checkPlayableAbility("can't cast foretold same turn", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell", false);
|
||||
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, puma);
|
||||
|
||||
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 22);
|
||||
assertLife(playerB, 16);
|
||||
assertCounterCount(saga, CounterType.LORE, 2);
|
||||
assertPowerToughness(playerA, crab, 1, 6);
|
||||
assertPowerToughness(playerA, valkyrie, 4, 4);
|
||||
assertPowerToughness(playerA, puma, 2, 2);
|
||||
assertHandCount(playerA, 1);
|
||||
assertHandCount(playerA, "Wastes", 1);
|
||||
assertTappedCount("Tundra", true, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForetoldNotForetell() {
|
||||
skipInitShuffling();
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
addCard(Zone.LIBRARY, playerA, "Wastes");
|
||||
addCard(Zone.LIBRARY, playerA, "Darksteel Citadel");
|
||||
addCard(Zone.BATTLEFIELD, playerA, valkyrie);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Dream Devourer");
|
||||
addCard(Zone.HAND, playerA, "Papercraft Decoy");
|
||||
|
||||
attack(1, playerA, valkyrie, playerB);
|
||||
addTarget(playerA, "Papercraft Decoy"); // exile becomes foretold
|
||||
|
||||
checkPT("Dream Devourer not boosted", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Dream Devourer", 0, 3);
|
||||
checkPlayableAbility("Can't cast this turn", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Foretell", false);
|
||||
checkHandCardCount("card drawn", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Darksteel Citadel", 1);
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Foretell");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 16);
|
||||
assertPowerToughness(playerA, "Papercraft Decoy", 2, 1);
|
||||
assertPowerToughness(playerA, "Dream Devourer", 0, 3);
|
||||
assertHandCount(playerA, 2);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.mage.test.cards.abilities.keywords;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -50,6 +51,7 @@ public class KickerWithAnyNumberModesAbilityTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, true); // use kicker
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, playerA); // gain x life
|
||||
addTarget(playerA, "Balduvian Bears"); // get counters
|
||||
|
||||
|
|
@ -79,6 +81,7 @@ public class KickerWithAnyNumberModesAbilityTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, true); // use kicker
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, playerA); // gain x life
|
||||
addTarget(playerA, "Balduvian Bears"); // get counters
|
||||
|
||||
|
|
@ -108,6 +111,7 @@ public class KickerWithAnyNumberModesAbilityTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, true); // use kicker
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, playerA); // gain x life
|
||||
addTarget(playerA, "Balduvian Bears"); // get counters
|
||||
|
||||
|
|
@ -139,6 +143,7 @@ public class KickerWithAnyNumberModesAbilityTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, true); // use kicker
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, playerA); // gain x life
|
||||
addTarget(playerA, "Balduvian Bears"); // get counters
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.abilities.keyword.IntimidateAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class LandfallTest extends CardTestPlayerBase {
|
||||
|
|
@ -26,9 +23,12 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rest for the Weary");
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Rest for the Weary");
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -43,7 +43,6 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
* If you Hive Mind an opponent's Rest for the Weary and redirect its target
|
||||
* to yourself when it's not your turn, the game spits out this message and
|
||||
* rolls back to before Rest for the Weary was cast.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testHiveMind() {
|
||||
|
|
@ -57,15 +56,17 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
// Landfall - If you had a land enter the battlefield under your control this turn, that player gains 8 life instead.
|
||||
addCard(Zone.HAND, playerA, "Rest for the Weary", 1);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rest for the Weary");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rest for the Weary", playerA);
|
||||
setChoice(playerB, true); // change target of copied spell
|
||||
addTarget(playerB, playerB);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Rest for the Weary", 1);
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 24);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -76,6 +77,7 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -104,10 +106,14 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||
|
||||
// prepare landfall
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Searing Blaze");
|
||||
addTarget(playerA, playerB);
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -133,6 +139,7 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
attack(2, playerB, "Silvercoat Lion");
|
||||
castSpell(2, PhaseStep.DECLARE_ATTACKERS, playerB, "Groundswell", "Silvercoat Lion");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -179,6 +186,7 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
attack(2, playerB, "Silvercoat Lion");
|
||||
castSpell(2, PhaseStep.DECLARE_ATTACKERS, playerB, "Groundswell", "Silvercoat Lion");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public class MayhemTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String islanders = "Spider-Islanders";
|
||||
|
||||
@Test
|
||||
public void testCastRegular() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
addCard(Zone.HAND, playerA, islanders);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, islanders);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, islanders, 1);
|
||||
}
|
||||
|
||||
private static final String imp = "Putrid Imp";
|
||||
|
||||
@Test
|
||||
public void testCastDiscarded() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, imp);
|
||||
addCard(Zone.HAND, playerA, islanders);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard");
|
||||
setChoice(playerA, islanders);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, islanders + " with Mayhem");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, islanders, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantCastGraveyard() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.GRAVEYARD, playerA, islanders);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, islanders + " with Mayhem");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
try {
|
||||
execute();
|
||||
} catch (Throwable e) {
|
||||
Assert.assertEquals(
|
||||
"Should fail to be able to cast " + islanders + " with mayhem as it wasn't discarded this turn",
|
||||
"Can't find ability to activate command: Cast " + islanders + " with Mayhem", e.getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCantCastDiscardedPreviously() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, imp);
|
||||
addCard(Zone.HAND, playerA, islanders);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard");
|
||||
setChoice(playerA, islanders);
|
||||
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, islanders + " with Mayhem");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
try {
|
||||
execute();
|
||||
} catch (Throwable e) {
|
||||
Assert.assertEquals(
|
||||
"Should fail to be able to cast " + islanders + " with mayhem as it wasn't discarded this turn",
|
||||
"Can't find ability to activate command: Cast " + islanders + " with Mayhem", e.getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import mage.filter.predicate.mageobject.*;
|
|||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -319,6 +320,7 @@ public class PrototypeTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, epiphany);
|
||||
setModeChoice(playerA, "3"); // Return target nonland permanent to its owner's hand.
|
||||
setModeChoice(playerA, "4"); // Create a token that's a copy of target creature you control.
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, automaton);
|
||||
addTarget(playerA, automaton);
|
||||
|
||||
|
|
@ -340,6 +342,7 @@ public class PrototypeTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, epiphany);
|
||||
setModeChoice(playerA, "3"); // Return target nonland permanent to its owner's hand.
|
||||
setModeChoice(playerA, "4"); // Create a token that's a copy of target creature you control.
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
addTarget(playerA, automaton);
|
||||
addTarget(playerA, automaton);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.watchers.common.SaddledMountWatcher;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -90,6 +91,7 @@ public class SaddleTest extends CardTestPlayerBase {
|
|||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Saddle");
|
||||
setChoice(playerA, bear); // to saddle cost
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
attack(1, playerA, possum, playerB);
|
||||
setChoice(playerA, bear); // to return
|
||||
|
|
@ -116,6 +118,7 @@ public class SaddleTest extends CardTestPlayerBase {
|
|||
// turn 1 - saddle x2 and trigger on attack
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Saddle");
|
||||
setChoice(playerA, bear + "^" + lion);
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
attack(1, playerA, possum, playerB);
|
||||
setChoice(playerA, elf); // to return (try to choose a wrong creature, so game must not allow to choose it)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.mage.test.cards.abilities.keywords;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -24,8 +25,9 @@ public class SpreeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, bear, 1);
|
||||
addCard(Zone.HAND, playerA, accident);
|
||||
|
||||
setModeChoice(playerA, "1");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident, bear);
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
@ -41,8 +43,9 @@ public class SpreeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1 + 1);
|
||||
addCard(Zone.HAND, playerA, accident);
|
||||
|
||||
setModeChoice(playerA, "2");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident);
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
@ -58,9 +61,10 @@ public class SpreeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, bear, 1);
|
||||
addCard(Zone.HAND, playerA, accident);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident, bear);
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, "2");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident, bear);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
@ -80,9 +84,10 @@ public class SpreeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, electromancer, 1);
|
||||
addCard(Zone.HAND, playerA, accident);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident, bear);
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, "2");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, accident, bear);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.cards.s.SpringOfEternalPeace;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
|
|
@ -384,7 +383,6 @@ public class TransformTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerA, "Huntmaster of the Fells", 2, 2);
|
||||
assertTappedCount("Plains", true, 2);
|
||||
assertTappedCount("Wastes", true, 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -413,8 +411,32 @@ public class TransformTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "Ravager of the Fells", 0);
|
||||
assertPermanentCount(playerA, "Huntmaster of the Fells", 1);
|
||||
assertPowerToughness(playerA, "Huntmaster of the Fells", 2, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWildsongHowlerTrigger() {
|
||||
// The only Daybound/Nightbound card with a Transforms trigger on the back side
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
addCard(Zone.HAND, playerA, "Howlpack Piper", 2); // Creature {2}{R}{G}
|
||||
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 50);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Howlpack Piper");
|
||||
setChoice(playerA, true); //Transform trigger
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Howlpack Piper");
|
||||
setChoice(playerA, true); //ETB trigger
|
||||
addTarget(playerA, "Silvercoat Lion");
|
||||
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
|
||||
setStrictChooseMode(true);
|
||||
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Wildsong Howler", 2);
|
||||
assertPermanentCount(playerA, "Howlpack Piper", 0); // They should be both transformed
|
||||
assertHandCount(playerA, "Silvercoat Lion", 3);
|
||||
assertHandCount(playerA, 3); //The two Silvercoat Lions from triggers and 1 from natural card draw
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,22 +5,31 @@ import mage.constants.Zone;
|
|||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author notgreat
|
||||
*/
|
||||
public class OneShotNonTargetTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void YorionChooseAfterTriggerTest() {
|
||||
// When Yorion enters the battlefield, exile any number of other nonland permanents you own and control.
|
||||
// Return those cards to the battlefield at the beginning of the next end step.
|
||||
addCard(Zone.HAND, playerA, "Yorion, Sky Nomad");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
|
||||
//
|
||||
// When Resolute Reinforcements enters the battlefield, create a 1/1 white Soldier creature token.
|
||||
addCard(Zone.HAND, playerA, "Resolute Reinforcements");
|
||||
|
||||
// prepare yori and put trigger on stack
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yorion, Sky Nomad");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
|
||||
checkPermanentCount("Yorion on battlefield", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Yorion, Sky Nomad", 1);
|
||||
|
||||
// prepare another create before yori trigger resolve
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Resolute Reinforcements");
|
||||
setChoice(playerA, "Resolute Reinforcements");
|
||||
setChoice(playerA, "Resolute Reinforcements"); // 1 of 2 target for yori trigger
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
|
|
@ -30,6 +39,7 @@ public class OneShotNonTargetTest extends CardTestPlayerBase {
|
|||
assertPermanentCount(playerA, "Resolute Reinforcements", 1);
|
||||
assertTappedCount("Plains", true, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NonTargetAdjusterTest() {
|
||||
addCard(Zone.HAND, playerA, "Temporal Firestorm");
|
||||
|
|
@ -52,21 +62,30 @@ public class OneShotNonTargetTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Python", 0);
|
||||
assertGraveyardCount(playerA, "Watchwolf", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ModeSelectionTest() {
|
||||
addCard(Zone.HAND, playerA, "SOLDIER Military Program");
|
||||
// At the beginning of combat on your turn, choose one. If you control a commander, you may choose both instead.
|
||||
// * Create a 1/1 white Soldier creature token.
|
||||
// * Put a +1/+1 counter on each of up to two Soldiers you control.
|
||||
addCard(Zone.HAND, playerA, "SOLDIER Military Program"); // {2}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Squire", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Squire", 1); // 1/2
|
||||
|
||||
// prepare mode ability
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "SOLDIER Military Program");
|
||||
|
||||
// turn 1 combat - put counter
|
||||
setModeChoice(playerA, "2");
|
||||
setChoice(playerA, "Squire");
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
// turn 3 combat - create token
|
||||
setModeChoice(playerA, "1");
|
||||
|
||||
// turn 5 combat - put counter
|
||||
setModeChoice(playerA, "2");
|
||||
setChoice(playerA, "Squire^Soldier Token");
|
||||
setChoice(playerA, "Squire");
|
||||
setChoice(playerA, "Soldier Token");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.END_TURN);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AddCardSubtypeAllEffectTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Kudo, King Among Bears
|
||||
{G}{W}
|
||||
Legendary Creature — Bear
|
||||
Other creatures have base power and toughness 2/2 and are Bears in addition to their other types.
|
||||
2/2
|
||||
*/
|
||||
private static final String kudo = "Kudo, King Among Bears";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature — Human Wizard
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitive = "Fugitive Wizard";
|
||||
|
||||
@Test
|
||||
public void testAddCardSubtypeAllEffect() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, fugitive, 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, fugitive, 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, kudo);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Savannah", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) {
|
||||
if (permanent.getName().equals(fugitive)) {
|
||||
assertTrue(permanent.hasSubtype(SubType.BEAR, currentGame));
|
||||
assertTrue(permanent.hasSubtype(SubType.WIZARD, currentGame));
|
||||
assertTrue(permanent.hasSubtype(SubType.HUMAN, currentGame));
|
||||
assertEquals(2, permanent.getPower().getModifiedBaseValue());
|
||||
assertEquals(2, permanent.getToughness().getModifiedBaseValue());
|
||||
}
|
||||
}
|
||||
|
||||
assertSubtype(kudo, SubType.BEAR);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.token.FoodToken;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -18,12 +24,14 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*/
|
||||
public class AngelOfJubilationTest extends CardTestPlayerBase {
|
||||
|
||||
public static final String angelOfJubilation = "Angel of Jubilation";
|
||||
|
||||
/**
|
||||
* Tests boosting other non black creatures
|
||||
*/
|
||||
@Test
|
||||
public void testBoost() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Devout Chaplain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Corpse Traders");
|
||||
|
||||
|
|
@ -33,7 +41,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPowerToughness(playerA, "Angel of Jubilation", 3, 3);
|
||||
assertPowerToughness(playerA, angelOfJubilation, 3, 3);
|
||||
assertPowerToughness(playerA, "Devout Chaplain", 3, 3);
|
||||
assertPowerToughness(playerA, "Corpse Traders", 3, 3);
|
||||
}
|
||||
|
|
@ -43,14 +51,14 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
*/
|
||||
@Test
|
||||
public void testNoBoostOnBattlefieldLeave() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Devout Chaplain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Corpse Traders");
|
||||
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Angel of Jubilation");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", angelOfJubilation);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -58,14 +66,14 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 0);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 0);
|
||||
assertPowerToughness(playerA, "Devout Chaplain", 2, 2);
|
||||
assertPowerToughness(playerA, "Corpse Traders", 3, 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreatures() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Corpse Traders");
|
||||
|
||||
|
|
@ -81,7 +89,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeNonCreaturePermanents() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Savannah Lions");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barrin, Master Wizard");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
|
|
@ -89,20 +97,20 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Food Chain");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent: Return target creature to its owner's hand.");
|
||||
addTarget(playerB, "Angel of Jubilation"); // return to hand
|
||||
addTarget(playerB, angelOfJubilation); // return to hand
|
||||
setChoice(playerB, "Food Chain"); // sacrifice cost
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 0);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 0);
|
||||
assertPermanentCount(playerB, "Food Chain", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreaturesAsPartOfPermanentsOptions() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Barrin, Master Wizard");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves", 2);
|
||||
|
|
@ -115,13 +123,13 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Angel of Jubilation", 1);
|
||||
assertPermanentCount(playerA, angelOfJubilation, 1);
|
||||
assertPermanentCount(playerB, "Nantuko Husk", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeAll() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Corpse Traders");
|
||||
addCard(Zone.HAND, playerB, "Soulblast");
|
||||
|
|
@ -142,7 +150,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCantSacrificeCreatureSource() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Children of Korlis");
|
||||
|
||||
checkPlayableAbility("Can't sac", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice", false);
|
||||
|
|
@ -155,7 +163,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeAllLands() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Tomb of Urami");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4);
|
||||
|
||||
|
|
@ -169,7 +177,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testOpponentCanSacrificeNonCreatureSource() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tundra");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Wasteland");
|
||||
|
||||
|
|
@ -195,7 +203,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStrictChooseMode(true);
|
||||
// Other nonblack creatures you control get +1/+1.
|
||||
// Players can't pay life or sacrifice creatures to cast spells or activate abilities
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
|
||||
// Indestructible
|
||||
|
|
@ -234,7 +242,7 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStrictChooseMode(true);
|
||||
// Other nonblack creatures you control get +1/+1.
|
||||
// Players can't pay life or sacrifice creatures to cast spells or activate abilities
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Angel of Jubilation");
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
|
||||
// Pay 7 life: Draw seven cards.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Griselbrand");
|
||||
|
|
@ -244,4 +252,90 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
|
|||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanSacrificeTriggeredAbility() {
|
||||
/*
|
||||
Unscrupulous Contractor
|
||||
{2}{B}
|
||||
Creature — Human Assassin
|
||||
When this creature enters, you may sacrifice a creature. When you do, target player draws two cards and loses 2 life.
|
||||
Plot {2}{B}
|
||||
3/2
|
||||
*/
|
||||
String contractor = "Unscrupulous Contractor";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
2/2
|
||||
*/
|
||||
String cub = "Bear Cub";
|
||||
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.HAND, playerA, contractor);
|
||||
addCard(Zone.HAND, playerB, contractor);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, contractor);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, cub);
|
||||
addTarget(playerA, playerA);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, contractor);
|
||||
setChoice(playerB, true);
|
||||
setChoice(playerB, cub);
|
||||
addTarget(playerB, playerB);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 2);
|
||||
assertLife(playerA, 20 - 2);
|
||||
assertGraveyardCount(playerA, cub, 1);
|
||||
|
||||
assertHandCount(playerB, 1 + 2); //draw + contractor effect
|
||||
assertLife(playerB, 20 - 2);
|
||||
assertGraveyardCount(playerB, cub, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canSacToMondrakWithArtifacts() {
|
||||
setStrictChooseMode(true);
|
||||
//Mondrak, Glory Dominus
|
||||
//{2}{W}{W}
|
||||
//Legendary Creature — Phyrexian Horror
|
||||
//If one or more tokens would be created under your control, twice that many of those tokens are created instead.
|
||||
//{1}{W/P}{W/P}, Sacrifice two other artifacts and/or creatures: Put an indestructible counter on Mondrak.
|
||||
String mondrak = "Mondrak, Glory Dominus";
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.ALL,
|
||||
new CreateTokenEffect(new FoodToken(), 2),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
addCustomCardWithAbility("Token-maker", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, mondrak);
|
||||
addCard(Zone.BATTLEFIELD, playerA, angelOfJubilation);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bear Cub", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
||||
checkPlayableAbility("Can't activate Mondrak", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice", false);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "create two");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W/P}{W/P}, Sacrifice");
|
||||
setChoice(playerA, "Food Token", 2);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, mondrak, CounterType.INDESTRUCTIBLE, 1);
|
||||
assertPermanentCount(playerA, "Bear Cub", 2);
|
||||
assertPermanentCount(playerA, "Food Token", 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class BecomesColorEffectTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Ancient Kavu
|
||||
{3}{R}
|
||||
Creature — Kavu
|
||||
{2}: This creature becomes colorless until end of turn.
|
||||
Those with the ability to change their nature survived Phyrexia’s biological attacks. Everything else died.
|
||||
3/3
|
||||
*/
|
||||
String kavu = "Ancient Kavu";
|
||||
/*
|
||||
Alchor's Tomb
|
||||
{4}
|
||||
Artifact
|
||||
{2}, {T}: Target permanent you control becomes the color of your choice. (This effect lasts indefinitely.)
|
||||
*/
|
||||
String alchorsTomb = "Alchor's Tomb";
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testBecomesColorSource() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, kavu);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
|
||||
checkColor("Ancient Kavu is red", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}: {this}");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkColor("Ancient Kavu is colorless", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "C", true);
|
||||
checkColor("Ancient Kavu is red again", 2, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBecomesColorTarget() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, kavu);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, alchorsTomb);
|
||||
|
||||
checkColor("Ancient Kavu is red", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "R", true);
|
||||
// make Ancient Kavu green
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}: Target permanent", kavu);
|
||||
setChoice(playerA, "Green");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkColor("Ancient Kavu is green", 1, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||
checkColor("Ancient Kavu is still green the following turn", 2, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||
// activate Ancient Kavu's ability to override green color until end of turn
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}: {this}");
|
||||
checkColor("Ancient Kavu is colorless", 3, PhaseStep.POSTCOMBAT_MAIN, playerA, kavu, "C", true);
|
||||
// next turn it should be green again
|
||||
checkColor("Ancient Kavu is green again", 4, PhaseStep.PRECOMBAT_MAIN, playerA, kavu, "G", true);
|
||||
|
||||
setStopAt(4, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.ObjectColor;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.mageobject.PowerPredicate;
|
||||
import mage.filter.predicate.mageobject.ToughnessPredicate;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class BecomesCreatureEffectTest extends CardTestPlayerBase {
|
||||
/*
|
||||
Ambush Commander
|
||||
{3}{G}{G}
|
||||
Creature — Elf
|
||||
Forests you control are 1/1 green Elf creatures that are still lands.
|
||||
{1}{G}, Sacrifice an Elf: Target creature gets +3/+3 until end of turn.
|
||||
2/2
|
||||
*/
|
||||
String ambushCommander = "Ambush Commander";
|
||||
/*
|
||||
Dryad Arbor
|
||||
Land Creature — Forest Dryad
|
||||
1/1
|
||||
*/
|
||||
String dryadArbor = "Dryad Arbor";
|
||||
/*
|
||||
Frogify
|
||||
{1}{U}
|
||||
Enchantment — Aura
|
||||
Enchant creature
|
||||
Enchanted creature loses all abilities and is a blue Frog creature with base power and toughness 1/1.
|
||||
(It loses all other card types and creature types.)
|
||||
*/
|
||||
String frogify = "Frogify";
|
||||
@Test
|
||||
public void testBecomesCreatureAllEffect() {
|
||||
FilterPermanent filter = new FilterPermanent();
|
||||
filter.add(CardType.CREATURE.getPredicate());
|
||||
filter.add(SubType.ELF.getPredicate());
|
||||
filter.add(new PowerPredicate(ComparisonType.EQUAL_TO, 1));
|
||||
filter.add(new ToughnessPredicate(ComparisonType.EQUAL_TO, 1));
|
||||
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, dryadArbor);
|
||||
addCard(Zone.HAND, playerA, ambushCommander);
|
||||
|
||||
runCode("Check forests are not 1/1 Elves", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||
int numElves = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size();
|
||||
Assert.assertEquals("No 1/1 elves should be present", 0, numElves);
|
||||
});
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ambushCommander);
|
||||
runCode("Check forests are 1/1 Elves", 1, PhaseStep.BEGIN_COMBAT, playerA, (info, player, game) -> {
|
||||
int numElves = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size();
|
||||
// 5 forests + dryad arbor
|
||||
Assert.assertEquals("There should be 6 1/1 elves present", 6, numElves);
|
||||
});
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBecomesCreatureAttachedEffect() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, dryadArbor);
|
||||
addCard(Zone.HAND, playerA, frogify);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, frogify, dryadArbor);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAbilities(playerA, dryadArbor, Collections.emptyList());
|
||||
assertPowerToughness(playerA, dryadArbor, 1, 1);
|
||||
assertType(dryadArbor, CardType.CREATURE, SubType.FROG);
|
||||
assertNotSubtype(dryadArbor, SubType.DRYAD);
|
||||
assertNotType(dryadArbor, CardType.LAND);
|
||||
assertColor(playerA, dryadArbor, ObjectColor.BLUE, true);
|
||||
assertColor(playerA, dryadArbor, ObjectColor.GREEN, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package org.mage.test.cards.continuous;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class BecomesCreatureIfVehicleEffectTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Aerial Modification
|
||||
{4}{W}
|
||||
Enchantment — Aura
|
||||
Enchant creature or Vehicle
|
||||
As long as enchanted permanent is a Vehicle, it’s a creature in addition to its other types.
|
||||
Enchanted creature gets +2/+2 and has flying.
|
||||
*/
|
||||
String aerialMod = "Aerial Modification";
|
||||
/*
|
||||
Goliath Truck
|
||||
{4}
|
||||
Artifact — Vehicle
|
||||
Stowage — Whenever this Vehicle attacks, put two +1/+1 counters on another target attacking creature.
|
||||
Crew 2 (Tap any number of creatures you control with total power 2 or more: This Vehicle becomes an artifact creature until end of turn.)
|
||||
4/4
|
||||
*/
|
||||
String goliathTruck = "Goliath Truck";
|
||||
|
||||
@Test
|
||||
public void testBecomesCreatureIfVehicleEffect() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, goliathTruck);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
addCard(Zone.HAND, playerA, aerialMod);
|
||||
|
||||
checkType("Goliath Truck is not a creature", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goliathTruck, CardType.CREATURE, false);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aerialMod, goliathTruck);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertType(goliathTruck, CardType.CREATURE, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package org.mage.test.cards.continuous;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -22,7 +23,9 @@ public class OracleEnVecNextTurnTest extends CardTestPlayerBase {
|
|||
|
||||
// 1 - activate
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Target opponent", playerB);
|
||||
setChoice(playerB, "Balduvian Bears^Angelic Wall");
|
||||
setChoice(playerB, "Balduvian Bears");
|
||||
setChoice(playerB, "Angelic Wall");
|
||||
setChoice(playerB, TestPlayer.CHOICE_SKIP);
|
||||
//
|
||||
checkLife("turn 1", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, 20);
|
||||
checkPermanentCount("turn 1", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Balduvian Bears", 1);
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ public class TakeControlWhileSearchingLibraryTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Buried Alive");
|
||||
setChoice(playerB, true); // continue after new control
|
||||
addTarget(playerB, "Balduvian Bears");
|
||||
addTarget(playerB, TestPlayer.TARGET_SKIP);
|
||||
//addTarget(playerB, TestPlayer.TARGET_SKIP);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkGraveyardCount("after grave a", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 0);
|
||||
checkGraveyardCount("after grave b", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Balduvian Bears", 0);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ public class RemoveCounterCostTest extends CardTestPlayerBase {
|
|||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, Remove two +1/+1 counters");
|
||||
setChoice(playerA, "Novijen Sages"); // counters to remove
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
setChoice(playerA, "X=2"); // counters to remove
|
||||
|
||||
setStrictChooseMode(true);
|
||||
|
|
|
|||
|
|
@ -427,18 +427,20 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase {
|
|||
String savageBeating = "Savage Beating";
|
||||
|
||||
skipInitShuffling();
|
||||
addCard(Zone.LIBRARY, playerA, savageBeating, 2);
|
||||
addCard(Zone.LIBRARY, playerA, savageBeating, 2); // to free cast
|
||||
addCard(Zone.HAND, playerA, jeleva);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
|
||||
// prepare and exile cards from libs
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, jeleva);
|
||||
|
||||
// attack and use free cast from exile
|
||||
attack(3, playerA, jeleva);
|
||||
setChoice(playerA, true); // opt to use Jeleva ability
|
||||
setChoice(playerA, savageBeating); // choose to cast Savage Beating for free
|
||||
setChoice(playerA, false); // opt not to pay entwine cost
|
||||
setChoice(playerA, savageBeating); // to free cast
|
||||
setChoice(playerA, true); // confirm free cast
|
||||
setChoice(playerA, false); // ignore entwine cost
|
||||
setModeChoice(playerA, "1"); // use first mode of Savage Beating granting double strike
|
||||
|
||||
setStopAt(3, PhaseStep.END_COMBAT);
|
||||
|
|
@ -448,6 +450,5 @@ public class CastFromHandWithoutPayingManaCostTest extends CardTestPlayerBase {
|
|||
assertTapped(jeleva, true);
|
||||
assertLife(playerB, 18);
|
||||
assertAbility(playerA, jeleva, DoubleStrikeAbility.getInstance(), true);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ public class ModalDoubleFacedCardsTest extends CardTestPlayerBase {
|
|||
// cast as copy of mdf card
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Zam Wesell");
|
||||
addTarget(playerA, playerB); // target opponent
|
||||
addTarget(playerA, "Akoum Warrior"); // creature card to copy
|
||||
setChoice(playerA, "Akoum Warrior"); // creature card to copy
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import java.util.stream.Stream;
|
|||
*/
|
||||
public class DungeonTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String TOMB_OF_ANNIHILATION = "Tomb of Annihilation";
|
||||
private static final String TOMB_OF_ANNIHILATION = "Tomb of Annihilation"; // TODO: miss test
|
||||
private static final String LOST_MINE_OF_PHANDELVER = "Lost Mine of Phandelver";
|
||||
private static final String DUNGEON_OF_THE_MAD_MAGE = "Dungeon of the Mad Mage";
|
||||
private static final String FLAMESPEAKER_ADEPT = "Flamespeaker Adept";
|
||||
|
|
|
|||
|
|
@ -157,4 +157,29 @@ public class EmblemsTest extends CardTestPlayerBase {
|
|||
assertHandCount(playerA, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJayaFieryNegotiator() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Jaya, Fiery Negotiator");
|
||||
addCard(Zone.HAND, playerA, "Wrenn's Resolve");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||
addCard(Zone.LIBRARY, playerA, "Lightning Bolt", 2);
|
||||
skipInitShuffling();
|
||||
|
||||
addCounters(1, PhaseStep.UPKEEP, playerA, "Jaya, Fiery Negotiator", CounterType.LOYALTY, 6);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-8: You get an emblem");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wrenn's Resolve");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
setChoice(playerA, false, 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerA, 6 - 1);
|
||||
assertLife(playerB, 20 - 3 * 3);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package org.mage.test.cards.modal;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -25,7 +26,7 @@ public class OneOrBothTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Subtle Strike", "Pillarfield Ox");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, null);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
@ -47,7 +48,7 @@ public class OneOrBothTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Subtle Strike", "Pillarfield Ox");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, null);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import mage.game.permanent.Permanent;
|
|||
import mage.game.permanent.PermanentToken;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -39,7 +40,7 @@ public class OneOrMoreTest extends CardTestPlayerBase {
|
|||
addTarget(playerA, "Silvercoat Lion"); // for 3
|
||||
addTarget(playerA, "Silvercoat Lion"); // for 4
|
||||
addTarget(playerA, playerB); // for 5
|
||||
setModeChoice(playerA, null);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
@ -76,7 +77,7 @@ public class OneOrMoreTest extends CardTestPlayerBase {
|
|||
addTarget(playerA, "Silvercoat Lion"); // for 3
|
||||
addTarget(playerA, "Silvercoat Lion"); // for 4
|
||||
addTarget(playerA, playerB); // for 5
|
||||
setModeChoice(playerA, null);
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package org.mage.test.cards.modal;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -61,25 +63,17 @@ public class PawPrintsTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Season of Gathering");
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "3"); // Will be unused
|
||||
setModeChoice(playerA, "3"); // no more paws for mode 3, see exception below
|
||||
addTarget(playerA, "Memnite"); // for 1
|
||||
setChoice(playerA, "Enchantment");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
// Add one more counter from Hardened Scales, which was still on the battlefield when the counter placing effect triggered
|
||||
assertPowerToughness(playerA, "Memnite", 3, 3);
|
||||
assertCounterCount("Memnite", CounterType.P1P1, 2);
|
||||
|
||||
// But not anymore...
|
||||
assertPermanentCount(playerA, "Hardened Scales", 0);
|
||||
assertGraveyardCount(playerA, "Hardened Scales", 1);
|
||||
|
||||
// Draw effect didnt trigger
|
||||
assertHandCount(playerA, 0);
|
||||
|
||||
try {
|
||||
execute();
|
||||
} catch (AssertionError e) {
|
||||
Assert.assertTrue("mode 3 must not be able to choose due total paws cost", e.getMessage().contains("Can't use mode: 3"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -282,9 +282,9 @@ public class AttachmentTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Show and Tell");
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerB, false);
|
||||
setChoice(playerA, true); // yes, put from hand to battle
|
||||
addTarget(playerA, "Aether Tunnel");
|
||||
setChoice(playerB, false); // no, do not put
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package org.mage.test.cards.single._5ed;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AnHavvaConstableTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
An-Havva Constable
|
||||
{1}{G}{G}
|
||||
Creature — Human
|
||||
An-Havva Constable’s toughness is equal to 1 plus the number of green creatures on the battlefield.
|
||||
2/1+*
|
||||
*/
|
||||
private static final String constable = "An-Havva Constable";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature — Bear
|
||||
2/2
|
||||
*/
|
||||
private static final String cub = "Bear Cub";
|
||||
@Test
|
||||
public void testAnHavva() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, constable);
|
||||
addCard(Zone.HAND, playerA, constable);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, cub, 3);
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
|
||||
checkPT("An-Havva Constable has toughness 7", 1, PhaseStep.PRECOMBAT_MAIN, playerA, constable, 2, 1 + 6);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", cub);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPT("An-Havva Constable has toughness 6", 1, PhaseStep.PRECOMBAT_MAIN, playerA, constable, 2, 1 + 5);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
playerA.getHand().getCards(currentGame).stream()
|
||||
.filter(card -> card.getName().equals(constable))
|
||||
.findFirst().
|
||||
ifPresent(card -> Assert.assertEquals(6, card.getToughness().getValue()));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package org.mage.test.cards.single.acr;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AdrestiaTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Adrestia
|
||||
{3}
|
||||
Legendary Artifact — Vehicle
|
||||
|
||||
Islandwalk (This creature can’t be blocked as long as defending player controls an Island.)
|
||||
|
||||
Whenever Adrestia attacks, if an Assassin crewed it this turn, draw a card. Adrestia becomes an Assassin in addition to its other types until end of turn.
|
||||
|
||||
Crew 1
|
||||
*/
|
||||
private static final String adrestia = "Adrestia";
|
||||
/*
|
||||
Nekrataal
|
||||
{2}{B}{B}
|
||||
Creature — Human Assassin
|
||||
|
||||
First strike
|
||||
|
||||
When this creature enters, destroy target nonartifact, nonblack creature. That creature can’t be regenerated.
|
||||
|
||||
2/1
|
||||
*/
|
||||
private static final String nekrataal = "Nekrataal";
|
||||
|
||||
@Test
|
||||
public void testAdrestia() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, adrestia);
|
||||
addCard(Zone.BATTLEFIELD, playerA, nekrataal);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Crew");
|
||||
setChoice(playerA, nekrataal);
|
||||
attack(1, playerA, adrestia);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertSubtype(adrestia, SubType.VEHICLE);
|
||||
assertType(adrestia, CardType.CREATURE, true);
|
||||
assertType(adrestia, CardType.ARTIFACT, true);
|
||||
assertSubtype(adrestia, SubType.ASSASSIN);
|
||||
assertHandCount(playerA, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -50,6 +50,9 @@ public class MantleOfTheAncientsTest extends CardTestPlayerBase {
|
|||
addTarget(playerA, "Gate Smasher^Aether Tunnel");
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP);
|
||||
|
||||
|
||||
showBattlefield("after", 1, PhaseStep.END_TURN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -314,15 +314,14 @@ public class ShareTheSpoilsTest extends CardTestCommander4Players {
|
|||
// Cast an adventure card from hand
|
||||
castSpell(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Dizzying Swoop");
|
||||
addTarget(playerA, "Prosper, Tome-Bound");
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP); // tap 1 of 2 targets
|
||||
//addTarget(playerA, TestPlayer.TARGET_SKIP); // only 1 creature, so tap 1 of 2, no need in skip
|
||||
waitStackResolved(5, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// Make sure the creature card can't be played from exile since there isn't the {W}{W} for it
|
||||
checkPlayableAbility("creature cast", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Ardenvale Tactician", false);
|
||||
|
||||
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
// 1 exiled with Share the Spoils
|
||||
|
|
|
|||
|
|
@ -189,9 +189,9 @@ public class ApproachOfTheSecondSunTest extends CardTestPlayerBase {
|
|||
// first may have been cast from anywhere.
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Finale of Promise", true);
|
||||
setChoice(playerA, "X=7"); // each with mana value X or less
|
||||
addTarget(playerA, TARGET_SKIP); // skip instant target
|
||||
addTarget(playerA, "Approach of the Second Sun"); // use sorcery target
|
||||
setChoice(playerA, "Yes"); // You may cast
|
||||
addTarget(playerA, TARGET_SKIP); // up to one target instant card
|
||||
addTarget(playerA, "Approach of the Second Sun"); // and/or up to one target sorcery card from your graveyard
|
||||
checkLife("Approach of the Second Sun cast from graveyard gains life", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 27);
|
||||
checkLibraryCount("Approach of the Second Sun cast from graveyard goes to library",
|
||||
1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun", 1);
|
||||
|
|
@ -200,9 +200,9 @@ public class ApproachOfTheSecondSunTest extends CardTestPlayerBase {
|
|||
// The second Approach of the Second Sun that you cast must be cast from your hand,
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Finale of Promise", true);
|
||||
setChoice(playerA, "X=7"); // each with mana value X or less
|
||||
setChoice(playerA, "Yes"); // You may cast
|
||||
addTarget(playerA, TARGET_SKIP); // up to one target instant card
|
||||
addTarget(playerA, "Approach of the Second Sun"); // and/or up to one target sorcery card from your graveyard
|
||||
setChoice(playerA, "Yes"); // You may cast
|
||||
checkLife("Approach of the Second Sun cast from graveyard gains life", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 34);
|
||||
checkLibraryCount("Approach of the Second Sun cast from graveyard goes to library",
|
||||
1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun", 2);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
package org.mage.test.cards.single.avr;
|
||||
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class DarkImpostorTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Dark Impostor
|
||||
{2}{B}
|
||||
Creature — Vampire Assassin
|
||||
|
||||
{4}{B}{B}: Exile target creature and put a +1/+1 counter on this creature.
|
||||
|
||||
This creature has all activated abilities of all creature cards exiled with it.
|
||||
2/2
|
||||
*/
|
||||
public static final String darkImposter = "Dark Impostor";
|
||||
/*
|
||||
Deathrite Shaman
|
||||
{B/G}
|
||||
Creature — Elf Shaman
|
||||
|
||||
{T}: Exile target land card from a graveyard. Add one mana of any color.
|
||||
|
||||
{B}, {T}: Exile target instant or sorcery card from a graveyard. Each opponent loses 2 life.
|
||||
|
||||
{G}, {T}: Exile target creature card from a graveyard. You gain 2 life.
|
||||
|
||||
1/2
|
||||
*/
|
||||
public static final String deathriteShaman = "Deathrite Shaman";
|
||||
|
||||
@Test
|
||||
public void testDarkImpostor() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, darkImposter);
|
||||
addCard(Zone.BATTLEFIELD, playerA, deathriteShaman);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{B}{B}");
|
||||
addTarget(playerA, deathriteShaman);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAbilityCount(playerA, darkImposter, SimpleActivatedAbility.class, 4); // own ability + 3 other from deathrite
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ package org.mage.test.cards.single.bfz;
|
|||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -27,7 +28,7 @@ public class BrutalExpulsionTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brutal Expulsion", "mode=2Augmenting Automaton");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, null); // ignore last one mode
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP); // ignore last one mode
|
||||
//addTarget(playerA, "mode=2Augmenting Automaton"); // doesn't work with mode
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
|
|
@ -56,7 +57,7 @@ public class BrutalExpulsionTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brutal Expulsion", "mode=2Kiora, the Crashing Wave");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, null); // ignore last one mode
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP); // ignore last one mode
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
|
@ -116,7 +117,7 @@ public class BrutalExpulsionTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brutal Expulsion", "mode=2Gideon, Ally of Zendikar");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, null); // ignore last one mode
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP); // ignore last one mode
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shock", "Gideon, Ally of Zendikar");
|
||||
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package org.mage.test.cards.single.big;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class EsotericDuplicatorTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Esoteric Duplicator
|
||||
{2}{U}
|
||||
Artifact — Clue
|
||||
|
||||
Whenever you sacrifice this artifact or another artifact, you may pay {2}. If you do, at the beginning of the next end step, create a token that’s a copy of that artifact.
|
||||
|
||||
{2}, Sacrifice this artifact: Draw a card.
|
||||
*/
|
||||
private static final String esotericDuplicator = "Esoteric Duplicator";
|
||||
|
||||
/*
|
||||
Sculpting Steel
|
||||
{3}
|
||||
Artifact
|
||||
You may have Sculpting Steel enter the battlefield as a copy of any artifact on the battlefield.
|
||||
*/
|
||||
private static final String sculptingSteel = "Sculpting Steel";
|
||||
|
||||
@Test
|
||||
public void testEsotericDuplicator() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, esotericDuplicator);
|
||||
addCard(Zone.HAND, playerA, sculptingSteel);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 7);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sculptingSteel);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, esotericDuplicator);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, Sacrifice"); // Sacrifice duplicator
|
||||
setChoice(playerA, true); // duplicate
|
||||
|
||||
|
||||
setStopAt(2, PhaseStep.UPKEEP);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, esotericDuplicator, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package org.mage.test.cards.single.c13;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class ActOfAuthorityEffectTest extends CardTestPlayerBase {
|
||||
/*
|
||||
Act of Authority
|
||||
{1}{W}{W}
|
||||
Enchantment
|
||||
When this enchantment enters, you may exile target artifact or enchantment.
|
||||
At the beginning of your upkeep, you may exile target artifact or enchantment. If you do, its controller gains control of this enchantment.
|
||||
*/
|
||||
private static final String actOfAuthority = "Act of Authority";
|
||||
|
||||
@Test
|
||||
public void testActOfAuthority() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, actOfAuthority);
|
||||
addCard(Zone.BATTLEFIELD, playerB, actOfAuthority + "@actB");
|
||||
|
||||
setChoice(playerA, true); // upkeep
|
||||
addTarget(playerA, "@actB");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, actOfAuthority, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,8 +27,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
|
||||
// attack and cast first time (free)
|
||||
attack(1, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Grizzly Bears"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(1, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 1", 1, PhaseStep.COMBAT_DAMAGE, playerA, "Grizzly Bears", 1);
|
||||
checkPermanentTapped("after 1", 1, PhaseStep.COMBAT_DAMAGE, playerA, "Forest", true, 0);
|
||||
|
|
@ -40,8 +40,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 3 - second cast (1x tax)
|
||||
|
||||
attack(3, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Grizzly Bears"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(3, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 2", 3, PhaseStep.COMBAT_DAMAGE, playerA, "Grizzly Bears", 1);
|
||||
checkPermanentTapped("after 2", 3, PhaseStep.COMBAT_DAMAGE, playerA, "Forest", true, 2); // 1x tax
|
||||
|
|
@ -53,8 +53,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 5 - third cast (2x tax)
|
||||
|
||||
attack(5, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Grizzly Bears"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(5, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 3", 5, PhaseStep.COMBAT_DAMAGE, playerA, "Grizzly Bears", 1);
|
||||
checkPermanentTapped("after 3", 5, PhaseStep.COMBAT_DAMAGE, playerA, "Forest", true, 2 * 2); // 2x tax
|
||||
|
|
@ -85,8 +85,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
|
||||
// attack and cast first time (free)
|
||||
attack(1, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Akoum Warrior"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(1, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 1", 1, PhaseStep.COMBAT_DAMAGE, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentTapped("after 1", 1, PhaseStep.COMBAT_DAMAGE, playerA, "Mountain", true, 0);
|
||||
|
|
@ -98,8 +98,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 3 - second cast (1x tax)
|
||||
|
||||
attack(3, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Akoum Warrior"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(3, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 2", 3, PhaseStep.COMBAT_DAMAGE, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentTapped("after 2", 3, PhaseStep.COMBAT_DAMAGE, playerA, "Mountain", true, 2); // 1x tax
|
||||
|
|
@ -111,8 +111,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 5 - third cast (2x tax)
|
||||
|
||||
attack(5, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Akoum Warrior"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
waitStackResolved(5, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 3", 5, PhaseStep.COMBAT_DAMAGE, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentTapped("after 3", 5, PhaseStep.COMBAT_DAMAGE, playerA, "Mountain", true, 2 * 2); // 2x tax
|
||||
|
|
@ -144,8 +144,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
|
||||
// attack and cast first time (free)
|
||||
attack(1, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Birgi, God of Storytelling"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Cast Birgi, God of Storytelling"); // spell choice
|
||||
waitStackResolved(1, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 1", 1, PhaseStep.COMBAT_DAMAGE, playerA, "Birgi, God of Storytelling", 1);
|
||||
|
|
@ -158,8 +158,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 3 - second cast, LEFT side (1x tax)
|
||||
|
||||
attack(3, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Birgi, God of Storytelling"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Cast Birgi, God of Storytelling"); // spell choice
|
||||
waitStackResolved(3, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 2", 3, PhaseStep.COMBAT_DAMAGE, playerA, "Birgi, God of Storytelling", 1);
|
||||
|
|
@ -172,8 +172,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 5 - third cast, RIGHT side (2x tax)
|
||||
|
||||
attack(5, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Birgi, God of Storytelling"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Cast Harnfel, Horn of Bounty"); // spell choice
|
||||
waitStackResolved(5, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 3", 5, PhaseStep.COMBAT_DAMAGE, playerA, "Harnfel, Horn of Bounty", 1);
|
||||
|
|
@ -186,8 +186,8 @@ public class GeodeGolemTest extends CardTestCommanderDuelBase {
|
|||
// turn 7 - fourth cast, RIGHT side (3x tax)
|
||||
|
||||
attack(7, playerA, "Geode Golem");
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Birgi, God of Storytelling"); // commander choice
|
||||
setChoice(playerA, true); // cast commander
|
||||
setChoice(playerA, "Cast Harnfel, Horn of Bounty"); // spell choice
|
||||
waitStackResolved(7, PhaseStep.COMBAT_DAMAGE);
|
||||
checkPermanentCount("after 4", 7, PhaseStep.COMBAT_DAMAGE, playerA, "Harnfel, Horn of Bounty", 1);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
package org.mage.test.cards.single.c18;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author notgreat
|
||||
*/
|
||||
public class RavenousSlimeTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testRavenousSlime() {
|
||||
addCustomEffect_TargetDestroy(playerA);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Ravenous Slime");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Centaur Courser");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "target destroy", "Runeclaw Bear");
|
||||
checkPT("Ravenous Slime ate Runeclaw Bear", 1, PhaseStep.BEGIN_COMBAT, playerA, "Ravenous Slime", 3, 3);
|
||||
|
||||
attack(1, playerA, "Ravenous Slime");
|
||||
block(1, playerB, "Centaur Courser", "Ravenous Slime");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertExileCount(playerB, "Runeclaw Bear", 1);
|
||||
assertExileCount(playerB, "Centaur Courser", 1);
|
||||
assertGraveyardCount(playerA, "Ravenous Slime", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package org.mage.test.cards.single.clu;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
|
@ -6,6 +5,7 @@ import mage.constants.Zone;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -41,7 +41,6 @@ public class SludgeTitanTest extends CardTestPlayerBase {
|
|||
addCard(Zone.LIBRARY, playerA, divination, 5);
|
||||
|
||||
attack(1, playerA, titan, playerB);
|
||||
setChoice(playerA, playerA.CHOICE_SKIP);
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_BLOCKERS);
|
||||
execute();
|
||||
|
|
@ -49,29 +48,6 @@ public class SludgeTitanTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, divination, 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoValidChoiceInvalid() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, titan);
|
||||
addCard(Zone.LIBRARY, playerA, divination, 5);
|
||||
|
||||
attack(1, playerA, titan, playerB);
|
||||
setChoice(playerA, divination); // invalid, titan doesn't allow for choosing sorcery
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_BLOCKERS);
|
||||
|
||||
try {
|
||||
execute();
|
||||
Assert.fail("must throw exception on execute");
|
||||
} catch (Throwable e) {
|
||||
if (!e.getMessage().startsWith("Missing CHOICE def")) {
|
||||
Assert.fail("Unexpected exception " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatureOnly_ChooseNone() {
|
||||
setStrictChooseMode(true);
|
||||
|
|
@ -81,7 +57,7 @@ public class SludgeTitanTest extends CardTestPlayerBase {
|
|||
addCard(Zone.LIBRARY, playerA, piker, 5);
|
||||
|
||||
attack(1, playerA, titan, playerB);
|
||||
setChoice(playerA, playerA.CHOICE_SKIP);
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
setStopAt(1, PhaseStep.DECLARE_BLOCKERS);
|
||||
execute();
|
||||
|
|
@ -207,6 +183,8 @@ public class SludgeTitanTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, titan);
|
||||
addCard(Zone.LIBRARY, playerA, brownscale, 5);
|
||||
|
||||
// must able to select only 1 creature, so after first choice it must auto-finish
|
||||
// if you see miss choice here then something broken in TestPlayer's choose method
|
||||
attack(1, playerA, titan, playerB);
|
||||
setChoice(playerA, brownscale);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package org.mage.test.cards.single.dft;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AatchikEmeraldRadianTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Aatchik, Emerald Radian
|
||||
{3}{B}{B}{G}
|
||||
Legendary Creature — Insect Druid
|
||||
When Aatchik enters, create a 1/1 green Insect creature token for each artifact and/or creature card in your graveyard.
|
||||
Whenever another Insect you control dies, put a +1/+1 counter on Aatchik. Each opponent loses 1 life.
|
||||
3/3
|
||||
*/
|
||||
private static final String aatchik = "Aatchik, Emerald Radian";
|
||||
|
||||
/*
|
||||
Springheart Nantuko
|
||||
{1}{G}
|
||||
Enchantment Creature — Insect Monk
|
||||
Bestow {1}{G}
|
||||
Enchanted creature gets +1/+1.
|
||||
Landfall — Whenever a land you control enters, you may pay {1}{G} if this permanent is attached to a creature you control.
|
||||
If you do, create a token that’s a copy of that creature. If you didn’t create a token this way, create a 1/1 green Insect creature token.
|
||||
1/1
|
||||
*/
|
||||
private static final String nantuko = "Springheart Nantuko";
|
||||
|
||||
@Test
|
||||
public void testOpponentCreatingTokens() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aatchik);
|
||||
addCard(Zone.BATTLEFIELD, playerB, aatchik);
|
||||
addCard(Zone.GRAVEYARD, playerA, aatchik);
|
||||
addCard(Zone.GRAVEYARD, playerB, aatchik);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bayou", 9);
|
||||
addCard(Zone.HAND, playerA, nantuko);
|
||||
addCard(Zone.HAND, playerA, "Bayou");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nantuko + " using bestow");
|
||||
addTarget(playerA, aatchik);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bayou");
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, aatchik);
|
||||
setChoice(playerA, "When {this} enters");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertTokenCount(playerB, "Insect Token", 0);
|
||||
assertTokenCount(playerA, "Insect Token", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package org.mage.test.cards.single.dis;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.UntapAllControllerEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ExperimentKrajTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Experiment Kraj
|
||||
{2}{G}{G}{U}{U}
|
||||
Legendary Creature — Ooze Mutant
|
||||
|
||||
Experiment Kraj has all activated abilities of each other creature with a +1/+1 counter on it.
|
||||
|
||||
{T}: Put a +1/+1 counter on target creature.
|
||||
*/
|
||||
private static final String experimentKraj = "Experiment Kraj";
|
||||
/*
|
||||
Stoneforge Mystic
|
||||
{1}{W}
|
||||
Creature — Kor Artificer
|
||||
|
||||
When this creature enters, you may search your library for an Equipment card, reveal it, put it into your hand, then shuffle.
|
||||
|
||||
{1}{W}, {T}: You may put an Equipment card from your hand onto the battlefield.
|
||||
*/
|
||||
private static final String stoneforgeMystic = "Stoneforge Mystic";
|
||||
/*
|
||||
Noble Hierarch
|
||||
{G}
|
||||
Creature — Human Druid
|
||||
|
||||
Exalted (Whenever a creature you control attacks alone, that creature gets +1/+1 until end of turn.)
|
||||
|
||||
{T}: Add {G}, {W}, or {U}.
|
||||
*/
|
||||
private static final String nobleHierarch = "Noble Hierarch";
|
||||
|
||||
@Test
|
||||
public void testExperimentKraj() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.ALL,
|
||||
new UntapAllControllerEffect(StaticFilters.FILTER_CONTROLLED_A_CREATURE),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
addCustomCardWithAbility("Untap creatures", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, experimentKraj);
|
||||
addCard(Zone.BATTLEFIELD, playerA, stoneforgeMystic);
|
||||
addCard(Zone.BATTLEFIELD, playerB, nobleHierarch);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Put a +1/+1", stoneforgeMystic);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Put a +1/+1", nobleHierarch);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertEquals("Kraj should have 5 activated abilities", 5, getPermanent(experimentKraj).getAbilities(currentGame)
|
||||
.stream()
|
||||
.filter(Ability::isActivatedAbility)
|
||||
.count());
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package org.mage.test.cards.single.dmu;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -76,4 +75,26 @@ public class KarnsSylexTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20 - 3);
|
||||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that it does not work with mana abilities, e.g. Thran Portal, with Yasharn, Implacable Earth.
|
||||
*/
|
||||
@Test
|
||||
public void blockedManaAbilitiesWithYasharn() {
|
||||
addCard(Zone.HAND, playerA, "Thran Portal");
|
||||
addCard(Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Zone.BATTLEFIELD, playerA, karnsSylex);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Yasharn, Implacable Earth");
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thran Portal");
|
||||
setChoice(playerA, "Thran");
|
||||
setChoice(playerA, "Mountain");
|
||||
|
||||
checkPlayableAbility("restricted by Yasharn", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Lightning Bolt", false);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import mage.constants.Zone;
|
|||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.t.ThranPortal Thran Portal}
|
||||
* Land Gate
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
package org.mage.test.cards.single.dsk;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class UnidentifiedHovershipTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Unidentified Hovership
|
||||
{1}{W}{W}
|
||||
Artifact - Vehicle
|
||||
Flying
|
||||
When this Vehicle enters, exile up to one target creature with toughness 5 or less.
|
||||
When this Vehicle leaves the battlefield, the exiled card's owner manifests dread.
|
||||
Crew 1
|
||||
2/2
|
||||
*/
|
||||
private static final String unidentifiedHovership = "Unidentified Hovership";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Naturalize
|
||||
{1}{G}
|
||||
Instant
|
||||
Destroy target artifact or enchantment.
|
||||
*/
|
||||
private static final String naturalize = "Naturalize";
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedHovership() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, unidentifiedHovership);
|
||||
addCard(Zone.HAND, playerB, naturalize);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Forest", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, unidentifiedHovership);
|
||||
addTarget(playerA, bearCub);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, naturalize, unidentifiedHovership);
|
||||
setChoice(playerB, "Mountain");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, 2 + 1); // forests + face down
|
||||
assertGraveyardCount(playerA, unidentifiedHovership, 1);
|
||||
assertGraveyardCount(playerB, 1 + 1); // naturalize + manifest
|
||||
assertExileCount(playerB, bearCub, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ public class TamiyoFieldResearcherTest extends CardTestPlayerBase {
|
|||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
|
||||
addTarget(playerA, "Bronze Sable");
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP);
|
||||
//addTarget(playerA, TestPlayer.TARGET_SKIP); // there are only 1 creature, so choose 1 of 2, no need in skip
|
||||
|
||||
attack(1, playerA, "Bronze Sable");
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ public class TamiyoFieldResearcherTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tamiyo, Field Researcher", true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Choose up to two");
|
||||
addTarget(playerA, "Bronze Sable");
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP);
|
||||
//addTarget(playerA, TestPlayer.TARGET_SKIP); // there are only 1 creature, so choose 1 of 2, no need in skip
|
||||
|
||||
attack(2, playerB, "Bronze Sable");
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package org.mage.test.cards.single.fic;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.UntapAllControllerEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class UriangerAugureltTest extends CardTestPlayerBase {
|
||||
|
||||
private static final String urianger = "Urianger Augurelt";
|
||||
private static final String arcaneSignet = "Arcane Signet";
|
||||
private static final String howlingMine = "Howling Mine";
|
||||
private static final String thoughtVessel = "Thought Vessel";
|
||||
private static final String benalishKnight = "Benalish Knight";
|
||||
|
||||
@Test
|
||||
public void uriangerAugureltTest() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
Zone.ALL,
|
||||
new UntapAllControllerEffect(StaticFilters.FILTER_CONTROLLED_A_CREATURE),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
addCustomCardWithAbility("Untap creatures", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, urianger);
|
||||
addCard(Zone.LIBRARY, playerA, "Plains", 3);
|
||||
addCard(Zone.LIBRARY, playerA, arcaneSignet);
|
||||
addCard(Zone.LIBRARY, playerA, howlingMine);
|
||||
addCard(Zone.LIBRARY, playerA, thoughtVessel);
|
||||
addCard(Zone.LIBRARY, playerA, benalishKnight);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||
setChoice(playerA, true, 4);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Draw Arcanum</i>");
|
||||
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "<i>Play Arcanum</i>");
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
playLand(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Plains");
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, benalishKnight, true);
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, arcaneSignet, true);
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, howlingMine, true);
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, thoughtVessel, true);
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, benalishKnight, 1);
|
||||
assertPermanentCount(playerA, arcaneSignet, 1);
|
||||
assertPermanentCount(playerA, howlingMine, 1);
|
||||
assertPermanentCount(playerA, thoughtVessel, 1);
|
||||
assertLife(playerA, 20 + 2 * 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package org.mage.test.cards.single.fin;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AettirAndPriwenTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Aettir and Priwen
|
||||
{6}
|
||||
Legendary Artifact — Equipment
|
||||
Equipped creature has base power and toughness X/X, where X is your life total.
|
||||
Equip {5}
|
||||
*/
|
||||
private static final String aettir = "Aettir and Priwen";
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature — Bear
|
||||
2/2
|
||||
*/
|
||||
private static final String cub = "Bear Cub";
|
||||
/*
|
||||
Lightning Bolt
|
||||
{R}
|
||||
Instant
|
||||
Lightning Bolt deals 3 damage to any target.
|
||||
*/
|
||||
public static final String bolt = "Lightning Bolt";
|
||||
|
||||
@Test
|
||||
public void testAettirAndPriwen() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, aettir);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 7);
|
||||
addCard(Zone.HAND, playerA, bolt, 2);
|
||||
|
||||
checkPowerToughness(2, cub, 1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{5}: Equip");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPowerToughness(20, cub, 1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bolt, playerA);
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
checkPowerToughness(20 - 3, cub, 1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bolt, playerA);
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
checkPowerToughness(20 - 3 * 2, cub, 1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
|
||||
checkPowerToughness(20 - 3 * 2, cub, 2, PhaseStep.PRECOMBAT_MAIN);
|
||||
}
|
||||
|
||||
void checkPowerToughness(int xValue, String name, int turnNum, PhaseStep phaseStep) {
|
||||
runCode("Checking P/T is " + xValue, turnNum, phaseStep, playerA, (info, player, game) -> {
|
||||
Permanent permanent = getPermanent(name, player);
|
||||
Assert.assertEquals(xValue, permanent.getPower().getModifiedBaseValue());
|
||||
Assert.assertEquals(xValue, permanent.getToughness().getModifiedBaseValue());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package org.mage.test.cards.single.fin;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class GarnetPrincessOfAlexandriaTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_Targets_0() {
|
||||
// 2/2
|
||||
// Whenever Garnet attacks, you may remove a lore counter from each of any number of Sagas you control.
|
||||
// Put a +1/+1 counter on Garnet for each lore counter removed this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Garnet, Princess of Alexandria");
|
||||
|
||||
// nothing to select after attack
|
||||
attack(1, playerA, "Garnet, Princess of Alexandria", playerB);
|
||||
//setChoice(playerA, TestPlayer.CHOICE_SKIP); // no valid choices, so do not show choose dialog
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 20 - 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Targets_1() {
|
||||
// 2/2
|
||||
// Whenever Garnet attacks, you may remove a lore counter from each of any number of Sagas you control.
|
||||
// Put a +1/+1 counter on Garnet for each lore counter removed this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Garnet, Princess of Alexandria");
|
||||
//
|
||||
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)
|
||||
// I, II, III, IV -- Stampede! -- Other creatures you control get +1/+0 until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Summon: Choco/Mog"); // {2}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
|
||||
// prepare x1 saga
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summon: Choco/Mog");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// can select 1 target only
|
||||
attack(1, playerA, "Garnet, Princess of Alexandria", playerB);
|
||||
setChoice(playerA, "Summon: Choco/Mog");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
// 2/2 attack + 1/1 saga's boost + 1/0 counter remove boost
|
||||
assertCounterCount(playerA, "Summon: Choco/Mog", CounterType.LORE, 0);
|
||||
assertLife(playerB, 20 - 2 - 1 - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Targets_2() {
|
||||
// 2/2
|
||||
// Whenever Garnet attacks, you may remove a lore counter from each of any number of Sagas you control.
|
||||
// Put a +1/+1 counter on Garnet for each lore counter removed this way.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Garnet, Princess of Alexandria");
|
||||
//
|
||||
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after IV.)
|
||||
// I, II, III, IV -- Stampede! -- Other creatures you control get +1/+0 until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Summon: Choco/Mog", 2); // {2}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3 * 2);
|
||||
|
||||
// prepare x2 sagas
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summon: Choco/Mog");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Summon: Choco/Mog");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
// can select 2 targets
|
||||
attack(1, playerA, "Garnet, Princess of Alexandria", playerB);
|
||||
setChoice(playerA, "Summon: Choco/Mog", 2); // x2 targets
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
// 2/2 attack + x2 1/1 saga's boost + x2 1/0 counter remove boost
|
||||
assertCounterCount(playerA, "Summon: Choco/Mog", CounterType.LORE, 0);
|
||||
assertLife(playerB, 20 - 2 - 2 - 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,13 +27,13 @@ public class WandOfVertebraeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, wandOfVertebrae);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.GRAVEYARD, playerA, lavaCoil);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears", 10);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}, {T}");
|
||||
addTarget(playerA, lavaCoil);
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP); // must choose 1 of 5
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ public class DiluvianPrimordialTest extends CardTestPlayerBase {
|
|||
*/
|
||||
private static final String primordial = "Diluvian Primordial";
|
||||
|
||||
// Bug: NPE on casting Valakut Awakening
|
||||
@Test
|
||||
public void test_MDFC() {
|
||||
// possible bug: NPE on casting Valakut Awakening
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, primordial);
|
||||
|
|
@ -32,7 +32,7 @@ public class DiluvianPrimordialTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, primordial);
|
||||
addTarget(playerA, "Valakut Awakening");
|
||||
setChoice(playerA, true); // Yes to "You may"
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP); // No choice for Awakening's effect
|
||||
//setChoice(playerA, TestPlayer.CHOICE_SKIP); // no need in skip, cause no valid choices for Awakening's effect
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
package org.mage.test.cards.single.kld;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class AnimationModuleTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Animation Module
|
||||
{1}
|
||||
Artifact
|
||||
|
||||
Whenever one or more +1/+1 counters are put on a permanent you control, you may pay {1}. If you do, create a 1/1 colorless Servo artifact creature token.
|
||||
|
||||
{3}, {T}: Choose a counter on target permanent or player. Give that permanent or player another counter of that kind.
|
||||
*/
|
||||
private static final String animationModule = "Animation Module";
|
||||
|
||||
@Test
|
||||
public void testGivePermanentCounter() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new AddCountersTargetEffect(CounterType.P1P1.createInstance()),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
ability.addTarget(new TargetPermanentOrPlayer(1));
|
||||
addCustomCardWithAbility("add counter", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, animationModule);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 10);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "put", animationModule);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
setChoice(playerA, true); //pay to create servo
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Choose a counter", animationModule);
|
||||
setChoice(playerA, true); //pay to create servo
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, animationModule, CounterType.P1P1, 2);
|
||||
assertPermanentCount(playerA, "Servo Token", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGivePlayerCounter() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
Ability ability = new SimpleActivatedAbility(
|
||||
new AddCountersTargetEffect(CounterType.ENERGY.createInstance()),
|
||||
new ManaCostsImpl<>("")
|
||||
);
|
||||
ability.addTarget(new TargetPermanentOrPlayer(1));
|
||||
addCustomCardWithAbility("add counter", playerA, ability);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, animationModule);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 10);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "put", playerA);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{3}, {T}: Choose a counter", playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, CounterType.ENERGY, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import mage.constants.PhaseStep;
|
|||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -32,9 +33,10 @@ public class RipplesOfPotentialTest extends CardTestPlayerBase {
|
|||
setChoice(playerA, "Blast Zone^Arcbound Javelineer^Chandra, Pyromaster^Atraxa's Skitterfang");
|
||||
// Phase out choice
|
||||
setChoice(playerA, "Blast Zone^Arcbound Javelineer^Chandra, Pyromaster");
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP); // keep Atraxa's Skitterfang
|
||||
setChoice(playerA, false); // Atraxa's Skitterfang ability - do not remove oil
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setChoice(playerA, false); // Atraxa's Skitterfang ability
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
package org.mage.test.cards.single.lci;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AbuelosAwakeningTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Abuelo's Awakening
|
||||
{X}{3}{W}
|
||||
Sorcery
|
||||
Return target artifact or non-Aura enchantment card from your graveyard to the battlefield with X additional +1/+1 counters on it.
|
||||
It’s a 1/1 Spirit creature with flying in addition to its other types.
|
||||
*/
|
||||
public static final String abuelosAwakening = "Abuelo's Awakening";
|
||||
/*
|
||||
Talisman of Progress
|
||||
{2}
|
||||
Artifact
|
||||
{T}: Add {C}.
|
||||
{T}: Add {W} or {U}. This artifact deals 1 damage to you.
|
||||
*/
|
||||
public static final String talisman = "Talisman of Progress";
|
||||
/*
|
||||
Lightning Bolt
|
||||
{R}
|
||||
Instant
|
||||
Lightning Bolt deals 3 damage to any target.
|
||||
*/
|
||||
public static final String bolt = "Lightning Bolt";
|
||||
|
||||
@Test
|
||||
public void testAbuelosAwakening() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, talisman);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||
addCard(Zone.HAND, playerA, abuelosAwakening);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, abuelosAwakening, talisman);
|
||||
setChoiceAmount(playerA, 2);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, talisman, CounterType.P1P1, 2);
|
||||
assertType(talisman, CardType.CREATURE, true);
|
||||
assertSubtype(talisman, SubType.SPIRIT);
|
||||
assertBasePowerToughness(playerA, talisman, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbuelosAwakeningDies() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, talisman);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||
addCard(Zone.HAND, playerA, abuelosAwakening);
|
||||
addCard(Zone.HAND, playerB, bolt);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, abuelosAwakening, talisman);
|
||||
setChoiceAmount(playerA, 2);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, bolt, talisman);
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, talisman, 0);
|
||||
assertGraveyardCount(playerA, talisman, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package org.mage.test.cards.single.lci;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class DireBlunderbussTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Dire Blunderbuss
|
||||
Color Indicator: RedArtifact — Equipment
|
||||
|
||||
Equipped creature gets +3/+0 and has “Whenever this creature attacks, you may sacrifice an artifact other than Dire Blunderbuss. When you do, this creature deals damage equal to its power to target creature.”
|
||||
|
||||
Equip {1}
|
||||
*/
|
||||
private static final String direBlunderBuss = "Dire Blunderbuss";
|
||||
|
||||
@Test
|
||||
public void DireBlunderbussTest() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, direBlunderBuss);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears@bearsB");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tormod's Crypt");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Balduvian Bears");
|
||||
|
||||
attack(1, playerA, "Balduvian Bears");
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, "Tormod's Crypt");
|
||||
addTarget(playerA, "@bearsB");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Balduvian Bears", 1);
|
||||
assertLife(playerB, 20 - 2 - 3);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package org.mage.test.cards.single.lci;
|
||||
|
||||
import mage.ObjectColor;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class EatenByPiranhasTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Eaten by Piranhas
|
||||
{1}{U}
|
||||
Enchantment — Aura
|
||||
|
||||
Flash (You may cast this spell any time you could cast an instant.)
|
||||
|
||||
Enchant creature
|
||||
|
||||
Enchanted creature loses all abilities and is a black Skeleton creature with base power and toughness 1/1. (It loses all other colors, card types, and creature types.)
|
||||
*/
|
||||
private static final String eatenByPiranhas = "Eaten by Piranhas";
|
||||
|
||||
@Test
|
||||
public void testEatenByPiranhas() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.HAND, playerB, eatenByPiranhas);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, eatenByPiranhas);
|
||||
addTarget(playerB, "Balduvian Bears");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertType("Balduvian Bears", CardType.CREATURE, SubType.SKELETON);
|
||||
assertPowerToughness(playerA, "Balduvian Bears", 1, 1);
|
||||
assertColor(playerA, "Balduvian Bears", ObjectColor.BLACK, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package org.mage.test.cards.single.leg;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AlAbarasCarpetTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Al-abara's Carpet
|
||||
{5}
|
||||
Artifact
|
||||
|
||||
{5}, {T}: Prevent all damage that would be dealt to you this turn by attacking creatures without flying.
|
||||
*/
|
||||
private static final String alabarasCarpet = "Al-abara's Carpet";
|
||||
|
||||
/*
|
||||
Storm Crow
|
||||
{1}{U}
|
||||
Creature — Bird
|
||||
|
||||
Flying (This creature can’t be blocked except by creatures with flying or reach.)
|
||||
|
||||
1/2
|
||||
*/
|
||||
private static final String stormCrow = "Storm Crow";
|
||||
/*
|
||||
Balduvian Bears
|
||||
{1}{G}
|
||||
Creature — Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String balduvianBears = "Balduvian Bears";
|
||||
@Test
|
||||
public void testCarpet() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, alabarasCarpet);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerB, balduvianBears);
|
||||
addCard(Zone.BATTLEFIELD, playerB, stormCrow);
|
||||
|
||||
attack(2, playerB, balduvianBears);
|
||||
attack(2, playerB, stormCrow);
|
||||
activateAbility(2, PhaseStep.DECLARE_ATTACKERS, playerA, "{5}, {T}");
|
||||
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package org.mage.test.cards.single.ltr;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
||||
public class BreakingOfTheFellowshipTest extends CardTestPlayerBaseWithAIHelps {
|
||||
|
||||
@Test
|
||||
public void test_PossibleTargets() {
|
||||
// Target creature an opponent controls deals damage equal to its power to another target creature that player controls.
|
||||
addCard(Zone.HAND, playerA, "Breaking of the Fellowship"); // {1}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
//
|
||||
addCard(Zone.HAND, playerB, "Grizzly Bears"); // 2/2, {1}{G}
|
||||
addCard(Zone.HAND, playerB, "Spectral Bears"); // 3/3, {1}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Forest", 2 * 2);
|
||||
|
||||
// turn 1 - no targets, can't play
|
||||
checkPlayableAbility("no targets - can't cast", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Breaking of the Fellowship", false);
|
||||
|
||||
// turn 3 - 1 of 2 targets, can't play
|
||||
castSpell(3 - 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Grizzly Bears");
|
||||
checkPlayableAbility("1 of 2 targets - can't cast", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Breaking of the Fellowship", false);
|
||||
|
||||
// turn 5 - 2 of 2 targets, can play
|
||||
castSpell(5 - 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Spectral Bears");
|
||||
checkPlayableAbility("2 of 2 targets - can cast", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Breaking of the Fellowship", true);
|
||||
|
||||
castSpell(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Breaking of the Fellowship", "Grizzly Bears^Spectral Bears");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(5, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertDamageReceived(playerB, "Spectral Bears", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Normal_AI() {
|
||||
// Target creature an opponent controls deals damage equal to its power to another target creature that player controls.
|
||||
addCard(Zone.HAND, playerA, "Breaking of the Fellowship"); // {1}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); // 2/2
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spectral Bears"); // 3/3
|
||||
|
||||
// AI must choose 3/3 to kill 2/2
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Grizzly Bears", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Protection_AI() {
|
||||
// Target creature an opponent controls deals damage equal to its power to another target creature that player controls.
|
||||
addCard(Zone.HAND, playerA, "Breaking of the Fellowship"); // {1}{R}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); // 2/2
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Spectral Bears"); // 3/3
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Lavinia of the Tenth"); // 4/4, Protection from red
|
||||
|
||||
// can't choose 4/4 to kill 3/3 due protection from red
|
||||
// AI must choose 3/3 to kill 2/2
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, "Grizzly Bears", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package org.mage.test.cards.single.ltr;
|
|||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
|
@ -29,14 +30,16 @@ public class GlamdringTest extends CardTestPlayerBase {
|
|||
|
||||
attack(1, playerA, "Blur Sliver");
|
||||
setChoice(playerA, "In Garruk's Wake"); // 9 mana, so we shouldn't be able to choose it
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
try {
|
||||
setStopAt(1, PhaseStep.FIRST_COMBAT_DAMAGE);
|
||||
execute();
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
assert(e.getMessage().contains("Missing CHOICE def for turn 1, step FIRST_COMBAT_DAMAGE, PlayerA"));
|
||||
Assert.assertTrue(
|
||||
"catch wrong exception: " + e.getMessage(),
|
||||
e.getMessage().contains("Found wrong choice command") && e.getMessage().contains("In Garruk's Wake")
|
||||
);
|
||||
return;
|
||||
}
|
||||
fail("Was able to pick [[In Garruk's Wake]] but it costs more than 2");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package org.mage.test.cards.single.m19;
|
||||
|
||||
import mage.abilities.mana.AnyColorManaAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AlpineMoonTest extends CardTestPlayerBase {
|
||||
/*
|
||||
Alpine Moon
|
||||
{R}
|
||||
Enchantment
|
||||
As this enchantment enters, choose a nonbasic land card name.
|
||||
Lands your opponents control with the chosen name lose all land types and abilities, and they gain “{T}: Add one mana of any color.”
|
||||
*/
|
||||
private static final String alpine = "Alpine Moon";
|
||||
/*
|
||||
Urborg, Tomb of Yawgmoth
|
||||
Legendary Land
|
||||
Each land is a Swamp in addition to its other land types.
|
||||
*/
|
||||
private static final String urborg = "Urborg, Tomb of Yawgmoth";
|
||||
|
||||
@Test
|
||||
public void testAlpineMoonAfterUrborg() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, urborg);
|
||||
addCard(Zone.BATTLEFIELD, playerB, alpine);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
|
||||
setChoice(playerB, urborg);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertNotSubtype(urborg, SubType.SWAMP);
|
||||
assertSubtype("Mountain", SubType.SWAMP);
|
||||
assertSubtype("Island", SubType.SWAMP);
|
||||
assertAbility(playerA, urborg, new AnyColorManaAbility(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlpineMoonBeforeUrborg() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerB, urborg);
|
||||
addCard(Zone.BATTLEFIELD, playerA, alpine);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
|
||||
setChoice(playerA, urborg);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertNotSubtype(urborg, SubType.SWAMP);
|
||||
assertSubtype("Mountain", SubType.SWAMP);
|
||||
assertSubtype("Island", SubType.SWAMP);
|
||||
assertAbility(playerB, urborg, new AnyColorManaAbility(), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,14 @@ public class EnthrallingHoldTest extends CardTestPlayerBase {
|
|||
@Test
|
||||
public void testTappedTarget_untapped_doesNotFizzle() {
|
||||
// Traxos, Scourge of Kroog enters the battlefield tapped and doesn't untap during your untap step.
|
||||
|
||||
// The middle ability of Enthralling Hold affects only the choice of target as the spell is cast.
|
||||
// If the creature becomes untapped before the spell resolves, it still resolves. If a player is
|
||||
// allowed to change the spell's target while it's on the stack, they may choose an untapped
|
||||
// creature. If you put Enthralling Hold onto the battlefield without casting it, you may attach
|
||||
// it to an untapped creature.
|
||||
// (2020-06-23)
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Traxos, Scourge of Kroog");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
|
||||
|
|
@ -26,10 +34,11 @@ public class EnthrallingHoldTest extends CardTestPlayerBase {
|
|||
*/
|
||||
addCard(Zone.HAND, playerA, "Twiddle");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enthralling Hold", "Traxos, Scourge of Kroog");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Twiddle", "Traxos, Scourge of Kroog");
|
||||
|
||||
setChoice(playerA, true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Enthralling Hold");
|
||||
addTarget(playerA, "Traxos, Scourge of Kroog");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Twiddle");
|
||||
addTarget(playerA, "Traxos, Scourge of Kroog");
|
||||
setChoice(playerA, true); // untap traxos
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@ public class BarrowgoyfTest extends CardTestPlayerBase {
|
|||
|
||||
attack(1, playerA, barrowgoyf, playerB);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP); // decide to not return. There was no choice anyway.
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
package org.mage.test.cards.single.mat;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
/**
|
||||
* @author correl
|
||||
*/
|
||||
public class NahiriForgedInFuryTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* {@link mage.cards.n.NahiriForgedInFury} {4}{R}{W}
|
||||
* Legendary Creature - Kor Artificer
|
||||
*
|
||||
* Affinity for Equipment
|
||||
*
|
||||
* Whenever an equipped creature you control attacks, exile the top card of
|
||||
* your library. You may play that card this turn. You may cast Equipment
|
||||
* spells this way without paying their mana costs.
|
||||
*/
|
||||
private static final String nahiri = "Nahiri, Forged in Fury";
|
||||
|
||||
private final String boots = "Swiftfoot Boots";
|
||||
private final String cleaver = "The Reaver Cleaver";
|
||||
private final String giant = "Hill Giant";
|
||||
private final String greaves = "Lightning Greaves";
|
||||
private final String lions = "Savannah Lions";
|
||||
private final String sword = "Sword of Feast and Famine";
|
||||
|
||||
@Test
|
||||
public void test_CostReducedByEquipment() {
|
||||
// Nahiri in hand, four equipment in play, and enough to pay RW
|
||||
addCard(Zone.HAND, playerA, nahiri);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, boots);
|
||||
addCard(Zone.BATTLEFIELD, playerA, cleaver);
|
||||
addCard(Zone.BATTLEFIELD, playerA, greaves);
|
||||
addCard(Zone.BATTLEFIELD, playerA, sword);
|
||||
|
||||
// Cast for RW (Reduced by 4)
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nahiri);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_EquippedAttackTriggers() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
addCard(Zone.BATTLEFIELD, playerA, lions);
|
||||
addCard(Zone.BATTLEFIELD, playerA, giant);
|
||||
addCard(Zone.BATTLEFIELD, playerA, boots);
|
||||
addCard(Zone.BATTLEFIELD, playerA, greaves);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {0}", lions);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {1}", giant);
|
||||
|
||||
// Attack with three creatures, two of which are equipped
|
||||
attack(1, playerA, nahiri);
|
||||
attack(1, playerA, lions);
|
||||
attack(1, playerA, giant);
|
||||
|
||||
// Order the 2 Nahiri triggers
|
||||
setChoice(playerA, "Whenever an equipped creature you control attacks");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
// Triggered twice, exiling two cards
|
||||
assertExileCount(playerA, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CanCastExiledEquipmentForFree() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, nahiri);
|
||||
addCard(Zone.BATTLEFIELD, playerA, greaves);
|
||||
skipInitShuffling();
|
||||
addCard(Zone.LIBRARY, playerA, sword);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {0}", nahiri);
|
||||
|
||||
// Attack with one equipped creature, exiling the sword
|
||||
attack(1, playerA, nahiri);
|
||||
|
||||
// Cast sword for free
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, sword);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(2, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package org.mage.test.cards.single.mh2;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentToken;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class AeveProgenitorOozeTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Aeve, Progenitor Ooze
|
||||
{2}{G}{G}{G}
|
||||
Legendary Creature — Ooze
|
||||
Storm (When you cast this spell, copy it for each spell cast before it this turn. Copies become tokens.)
|
||||
Aeve isn’t legendary if it’s a token.
|
||||
Aeve enters with a +1/+1 counter on it for each other Ooze you control.
|
||||
2/2
|
||||
*/
|
||||
private static final String aeve = "Aeve, Progenitor Ooze";
|
||||
/*
|
||||
Lightning Bolt
|
||||
{R}
|
||||
Instant
|
||||
Lightning Bolt deals 3 damage to any target.
|
||||
*/
|
||||
public static final String bolt = "Lightning Bolt";
|
||||
|
||||
@Test
|
||||
public void testAeve() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.HAND, playerA, aeve);
|
||||
addCard(Zone.HAND, playerA, bolt);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, playerB);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aeve);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, aeve, 2);
|
||||
assertTokenCount(playerA, aeve, 1);
|
||||
for (Permanent permanent : currentGame.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, playerA.getId(), currentGame)) {
|
||||
if (permanent.getName().equals(aeve)) {
|
||||
if (permanent instanceof PermanentToken) {
|
||||
Assert.assertEquals(0, permanent.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
} else {
|
||||
Assert.assertEquals(1, permanent.getCounters(currentGame).getCount(CounterType.P1P1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import mage.counters.CounterType;
|
|||
import mage.players.Player;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -82,6 +83,7 @@ public class IzzetGeneratoriumTest extends CardTestPlayerBase {
|
|||
checkPlayableAbility("1: condition not met before losing counters", 2, PhaseStep.UPKEEP, playerA, "{T}: Draw", false);
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Final Act");
|
||||
setModeChoice(playerB, "5"); // each opponent loses all counters.
|
||||
setModeChoice(playerB, TestPlayer.MODE_SKIP);
|
||||
waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
runCode("energy counter is 0", 2, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> checkEnergyCount(info, player, 0));
|
||||
checkPlayableAbility("2: condition met after losing counters", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Draw", true);
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ public class NethergoyfTest extends CardTestPlayerBaseWithAIHelps {
|
|||
// The same is true for permanent spells you control and nonland permanent cards you own that aren’t on the battlefield.
|
||||
addCard(Zone.HAND, playerA, "Encroaching Mycosynth");
|
||||
|
||||
// AI must be able to choose good targets combination
|
||||
aiPlayStep(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
package org.mage.test.cards.single.mir;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
public class PhyrexianDreadnoughtTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Phyrexian Dreadnought
|
||||
{1}
|
||||
Artifact Creature — Phyrexian Dreadnought
|
||||
|
||||
Trample
|
||||
|
||||
When this creature enters, sacrifice it unless you sacrifice any number of creatures with total power 12 or greater.
|
||||
|
||||
12/12
|
||||
*/
|
||||
private static final String phyrexianDreadnought = "Phyrexian Dreadnought";
|
||||
|
||||
@Test
|
||||
public void testPhyrexianDreadnoughtCanPay() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, phyrexianDreadnought);
|
||||
addCard(Zone.BATTLEFIELD, playerA, phyrexianDreadnought + "@sacTarget");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, phyrexianDreadnought);
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerA, "@sacTarget");
|
||||
setChoice(playerA, TestPlayer.CHOICE_SKIP);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, phyrexianDreadnought, 1);
|
||||
assertGraveyardCount(playerA, phyrexianDreadnought, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPhyrexianDreadnoughtCantPay() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, phyrexianDreadnought);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, phyrexianDreadnought);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
setChoice(playerA, false);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, phyrexianDreadnought, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package org.mage.test.cards.single.mkc;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class SereneSleuthTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Serene Sleuth
|
||||
{1}{W}
|
||||
Creature - Human Detective
|
||||
When Serene Sleuth enters the battlefield, investigate.
|
||||
At the beginning of combat on your turn, investigate for each goaded creature you control. Then each creature you control is no longer goaded.
|
||||
2/2
|
||||
*/
|
||||
private static final String sereneSleuth = "Serene Sleuth";
|
||||
|
||||
/*
|
||||
Baeloth Barrityl, Entertainer
|
||||
{4}{R}
|
||||
Legendary Creature - Elf Shaman
|
||||
Creatures your opponents control with power less than Baeloth Barrityl's power are goaded.
|
||||
Whenever a goaded attacking or blocking creature dies, you create a Treasure token.
|
||||
Choose a Background
|
||||
2/5
|
||||
*/
|
||||
private static final String baelothBarritylEntertainer = "Baeloth Barrityl, Entertainer";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
/*
|
||||
Cloudshift
|
||||
{W}
|
||||
Instant
|
||||
Exile target creature you control, then return that card to the battlefield under your control.
|
||||
*/
|
||||
private static final String cloudshift = "Cloudshift";
|
||||
|
||||
@Test
|
||||
public void testSereneSleuth() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, baelothBarritylEntertainer);
|
||||
addCard(Zone.BATTLEFIELD, playerA, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.HAND, playerA, sereneSleuth);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sereneSleuth);
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Clue Token", 1 + 1);
|
||||
assertTrue("fugitive wizard is not goaded", getPermanent(fugitiveWizard).getGoadingPlayers().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSereneSleuthReGoaded() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, baelothBarritylEntertainer);
|
||||
addCard(Zone.BATTLEFIELD, playerA, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||
addCard(Zone.HAND, playerA, sereneSleuth);
|
||||
addCard(Zone.HAND, playerB, cloudshift);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sereneSleuth);
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, cloudshift, baelothBarritylEntertainer);
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Clue Token", 1 + 1 + 1);
|
||||
assertTrue("fugitive wizard is goaded", getPermanent(fugitiveWizard).getGoadingPlayers().isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
package org.mage.test.cards.single.mkm;
|
||||
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.common.ExileAllEffect;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
|
|
@ -21,6 +25,11 @@ public class KayaSpiritsJusticeTest extends CardTestPlayerBase {
|
|||
addCard(Zone.GRAVEYARD, playerA, "Fyndhorn Elves");
|
||||
addCard(Zone.HAND, playerA, "Thraben Inspector");
|
||||
addCard(Zone.HAND, playerA, "Astrid Peth");
|
||||
// Choose one or more —
|
||||
// • Exile all artifacts.
|
||||
// • Exile all creatures.
|
||||
// • Exile all enchantments.
|
||||
// • Exile all graveyards.
|
||||
addCard(Zone.HAND, playerA, "Farewell");
|
||||
|
||||
// Creates a Clue token
|
||||
|
|
@ -35,6 +44,7 @@ public class KayaSpiritsJusticeTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Farewell");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "4");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
// Kaya's first ability triggers twice, so choose which is put on the stack:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.mage.test.cards.single.mom;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
|
@ -47,6 +48,7 @@ public class InvasionOfFioraTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, invasion);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
setModeChoice(playerA, "1");
|
||||
setModeChoice(playerA, TestPlayer.MODE_SKIP);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
checkPermanentCount("Battle on battlefield", 1, PhaseStep.PRECOMBAT_MAIN, playerA, invasion, 1);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package org.mage.test.cards.single.neo;
|
||||
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
public class EaterOfVirtueTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Eater of Virtue
|
||||
{1}
|
||||
Legendary Artifact — Equipment
|
||||
|
||||
Whenever equipped creature dies, exile it.
|
||||
|
||||
Equipped creature gets +2/+0.
|
||||
|
||||
As long as a card exiled with Eater of Virtue has flying, equipped creature has flying.
|
||||
The same is true for first strike, double strike, deathtouch, haste, hexproof, indestructible, lifelink, menace, protection, reach, trample, and vigilance.
|
||||
|
||||
Equip {1}
|
||||
*/
|
||||
public static final String eaterOfVirtue = "Eater of Virtue";
|
||||
|
||||
@Test
|
||||
public void testEaterOfVirtue() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, eaterOfVirtue);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Adult Gold Dragon"); // Flying, Lifelink, Haste
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears");
|
||||
addCard(Zone.HAND, playerB, "Doom Blade");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Adult Gold Dragon");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Doom Blade", "Adult Gold Dragon");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Equip", "Balduvian Bears");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAbilities(playerA, "Balduvian Bears", Arrays.asList(FlyingAbility.getInstance(), LifelinkAbility.getInstance(), HasteAbility.getInstance()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package org.mage.test.cards.single.one;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class EncroachingMycosynthTest extends CardTestCommanderDuelBase {
|
||||
|
||||
/*
|
||||
Encroaching Mycosynth
|
||||
{3}{U}
|
||||
Artifact
|
||||
|
||||
Nonland permanents you control are artifacts in addition to their other types.
|
||||
The same is true for permanent spells you control and nonland permanent cards you own that aren’t on the battlefield.
|
||||
*/
|
||||
private static final String encroachingMycosynth = "Encroaching Mycosynth";
|
||||
private static final String balduvianBears = "Balduvian Bears";
|
||||
@Test
|
||||
public void testEncroachingMycosynth() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, balduvianBears);
|
||||
addCard(Zone.HAND, playerA, balduvianBears, 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, encroachingMycosynth);
|
||||
addCard(Zone.EXILED, playerA, balduvianBears);
|
||||
addCard(Zone.LIBRARY, playerA, balduvianBears);
|
||||
addCard(Zone.COMMAND, playerA, balduvianBears);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, balduvianBears);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertType(balduvianBears, CardType.ARTIFACT, true);
|
||||
List<Card> cards = getHandCards(playerA);
|
||||
cards.addAll(getLibraryCards(playerA));
|
||||
cards.addAll(getCommandCards(playerA));
|
||||
cards.addAll(getExiledCards(playerA));
|
||||
cards.addAll(getLibraryCards(playerA));
|
||||
for (Card card : cards) {
|
||||
if (!card.isLand(currentGame)) {
|
||||
assertTrue(card.getCardType(currentGame).contains(CardType.ARTIFACT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package org.mage.test.cards.single.one;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class NahirisSacrificeTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Nahiri's Sacrifice
|
||||
{1}{R}
|
||||
Sorcery
|
||||
|
||||
As an additional cost to cast this spell, sacrifice an artifact or creature with mana value X.
|
||||
|
||||
Nahiri’s Sacrifice deals X damage divided as you choose among any number of target creatures.
|
||||
*/
|
||||
private static final String nahirisSacrifice = "Nahiri's Sacrifice";
|
||||
private static final String balduvianBears = "Balduvian Bears";
|
||||
@Test
|
||||
public void testNahirisSacrifice() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, nahirisSacrifice);
|
||||
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, balduvianBears + "@bearsB");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, nahirisSacrifice, "@bearsB");
|
||||
setChoice(playerA, "X=2");
|
||||
setChoice(playerA, balduvianBears);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, balduvianBears, 1);
|
||||
assertGraveyardCount(playerA, nahirisSacrifice, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNahirisSacrificePrevented() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, nahirisSacrifice);
|
||||
addCard(Zone.BATTLEFIELD, playerA, balduvianBears);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, balduvianBears + "@bearsB");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Yasharn, Implacable Earth");
|
||||
|
||||
checkPlayableAbility("Can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast " + nahirisSacrifice, false);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package org.mage.test.cards.single.shm;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
|
||||
public class ElsewhereFlaskTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Elsewhere Flask
|
||||
{2}
|
||||
Artifact
|
||||
|
||||
When this artifact enters, draw a card.
|
||||
|
||||
Sacrifice this artifact: Choose a basic land type. Each land you control becomes that type until end of turn.
|
||||
*/
|
||||
private static final String elsewhereFlask = "Elsewhere Flask";
|
||||
|
||||
@Test
|
||||
public void testElsewhereFlask() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, elsewhereFlask);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
|
||||
setChoice(playerA, "Swamp");
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertType("Island", CardType.LAND, SubType.SWAMP);
|
||||
assertType("Forest", CardType.LAND, SubType.SWAMP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testElsewhereFlask2() {
|
||||
setStrictChooseMode(true);
|
||||
addCard(Zone.BATTLEFIELD, playerA, elsewhereFlask);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice");
|
||||
setChoice(playerA, "Swamp");
|
||||
|
||||
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertType("Island", CardType.LAND, SubType.ISLAND);
|
||||
assertType("Forest", CardType.LAND, SubType.FOREST);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.abilities.keyword.MenaceAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class AlienSymbiosisTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Alien Symbiosis
|
||||
{1}{B}
|
||||
Enchantment - Aura
|
||||
Enchant creature
|
||||
Enchanted creature gets +1/+1, has menace, and is a Symbiote in addition to its other types.
|
||||
You may cast this card from your graveyard by discarding a card in addition to paying its other costs.
|
||||
*/
|
||||
private static final String alienSymbiosis = "Alien Symbiosis";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
@Test
|
||||
public void testAlienSymbiosisCastFromGrave() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerA, alienSymbiosis);
|
||||
addCard(Zone.HAND, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bearCub);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, alienSymbiosis, bearCub);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPowerToughness(playerA, bearCub, 3, 3);
|
||||
assertAbilityCount(playerA, bearCub, MenaceAbility.class, 1);
|
||||
assertSubtype(bearCub, SubType.SYMBIOTE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class ArachnePsionicWeaverTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Arachne, Psionic Weaver
|
||||
{2}{W}
|
||||
Legendary Creature - Spider Human Hero
|
||||
Web-slinging {W}
|
||||
As Arachne enters, look at target opponent's hand, then choose a noncreature card type.
|
||||
Spells of the chosen type cost {1} more to cast.
|
||||
3/3
|
||||
*/
|
||||
private static final String arachnePsionicWeaver = "Arachne, Psionic Weaver";
|
||||
|
||||
/*
|
||||
Tormod's Crypt
|
||||
{0}
|
||||
Artifact
|
||||
{tap}, Sacrifice Tormod's Crypt: Exile all cards from target player's graveyard.
|
||||
*/
|
||||
private static final String tormodsCrypt = "Tormod's Crypt";
|
||||
|
||||
@Test
|
||||
public void testArachnePsionicWeaver() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, arachnePsionicWeaver);
|
||||
addCard(Zone.HAND, playerA, tormodsCrypt);
|
||||
addCard(Zone.HAND, playerB, tormodsCrypt);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arachnePsionicWeaver);
|
||||
setChoice(playerA, CardType.ARTIFACT.toString());
|
||||
|
||||
checkPlayableAbility("Player A can't cast Tormod's", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cast " + tormodsCrypt, false);
|
||||
|
||||
checkPlayableAbility("Player B can cast Tormod's", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast " + tormodsCrypt, true);
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class BlackCatCunningThiefTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Black Cat, Cunning Thief
|
||||
{3}{B}{B}
|
||||
Legendary Creature - Human Rogue Villain
|
||||
When Black Cat enters, look at the top nine cards of target opponent's library, exile two of them face down, then put the rest on the bottom of their library in a random order. You may play the exiled cards for as long as they remain exiled. Mana of any type can be spent to cast spells this way.
|
||||
2/3
|
||||
*/
|
||||
private static final String blackCatCunningThief = "Black Cat, Cunning Thief";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
@Test
|
||||
public void testBlackCatCunningThief() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.HAND, playerA, blackCatCunningThief);
|
||||
addCard(Zone.LIBRARY, playerB, bearCub);
|
||||
addCard(Zone.LIBRARY, playerB, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 8);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, blackCatCunningThief);
|
||||
addTarget(playerA, playerB);
|
||||
setChoice(playerA, bearCub);
|
||||
setChoice(playerA, fugitiveWizard);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bearCub, true);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, fugitiveWizard);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, bearCub, 1);
|
||||
assertPermanentCount(playerA, fugitiveWizard, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class CarnageCrimsonChaosTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Carnage, Crimson Chaos
|
||||
{2}{B}{R}
|
||||
Legendary Creature - Symbiote Villain
|
||||
Trample
|
||||
When Carnage enters, return target creature card with mana value 3 or less from your graveyard to the battlefield. It gains "This creature attacks each combat if able" and "When this creature deals combat damage to a player, sacrifice it."
|
||||
Mayhem {B}{R}
|
||||
4/3
|
||||
*/
|
||||
private static final String carnageCrimsonChaos = "Carnage, Crimson Chaos";
|
||||
|
||||
/*
|
||||
Concordant Crossroads
|
||||
{G}
|
||||
World Enchantment
|
||||
All creatures have haste.
|
||||
*/
|
||||
private static final String concordantCrossroads = "Concordant Crossroads";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
@Test
|
||||
public void testCarnageCrimsonChaos() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, concordantCrossroads);
|
||||
addCard(Zone.HAND, playerA, carnageCrimsonChaos);
|
||||
addCard(Zone.GRAVEYARD, playerA, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Badlands", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, carnageCrimsonChaos);
|
||||
addTarget(playerA, bearCub);
|
||||
|
||||
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, bearCub, 1);
|
||||
assertLife(playerB, 20 - 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class CheeringCrowdTest extends CardTestCommander4Players {
|
||||
|
||||
/*
|
||||
Cheering Crowd
|
||||
{1}{R/G}
|
||||
Creature - Human Citizen
|
||||
At the beginning of each player's first main phase, that player may put a +1/+1 counter on this creature. If they do, they add {C} for each counter on it.
|
||||
2/2
|
||||
*/
|
||||
private static final String cheeringCrowd = "Cheering Crowd";
|
||||
|
||||
@Test
|
||||
public void testCheeringCrowd() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, cheeringCrowd);
|
||||
|
||||
setChoice(playerA, true);
|
||||
setChoice(playerB, true);
|
||||
setChoice(playerC, true);
|
||||
setChoice(playerD, true);
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||
checkManaPool("PlayerA should have 1 Mana", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "C", 1);
|
||||
waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN, playerD);
|
||||
checkManaPool("PlayerD should have 2 Mana", 2, PhaseStep.PRECOMBAT_MAIN, playerD, "C", 2);
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN, playerC);
|
||||
checkManaPool("PlayerC should have 3 Mana", 3, PhaseStep.PRECOMBAT_MAIN, playerC, "C", 3);
|
||||
waitStackResolved(4, PhaseStep.PRECOMBAT_MAIN, playerB);
|
||||
checkManaPool("PlayerB should have 4 Mana", 4, PhaseStep.PRECOMBAT_MAIN, playerB, "C", 4);
|
||||
|
||||
setStopAt(4, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, cheeringCrowd, CounterType.P1P1, 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class ElectroAssaultingBatteryTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Electro, Assaulting Battery
|
||||
{1}{R}{R}
|
||||
Legendary Creature - Human Villain
|
||||
Flying
|
||||
You don't lose unspent red mana as steps and phases end.
|
||||
Whenever you cast an instant or sorcery spell, add {R}.
|
||||
When Electro leaves the battlefield, you may pay {X}. When you do, he deals X damage to target player.
|
||||
2/3
|
||||
*/
|
||||
private static final String electroAssaultingBattery = "Electro, Assaulting Battery";
|
||||
|
||||
/*
|
||||
Pyretic Ritual
|
||||
{1}{R}
|
||||
Instant
|
||||
Add {R}{R}{R}.
|
||||
*/
|
||||
private static final String pyreticRitual = "Pyretic Ritual";
|
||||
|
||||
/*
|
||||
Lightning Bolt
|
||||
{R}
|
||||
Instant
|
||||
Lightning Bolt deals 3 damage to any target.
|
||||
*/
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
|
||||
|
||||
@Test
|
||||
public void testElectroAssaultingBattery() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, electroAssaultingBattery);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||
addCard(Zone.HAND, playerA, pyreticRitual);
|
||||
addCard(Zone.HAND, playerB, lightningBolt);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, pyreticRitual);
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, lightningBolt, electroAssaultingBattery);
|
||||
setChoice(playerA, true);
|
||||
setChoiceAmount(playerA, 4); // 3 from ritual + 1 from electro
|
||||
addTarget(playerA, playerB);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 20 - 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class GwenomRemorselessTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Gwenom, Remorseless
|
||||
{3}{B}{B}
|
||||
Legendary Creature - Symbiote Spider Hero
|
||||
Deathtouch, lifelink
|
||||
Whenever Gwenom attacks, until end of turn you may look at the top card of your library any time and you may play cards 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.
|
||||
4/4
|
||||
*/
|
||||
private static final String gwenomRemorseless = "Gwenom, Remorseless";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
@Test
|
||||
public void testGwenomRemorseless() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, gwenomRemorseless);
|
||||
addCard(Zone.LIBRARY, playerA, "Island");
|
||||
addCard(Zone.LIBRARY, playerA, bearCub, 2);
|
||||
addCard(Zone.LIBRARY, playerA, "Forest");
|
||||
|
||||
attack(1, playerA, gwenomRemorseless);
|
||||
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Forest");
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, bearCub);
|
||||
|
||||
// effect ends at end of turn
|
||||
checkPlayableAbility("Can't play top card", 2, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Island", false);
|
||||
|
||||
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, bearCub, 1);
|
||||
assertPermanentCount(playerA, gwenomRemorseless, 1);
|
||||
assertPermanentCount(playerA, "Forest", 1);
|
||||
assertLife(playerB, 20 - 4);
|
||||
assertLife(playerA, 20 + 4 - 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class HydroManFluidFelonTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Hydro-Man, Fluid Felon
|
||||
{U}{U}
|
||||
Legendary Creature - Elemental Villain
|
||||
Whenever you cast a blue spell, if Hydro-Man is a creature, he gets +1/+1 until end of turn.
|
||||
At the beginning of your end step, untap Hydro-Man. Until your next turn, he becomes a land and gains "{T}: Add {U}."
|
||||
2/2
|
||||
*/
|
||||
private static final String hydroManFluidFelon = "Hydro-Man, Fluid Felon";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
@Test
|
||||
public void testHydroManFluidFelon() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerA, hydroManFluidFelon);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fugitiveWizard, true);
|
||||
|
||||
checkPT("Hydro-Man is boosted", 1, PhaseStep.PRECOMBAT_MAIN, playerA, hydroManFluidFelon, 3, 3);
|
||||
|
||||
attack(1, playerA, hydroManFluidFelon);
|
||||
|
||||
setStopAt(2, PhaseStep.UPKEEP);
|
||||
execute();
|
||||
|
||||
assertType(hydroManFluidFelon, CardType.LAND, true);
|
||||
assertNotType(hydroManFluidFelon, CardType.CREATURE);
|
||||
assertTapped(hydroManFluidFelon, false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class InterdimensionalWebWatchTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Interdimensional Web Watch
|
||||
{4}
|
||||
Artifact
|
||||
When this artifact enters, exile the top two cards of your library. Until the end of your next turn, you may play those cards.
|
||||
{T}: Add two mana in any combination of colors. Spend this mana only to cast spells from exile.
|
||||
*/
|
||||
private static final String interdimensionalWebWatch = "Interdimensional Web Watch";
|
||||
|
||||
/*
|
||||
Lightning Bolt
|
||||
{R}
|
||||
Instant
|
||||
Lightning Bolt deals 3 damage to any target.
|
||||
*/
|
||||
private static final String lightningBolt = "Lightning Bolt";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
/*
|
||||
Shock
|
||||
{R}
|
||||
Instant
|
||||
Shock deals 2 damage to any target.
|
||||
*/
|
||||
private static final String shock = "Shock";
|
||||
|
||||
@Test
|
||||
public void testInterdimensionalWebWatch() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, lightningBolt);
|
||||
addCard(Zone.LIBRARY, playerA, fugitiveWizard);
|
||||
addCard(Zone.HAND, playerA, interdimensionalWebWatch);
|
||||
addCard(Zone.HAND, playerA, shock);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, interdimensionalWebWatch, true);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add two");
|
||||
setChoiceAmount(playerA, 0, 1, 0, 1, 0); // Add {U}{R}
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
checkPlayableAbility("Can't cast shock from hand", 1, PhaseStep.PRECOMBAT_MAIN, playerA,
|
||||
"Cast " + shock, false);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lightningBolt, true);
|
||||
addTarget(playerA, playerB);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, fugitiveWizard);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 20 - 3);
|
||||
assertPermanentCount(playerA, fugitiveWizard, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class JackalGeniusGeneticistTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Jackal, Genius Geneticist
|
||||
{G}{U}
|
||||
Legendary Creature - Human Scientist Villain
|
||||
Trample
|
||||
Whenever you cast a creature spell with mana value equal to Jackal's power, copy that spell, except the copy isn't legendary. Then put a +1/+1 counter on Jackal.
|
||||
1/1
|
||||
*/
|
||||
private static final String jackalGeniusGeneticist = "Jackal, Genius Geneticist";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Ragavan, Nimble Pilferer
|
||||
{R}
|
||||
Legendary Creature - Monkey Pirate
|
||||
Whenever Ragavan, Nimble Pilferer deals combat damage to a player, create a Treasure token and exile the top card of that player's library. Until end of turn, you may cast that card.
|
||||
Dash {1}{R}
|
||||
2/1
|
||||
*/
|
||||
private static final String ragavanNimblePilferer = "Ragavan, Nimble Pilferer";
|
||||
|
||||
@Test
|
||||
public void testJackalGeniusGeneticist() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, jackalGeniusGeneticist);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Taiga", 3);
|
||||
addCard(Zone.HAND, playerA, ragavanNimblePilferer);
|
||||
addCard(Zone.HAND, playerA, bearCub);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, ragavanNimblePilferer);
|
||||
setChoice(playerA, "Cast with no");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bearCub);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, ragavanNimblePilferer, 2);
|
||||
assertPermanentCount(playerA, bearCub, 2);
|
||||
assertCounterCount(playerA, jackalGeniusGeneticist, CounterType.P1P1, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.abilities.effects.common.UntapAllControllerEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class LadyOctopusInspiredInventorTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Lady Octopus, Inspired Inventor
|
||||
{U}
|
||||
Legendary Creature - Human Scientist Villain
|
||||
Whenever you draw your first or second card each turn, put an ingenuity counter on Lady Octopus.
|
||||
{T}: You may cast an artifact spell from your hand with mana value less than or equal to the number of ingenuity counters on Lady Octopus without paying its mana cost.
|
||||
*/
|
||||
private static final String ladyOctopusInspiredInventor = "Lady Octopus, Inspired Inventor";
|
||||
|
||||
/*
|
||||
Aether Vial
|
||||
{1}
|
||||
Artifact
|
||||
At the beginning of your upkeep, you may put a charge counter on Aether Vial.
|
||||
{T}: You may put a creature card with converted mana cost equal to the number of charge counters on ther Vial from your hand onto the battlefield.
|
||||
*/
|
||||
private static final String aetherVial = "Aether Vial";
|
||||
|
||||
/*
|
||||
Tormod's Crypt
|
||||
{0}
|
||||
Artifact
|
||||
{tap}, Sacrifice Tormod's Crypt: Exile all cards from target player's graveyard.
|
||||
*/
|
||||
private static final String tormodsCrypt = "Tormod's Crypt";
|
||||
|
||||
/*
|
||||
Howling Mine
|
||||
{2}
|
||||
Artifact
|
||||
At the beginning of each player's draw step, if Howling Mine is untapped, that player draws an additional card.
|
||||
*/
|
||||
private static final String howlingMine = "Howling Mine";
|
||||
|
||||
@Test
|
||||
public void testLadyOctopusInspiredInventor() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCustomCardWithAbility("untap all creatures", playerA, new SimpleActivatedAbility(
|
||||
new UntapAllControllerEffect(new FilterCreaturePermanent()),
|
||||
new ManaCostsImpl<>("")
|
||||
));
|
||||
addCustomCardWithAbility("draw a card", playerA, new SimpleActivatedAbility(
|
||||
new DrawCardSourceControllerEffect(1),
|
||||
new ManaCostsImpl<>("")
|
||||
));
|
||||
addCard(Zone.BATTLEFIELD, playerA, ladyOctopusInspiredInventor);
|
||||
addCard(Zone.HAND, playerA, aetherVial);
|
||||
addCard(Zone.HAND, playerA, tormodsCrypt);
|
||||
addCard(Zone.HAND, playerA, howlingMine);
|
||||
|
||||
activateDrawCardAndUntap(); // Tormod's crypt
|
||||
activateDrawCardAndUntap(); // Aether Vial
|
||||
activateDrawCardAndUntap(); // Howling Mine
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, ladyOctopusInspiredInventor, CounterType.INGENUITY, 2);
|
||||
assertHandCount(playerA, 3);
|
||||
}
|
||||
|
||||
private void activateDrawCardAndUntap() {
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: You may cast");
|
||||
setChoice(playerA, true);
|
||||
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "draw a");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "untap all");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLadyOctopusInspiredInventorChoose() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCustomCardWithAbility("draw a card", playerA, new SimpleActivatedAbility(
|
||||
new DrawCardSourceControllerEffect(3),
|
||||
new ManaCostsImpl<>("")
|
||||
));
|
||||
addCard(Zone.BATTLEFIELD, playerA, ladyOctopusInspiredInventor);
|
||||
addCard(Zone.HAND, playerA, aetherVial);
|
||||
addCard(Zone.HAND, playerA, tormodsCrypt);
|
||||
addCard(Zone.HAND, playerA, howlingMine);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "draw ");
|
||||
setChoice(playerA, "Whenever you draw your first"); // trigger stack
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: You may cast");
|
||||
setChoice(playerA, tormodsCrypt);
|
||||
setChoice(playerA, true);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(playerA, ladyOctopusInspiredInventor, CounterType.INGENUITY, 2);
|
||||
assertHandCount(playerA, 3 + 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class MaximumCarnageTest extends CardTestCommander4Players {
|
||||
|
||||
/*
|
||||
Maximum Carnage
|
||||
{4}{R}
|
||||
Enchantment - Saga
|
||||
(As this Saga enters step and after your draw step, add a lore counter. Sacrifice after III.)
|
||||
I -- Until your next turn, each creature attacks each combat if able and attacks a player other than you if able.
|
||||
II -- Add {R}{R}{R}.
|
||||
III -- This Saga deals 5 damage to each opponent.
|
||||
*/
|
||||
private static final String maximumCarnage = "Maximum Carnage";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
@Test
|
||||
public void testMaximumCarnage() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, maximumCarnage);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerD, bearCub);
|
||||
|
||||
addTarget(playerD, playerC); // must attack
|
||||
addTarget(playerB, playerD); // must attack
|
||||
|
||||
setStopAt(4, PhaseStep.END_TURN);
|
||||
execute();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaximumCarnageCantAttackController() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, maximumCarnage);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerD, bearCub);
|
||||
|
||||
addTarget(playerD, playerA); // must attack
|
||||
|
||||
setStopAt(4, PhaseStep.END_TURN);
|
||||
try {
|
||||
execute();
|
||||
} catch (AssertionError e) {
|
||||
assertTrue("Shouldn't be able to attack playerA",
|
||||
e.getMessage().contains("[targetPlayer=PlayerA], but not used"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class MisterNegativeTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Mister Negative
|
||||
{5}{W}{B}
|
||||
Legendary Creature - Human Villain
|
||||
Vigilance, lifelink
|
||||
When Mister Negative enters, you may exchange your life total with target opponent. If you lose life this way, draw that many cards.
|
||||
5/5
|
||||
*/
|
||||
private static final String misterNegative = "Mister Negative";
|
||||
|
||||
@Test
|
||||
public void testMisterNegative() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, misterNegative);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Scrubland", 7);
|
||||
setLife(playerB, 15);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, misterNegative);
|
||||
addTarget(playerA, playerB);
|
||||
setChoice(playerA, true);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 5);
|
||||
assertLife(playerA, 15);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMisterNegativeNoDraw() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, misterNegative);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Scrubland", 7);
|
||||
setLife(playerB, 21);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, misterNegative);
|
||||
addTarget(playerA, playerB);
|
||||
setChoice(playerA, true);
|
||||
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 0);
|
||||
assertLife(playerA, 21);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class MultiversalPassageTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Multiversal Passage
|
||||
|
||||
Land
|
||||
As this land enters, choose a basic land type. Then you may pay 2 life. If you don't, it enters tapped.
|
||||
This land is the chosen type.
|
||||
*/
|
||||
private static final String multiversalPassage = "Multiversal Passage";
|
||||
|
||||
@Test
|
||||
public void testMultiversalPassage() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, multiversalPassage);
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, multiversalPassage);
|
||||
setChoice(playerA, "Swamp");
|
||||
setChoice(playerA, true); // untapped
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertSubtype(multiversalPassage, SubType.SWAMP);
|
||||
assertLife(playerA, 20 - 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class OscorpIndustriesTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Oscorp Industries
|
||||
|
||||
Land
|
||||
This land enters tapped.
|
||||
When this land enters from a graveyard, you lose 2 life.
|
||||
{T}: Add {U}, {B}, or {R}.
|
||||
Mayhem
|
||||
*/
|
||||
private static final String oscorpIndustries = "Oscorp Industries";
|
||||
|
||||
/*
|
||||
Thought Courier
|
||||
{1}{U}
|
||||
Creature - Human Wizard
|
||||
{tap}: Draw a card, then discard a card.
|
||||
1/1
|
||||
*/
|
||||
private static final String thoughtCourier = "Thought Courier";
|
||||
|
||||
@Test
|
||||
public void testOscorpIndustries() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, oscorpIndustries);
|
||||
addCard(Zone.BATTLEFIELD, playerA, thoughtCourier);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Draw");
|
||||
setChoice(playerA, oscorpIndustries);
|
||||
|
||||
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, oscorpIndustries + " with Mayhem");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20 - 2);
|
||||
assertPermanentCount(playerA, oscorpIndustries, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommander4Players;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class ParkerLuckTest extends CardTestCommander4Players {
|
||||
|
||||
/*
|
||||
Parker Luck
|
||||
{2}{B}
|
||||
Enchantment
|
||||
At the beginning of your end step, two target players each reveal the top card of their library. They each lose life equal to the mana value of the card revealed by the other player. Then they each put the card they revealed into their hand.
|
||||
*/
|
||||
private static final String parkerLuck = "Parker Luck";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
@Test
|
||||
public void testParkerLuck() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, parkerLuck);
|
||||
addCard(Zone.LIBRARY, playerD, bearCub);
|
||||
addCard(Zone.LIBRARY, playerC, fugitiveWizard);
|
||||
|
||||
addTarget(playerA, playerC);
|
||||
addTarget(playerA, playerD);
|
||||
|
||||
setStopAt(1, PhaseStep.CLEANUP);
|
||||
execute();
|
||||
|
||||
assertLife(playerC, 20 - 2);
|
||||
assertLife(playerD, 20 - 1);
|
||||
assertHandCount(playerC, 1);
|
||||
assertHandCount(playerD, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParkerLuckOneLibraryEmpty() {
|
||||
setStrictChooseMode(true);
|
||||
skipInitShuffling();
|
||||
removeAllCardsFromLibrary(playerC);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, parkerLuck);
|
||||
addCard(Zone.LIBRARY, playerD, bearCub);
|
||||
|
||||
addTarget(playerA, playerC);
|
||||
addTarget(playerA, playerD);
|
||||
|
||||
setStopAt(1, PhaseStep.CLEANUP);
|
||||
execute();
|
||||
|
||||
assertLife(playerC, 20 - 2);
|
||||
assertHandCount(playerD, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.common.TapAllEffect;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class PeterParkerTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Peter Parker
|
||||
{1}{W}
|
||||
Legendary Creature - Human Scientist Hero
|
||||
When Peter Parker enters, create a 2/1 green Spider creature token with reach.
|
||||
{1}{G}{W}{U}: Transform Peter Parker. Activate only as a sorcery.
|
||||
Amazing Spider-Man
|
||||
{1}{G}{W}{U}
|
||||
Legendary Creature - Spider Human Hero
|
||||
Vigilance, reach
|
||||
Each legendary spell you cast that's one or more colors has web-slinging {G}{W}{U}.
|
||||
4/4
|
||||
*/
|
||||
private static final String peterParker = "Peter Parker";
|
||||
|
||||
|
||||
/*
|
||||
Absolute Virtue
|
||||
{6}{W}{U}
|
||||
Legendary Creature - Avatar Warrior
|
||||
This spell can't be countered.
|
||||
Flying
|
||||
You have protection from each of your opponents.
|
||||
8/8
|
||||
*/
|
||||
private static final String absoluteVirtue = "Absolute Virtue";
|
||||
|
||||
/*
|
||||
Adelbert Steiner
|
||||
{1}{W}
|
||||
Legendary Creature - Human Knight
|
||||
Lifelink
|
||||
Adelbert Steiner gets +1/+1 for each Equipment you control.
|
||||
2/1
|
||||
*/
|
||||
private static final String adelbertSteiner = "Adelbert Steiner";
|
||||
|
||||
/*
|
||||
Chainer, Nightmare Adept
|
||||
{2}{B}{R}
|
||||
Legendary Creature - Human Minion
|
||||
Discard a card: You may cast a creature card from your graveyard this turn. Activate this ability only once each turn.
|
||||
Whenever a nontoken creature enters the battlefield under your control, if you didn't cast it from your hand, it gains haste until your next turn.
|
||||
3/2
|
||||
*/
|
||||
private static final String chainerNightmareAdept = "Chainer, Nightmare Adept";
|
||||
|
||||
/*
|
||||
Balduvian Bears
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String balduvianBears = "Balduvian Bears";
|
||||
|
||||
@Test
|
||||
@Ignore("Enable after MDFC rework")
|
||||
public void testAmazingSpiderMan() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCustomCardWithAbility("tap all creatures", playerA, new SimpleActivatedAbility(
|
||||
new TapAllEffect(new FilterCreaturePermanent(SubType.BEAR, "bears")),
|
||||
new ManaCostsImpl<>("")
|
||||
));
|
||||
|
||||
addCard(Zone.HAND, playerA, peterParker);
|
||||
addCard(Zone.BATTLEFIELD, playerA, chainerNightmareAdept);
|
||||
addCard(Zone.BATTLEFIELD, playerA, balduvianBears,2);
|
||||
addCard(Zone.HAND, playerA, adelbertSteiner, 2);
|
||||
addCard(Zone.GRAVEYARD, playerA, absoluteVirtue);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tropical Island", 8);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Tundra", 8);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Amazing Spider-Man", true);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "tap all"); // tap bears, addCard command isn't working to set tapped
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, adelbertSteiner + " with Web-slinging", true);
|
||||
setChoice(playerA, balduvianBears); // return to hand
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard a card");
|
||||
setChoice(playerA, adelbertSteiner); // discard
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
checkPlayableAbility("Bear does not have web-slinging", 1, PhaseStep.PRECOMBAT_MAIN, playerA,
|
||||
"Cast " + balduvianBears + " with Web-slinging", false);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, absoluteVirtue + " with Web-slinging");
|
||||
setChoice(playerA, balduvianBears); // return to hand
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class RhinosRampageTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Rhino's Rampage
|
||||
{R/G}
|
||||
Sorcery
|
||||
Target creature you control gets +1/+0 until end of turn. It fights target creature an opponent controls.
|
||||
When excess damage is dealt to the creature an opponent controls this way, destroy up to one target noncreature artifact with mana value 3 or less.
|
||||
*/
|
||||
private static final String rhinosRampage = "Rhino's Rampage";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Fugitive Wizard
|
||||
{U}
|
||||
Creature - Human Wizard
|
||||
|
||||
1/1
|
||||
*/
|
||||
private static final String fugitiveWizard = "Fugitive Wizard";
|
||||
|
||||
/*
|
||||
Tormod's Crypt
|
||||
{0}
|
||||
Artifact
|
||||
{T}, Sacrifice Tormod's Crypt: Exile all cards from target player's graveyard.
|
||||
*/
|
||||
private static final String tormodsCrypt = "Tormod's Crypt";
|
||||
|
||||
@Test
|
||||
public void testRhinosRampageExcess() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, rhinosRampage);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerB, tormodsCrypt);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, rhinosRampage);
|
||||
addTarget(playerA, bearCub);
|
||||
addTarget(playerA, fugitiveWizard);
|
||||
addTarget(playerA, tormodsCrypt);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerB, fugitiveWizard, 1);
|
||||
assertGraveyardCount(playerB, tormodsCrypt, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRhinosRampageNoExcess() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, rhinosRampage);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, fugitiveWizard);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, tormodsCrypt);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, rhinosRampage);
|
||||
addTarget(playerA, fugitiveWizard);
|
||||
addTarget(playerA, bearCub);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, fugitiveWizard, 1);
|
||||
assertGraveyardCount(playerB, bearCub, 1);
|
||||
assertPermanentCount(playerB, tormodsCrypt, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package org.mage.test.cards.single.spm;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Jmlundeen
|
||||
*/
|
||||
public class SandmansQuicksandTest extends CardTestPlayerBase {
|
||||
|
||||
/*
|
||||
Sandman's Quicksand
|
||||
{1}{B}{B}
|
||||
Sorcery
|
||||
Mayhem {3}{B}
|
||||
All creatures get -2/-2 until end of turn. If this spell's mayhem cost was paid, creatures your opponents control get -2/-2 until end of turn instead.
|
||||
*/
|
||||
private static final String sandmansQuicksand = "Sandman's Quicksand";
|
||||
|
||||
/*
|
||||
Bear Cub
|
||||
{1}{G}
|
||||
Creature - Bear
|
||||
|
||||
2/2
|
||||
*/
|
||||
private static final String bearCub = "Bear Cub";
|
||||
|
||||
/*
|
||||
Thought Courier
|
||||
{1}{U}
|
||||
Creature - Human Wizard
|
||||
{tap}: Draw a card, then discard a card.
|
||||
1/1
|
||||
*/
|
||||
private static final String thoughtCourier = "Thought Courier";
|
||||
|
||||
@Test
|
||||
public void testSandmansQuicksand() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, sandmansQuicksand);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sandmansQuicksand);
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, bearCub, 1);
|
||||
assertGraveyardCount(playerB, bearCub, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSandmansQuicksandMayhem() {
|
||||
setStrictChooseMode(true);
|
||||
|
||||
addCard(Zone.HAND, playerA, sandmansQuicksand);
|
||||
addCard(Zone.BATTLEFIELD, playerA, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, thoughtCourier);
|
||||
addCard(Zone.BATTLEFIELD, playerB, bearCub);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Draw");
|
||||
setChoice(playerA, sandmansQuicksand);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sandmansQuicksand + " with Mayhem");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, bearCub, 0);
|
||||
assertGraveyardCount(playerB, bearCub, 1);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue