Merge branch 'master' into fix-tapped-for-mana-event

This commit is contained in:
Oleg Agafonov 2019-12-31 12:12:25 +01:00 committed by GitHub
commit 60781604f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1600 changed files with 42766 additions and 10461 deletions

View file

@ -1,4 +1,3 @@
package org.mage.test.AI.basic;
import mage.constants.PhaseStep;
@ -8,7 +7,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBaseAI;
/**
*
* @author LevelX2
*/
public class CastCreaturesTest extends CardTestPlayerBaseAI {
@ -173,7 +171,7 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI {
/**
* Tests that the creature is cast if enough mana is available.
*
* <p>
* Once Ammit Eternal is cast against a computer AI opponent, the AI just
* decides to sit there and only play basic lands. I've sat there and decked
* it because it just plays lands. It's like it views giving the Ammit
@ -194,8 +192,11 @@ public class CastCreaturesTest extends CardTestPlayerBaseAI {
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ammit Eternal");
setStrictChooseMode(true);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerB, "Ammit Eternal", 1);

View file

@ -0,0 +1,58 @@
package org.mage.test.AI.basic;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class ChooseTargetTest extends CardTestPlayerBase {
@Test
public void test_chooseTargetCard_Manual() {
// At the beginning of your end step, choose a creature card in an opponent's graveyard, then that player chooses a creature card in your graveyard.
// You may return those cards to the battlefield under their owners' control.
addCard(Zone.BATTLEFIELD, playerA, "Dawnbreak Reclaimer", 1);
//
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 1);
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1);
setChoice(playerA, "Silvercoat Lion");
setChoice(playerB, "Silvercoat Lion");
setChoice(playerA, "Yes");
setStrictChooseMode(true);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseTargetCard_AI() {
// At the beginning of your end step, choose a creature card in an opponent's graveyard, then that player chooses a creature card in your graveyard.
// You may return those cards to the battlefield under their owners' control.
addCard(Zone.BATTLEFIELD, playerA, "Dawnbreak Reclaimer", 1);
//
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 1);
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1);
// AI must choose itself (strict mode must be disabled)
//setChoice(playerA, "Silvercoat Lion");
//setChoice(playerB, "Silvercoat Lion");
//setChoice(playerA, "Yes");
//setStrictChooseMode(true);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
}
}

View file

@ -0,0 +1,40 @@
package org.mage.test.AI.basic;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestCommander4Players;
/**
* @author JayDi85
*/
public class ExileTargetTest extends CardTestCommander4Players {
// Player order: A -> D -> C -> B
@Test
public void test_chooseOpponentTargets() {
// AI sometimes chooses own permanents in multiplayer game instead opponents
// When Oblivion Ring enters the battlefield, exile another target nonland permanent.
// When Oblivion Ring leaves the battlefield, return the exiled card to the battlefield under its owners control.
addCard(Zone.HAND, playerA, "Oblivion Ring", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
//
addCard(Zone.BATTLEFIELD, playerA, "Apex Altisaur", 1); // 10/10
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); // 2/2
addCard(Zone.BATTLEFIELD, playerC, "Balduvian Bears", 1); // 2/2
// must select opponent's Balduvian Bears
// showAvaileableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Oblivion Ring");
//addTarget(playerA, "Balduvian Bears"); // disable to activate AI target choose
// showAvaileableAbilities("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
//setStrictChooseMode(true); // disable strict mode to activate AI for choosing
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerC, "Balduvian Bears", 0);
}
}

View file

@ -21,7 +21,6 @@ import org.mage.test.serverside.base.CardTestPlayerBaseAI;
public class TargetPriorityTest extends CardTestPlayerBaseAI {
// TODO: enable _target_ tests after computerPlayer.chooseTarget will be reworks like chooseTargetAmount
@Test
@Ignore
public void test_target_PriorityKillByBigPT() {
@ -116,7 +115,6 @@ public class TargetPriorityTest extends CardTestPlayerBaseAI {
checkPermanentCounters("counters", 1, PhaseStep.BEGIN_COMBAT, playerB, "Balduvian Bears", CounterType.P1P1, 2);
// AI cast avatar on turn 3 and target 1 creature to kil by 3 damage
//setStrictChooseMode(true); // AI
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
@ -144,8 +142,7 @@ public class TargetPriorityTest extends CardTestPlayerBaseAI {
addCard(Zone.BATTLEFIELD, playerB, "Battering Sliver", 1 * cardsMultiplier); // 4/4 with ability
//castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt");
showHand("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
// showHand("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
@ -159,9 +156,7 @@ public class TargetPriorityTest extends CardTestPlayerBaseAI {
*/
}
// TARGET AMOUNT
@Test
public void test_targetAmount_PriorityKillByBigPT() {
addCard(Zone.HAND, playerA, "Flames of the Firebrand"); // damage 3
@ -279,7 +274,7 @@ public class TargetPriorityTest extends CardTestPlayerBaseAI {
// must damage x3 Balduvian Bears by -1 to keep alive
checkDamage("pt after", 1, PhaseStep.BEGIN_COMBAT, playerA, "Balduvian Bears", 1);
showBattlefield("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
// showBattlefield("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();

View file

@ -0,0 +1,101 @@
package org.mage.test.AI.basic;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class TargetRequiredTest extends CardTestPlayerBase {
/*
Redcap must sacrifice target land -- it's required target, but AI don't known about that
(target can be copied as new target in effect's code)
*/
@Test
public void test_chooseBadTargetOnSacrifice_WithTargets_User() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
addTarget(playerA, "Mountain");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Mountain", 3 - 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithTargets_AI() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); AI must select targets
//setStrictChooseMode(true); AI must select targets
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerA, "Mountain", 1);
assertPermanentCount(playerA, "Mountain", 3 - 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithoutTargets_User() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Atarka Monument", 1); // {T}: Add {R} or {G}.
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); no lands to sacrifice
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
@Test
public void test_chooseBadTargetOnSacrifice_WithoutTargets_AI() {
// Redcap Melee deals 4 damage to target creature or planeswalker. If a nonred permanent is dealt damage this way, you sacrifice a land.
addCard(Zone.HAND, playerA, "Redcap Melee", 1);
addCard(Zone.BATTLEFIELD, playerA, "Atarka Monument", 1); // {T}: Add {R} or {G}.
//
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Redcap Melee", "Silvercoat Lion");
//addTarget(playerA, "Mountain"); no lands to sacrifice
//setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Redcap Melee", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
}
}

View file

@ -204,7 +204,7 @@ public class TargetsAreChosenTest extends CardTestPlayerBaseAI {
@Test
public void testArchfiendOfDepravity() {
// Flying
// At the beginning of each opponent's end step, that player chooses up to two creatures he or she controls, then sacrifices the rest.
// At the beginning of each opponent's end step, that player chooses up to two creatures they control, then sacrifices the rest.
addCard(Zone.BATTLEFIELD, playerB, "Archfiend of Depravity");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 3);

View file

@ -19,8 +19,8 @@ public class DomainTest extends CardTestPlayerBase {
*/
@Test
public void testCollapsingBorders() {
// Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands he or she controls.
// Then Collapsing Borders deals 3 damage to him or her.
// Domain - At the beginning of each player's upkeep, that player gains 1 life for each basic land type among lands they control.
// Then Collapsing Borders deals 3 damage to that player.
addCard(Zone.HAND, playerA, "Collapsing Borders", 1); // {3}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.abilities.activated;
import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class LightningStormTest extends CardTestPlayerBase {
@ -16,10 +14,9 @@ public class LightningStormTest extends CardTestPlayerBase {
* So, this just happened to me. My opponent cast Lightning Storm and while
* it was on the stack I couldn't use the ability despite having land in
* hand which isn't something I've had an issue with before.
*
* <p>
* My opponent had a Leyline of Sanctity in play, so perhaps that was
* causing the issue somehow? Does anyone want to try and replicate it?
*
*/
@Test
public void ActivateByBothPlayersTest() {
@ -31,22 +28,32 @@ public class LightningStormTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Mountain");
addCard(Zone.HAND, playerB, "Mountain");
// A activate
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Storm", playerB);
// B discard and re-target
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Discard");
setChoice(playerB, "playerA");
setChoice(playerB, "Mountain");
setChoice(playerB, "Yes");
addTarget(playerB, playerA);
// A discard and re-target
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Discard");
setChoice(playerA, "playerB");
setChoice(playerA, "Mountain");
setChoice(playerA, "Yes");
addTarget(playerA, playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Lightning Storm", 1);
assertGraveyardCount(playerB, "Mountain", 1);
assertGraveyardCount(playerA, "Mountain", 1);
assertLife(playerA, 20);
assertLife(playerB, 13);
assertLife(playerB, 20 - 3 - 2 - 2);
}
}

View file

@ -24,7 +24,7 @@ public class AddAbilitiesToNonPermanentsTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
// Flash
// Creature cards you own that aren't on the battlefield have flash.
// Each opponent can cast spells only any time he or she could cast a sorcery.
// Each opponent can cast spells only any time they could cast a sorcery.
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Mage of Zhalfir");
// Search your library for an instant card or a card with flash, reveal it, and put it into your hand. Then shuffle your library.

View file

@ -15,7 +15,7 @@ public class CursesTest extends CardTestPlayerBase {
Cruel Reality {5}{B}{B}
Enchantment - Aura Curse
Enchant player
At the beginning of enchanted player's upkeep, that player sacrifices a creature or planeswalker. If the player can't, he or she loses 5 life.
At the beginning of enchanted player's upkeep, that player sacrifices a creature or planeswalker. If the player can't, they lose 5 life.
*/
private String cReality = "Cruel Reality";
@ -43,7 +43,7 @@ public class CursesTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
// Enchant player
// Whenever enchanted player casts an instant or sorcery spell, each other player may copy that
// spell and may choose new targets for the copy he or she controls.
// spell and may choose new targets for the copy they control.
addCard(Zone.HAND, playerA, "Curse of Echoes");
// Draw three cards.
addCard(Zone.HAND, playerB, "Jace's Ingenuity");

View file

@ -23,7 +23,7 @@ public class WarpWorldTest extends CardTestPlayerBase {
*/
@Test
public void testWarpWorld() {
// Each player shuffles all permanents he or she owns into their library, then reveals that many cards from the top of their library.
// Each player shuffles all permanents they own into their library, then reveals that many cards from the top of their library.
// Each player puts all artifact, creature, and land cards revealed this way onto the battlefield, then does the same for enchantment cards,
// then puts all cards revealed this way that weren't put onto the battlefield on the bottom of their library.
addCard(Zone.HAND, playerA, "Warp World"); // Sorcery {5}{R}{R}{R}

View file

@ -157,7 +157,7 @@ public class CloudshiftTest extends CardTestPlayerBase {
/*
I had a Stoneforge Mystic equipped with a Umesawa's Jitte. I activated Jitte 4 times to make
Stoneforge Mystic 9/10. My opponent put into play a Flickerwisp with his Aether Vial and
Stoneforge Mystic 9/10. My opponent put into play a Flickerwisp with their Aether Vial and
targeted my Stoneforge Mystic. At the end of my turn, Stoneforge Mystic came back as a 9/10,
before going down to 1/2 normally once my turn ended.
*/

View file

@ -36,7 +36,7 @@ public class EchoTest extends CardTestPlayerBase {
// cast Avalanche Riders and destroy forest
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Avalanche Riders");
addTarget(playerA, "Forest");
@ -45,10 +45,19 @@ public class EchoTest extends CardTestPlayerBase {
activateManaAbility(3, PhaseStep.UPKEEP, playerA, "{T}: Add {W}");
activateManaAbility(3, PhaseStep.UPKEEP, playerA, "{T}: Add {W}");
activateManaAbility(3, PhaseStep.UPKEEP, playerA, "{T}: Add {W}");
castSpell(3, PhaseStep.UPKEEP, playerA, "Restoration Angel", null, "Echo {3}{R} <i>(At the beginning of your upkeep, if this came under your control since the beginning of your last upkeep, sacrifice it unless you pay its echo cost.)</i>");
castSpell(3, PhaseStep.UPKEEP, playerA, "Restoration Angel");
addTarget(playerA, "Avalanche Riders");
setChoice(playerA, "Yes"); // raider do restore
// Avalanche Riders triggered again
addTarget(playerA, "Forest");
// but no echo for blinked rider
setStrictChooseMode(true);
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20);
@ -56,7 +65,8 @@ public class EchoTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Avalanche Riders", 1);
assertPermanentCount(playerA, "Restoration Angel", 1);
assertPermanentCount(playerB, "Forest", 0);
assertPermanentCount(playerA, "Forest", 0);
assertGraveyardCount(playerA, "Forest", 2);
assertTappedCount("Plains", true, 4);
assertTappedCount("Mountain", true, 0);
}

View file

@ -128,7 +128,7 @@ public class FlashbackTest extends CardTestPlayerBase {
/**
* My opponent put Iona on the battlefield using Unburial Rites, but my game
* log didn't show me the color he has chosen.
* log didn't show me the color they chose.
*/
@Test
public void testUnburialRites() {

View file

@ -11,17 +11,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class KickerWithFlashbackTest extends CardTestPlayerBase {
// https://github.com/magefree/mage/issues/5389
// Burst Lightning {R}
// Kicker {4} (You may pay an additional {4} as you cast this spell.)
// Burst Lightning deals 2 damage to any target. If this spell was kicked, it deals 4 damage to that permanent or player instead.
// Snapcaster Mage {1}{U}
// Flash
// When Snapcaster Mage enters the battlefield, target instant or sorcery card in your graveyard gains flashback until end of turn.
// The flashback cost is equal to its mana cost. (You may cast that card from your graveyard for its flashback cost. Then exile it.)
@Test
public void test_SimpleKicker() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -79,7 +75,7 @@ public class KickerWithFlashbackTest extends CardTestPlayerBase {
addTarget(playerA, "Burst Lightning");
// cast burst by flashback
showAvaileableAbilities("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
// showAvaileableAbilities("after", 1, PhaseStep.BEGIN_COMBAT, playerA);
activateAbility(1, PhaseStep.BEGIN_COMBAT, playerA, "Flashback");
setChoice(playerA, "Yes"); // use kicker
addTarget(playerA, playerB);

View file

@ -21,7 +21,7 @@ public class MadnessTest extends CardTestPlayerBase {
* If a player would discard this card, that player discards it, but may
* exile it instead of putting it into their graveyard and When this
* card is exiled this way, its owner may cast it by paying [cost] rather
* than paying its mana cost. If that player doesn't, he or she puts this
* than paying its mana cost. If that player doesn't, they put this
* card into their graveyard. 702.34b Casting a spell using its
* madness ability follows the rules for paying alternative costs in rules
* 601.2b and 601.2eg.

View file

@ -213,8 +213,8 @@ public class ManifestTest extends CardTestPlayerBase {
skipInitShuffling();
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
// showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Silence the Believers", EmptyNames.FACE_DOWN_CREATURE.toString());
setStopAt(1, PhaseStep.END_TURN);

View file

@ -362,10 +362,10 @@ public class MorphTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler", NO_TARGET, "Sagu Mauler", StackClause.WHILE_NOT_ON_STACK);
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Echoing Decay", EmptyNames.FACE_DOWN_CREATURE.toString());
showBattlefield("A battle after", 1, PhaseStep.END_TURN, playerA);
// showBattlefield("A battle after", 1, PhaseStep.END_TURN, playerA);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
@ -540,14 +540,14 @@ public class MorphTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Fury");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
// showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Supplant Form");
addTarget(playerB, EmptyNames.FACE_DOWN_CREATURE.toString());
showBattlefield("A battle end", 1, PhaseStep.END_TURN, playerA);
showBattlefield("B battle end", 1, PhaseStep.END_TURN, playerB);
// showBattlefield("A battle end", 1, PhaseStep.END_TURN, playerA);
// showBattlefield("B battle end", 1, PhaseStep.END_TURN, playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
@ -717,14 +717,20 @@ public class MorphTest extends CardTestPlayerBase {
* not work correctly. When Vesuvan Shapeshifter turns face up and becomes a
* copy of the targeted creature, it should still be in the state of
* "turning face up", thus triggering the ability of the Brine Elemental.
* <p>
* combo: Vesuvan Shapeshifter + Brine Elemental Brine Elemental in play,
* Vesuvan Shapeshifter in hand 1) Cast Vesuvan Shapeshifter face-down. 2)
* Flip Vesuvan Shapeshifter for its morph cost, copying Brine Elemental.
* Your opponent skips his next untap. 3) During your upkeep, flip Vesuvan
* Shapeshifter face-down. 4) Repeat from 2.
*/
@Test
public void testVesuvanShapeshifter() {
// Morph {5}{U}{U}
// When Brine Elemental is turned face up, each opponent skips their next untap step.
addCard(Zone.HAND, playerA, "Brine Elemental"); // Creature {4}{U}{U} 5/4
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
addCard(Zone.BATTLEFIELD, playerA, "Brine Elemental"); // Creature {4}{U}{U} 5/4
//addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
// As Vesuvan Shapeshifter enters the battlefield or is turned face up, you may choose another creature on the battlefield.
// If you do, until Vesuvan Shapeshifter is turned face down, it becomes a copy of that creature
@ -733,23 +739,23 @@ public class MorphTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Vesuvan Shapeshifter"); // Creature 0/0
addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brine Elemental");
setChoice(playerA, "No"); // cast it normally
// 1. Cast Vesuvan as face-down
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Vesuvan Shapeshifter");
setChoice(playerB, "Yes");
setChoice(playerB, "Yes"); // cast as face-down
// 2. Moth Vesuvan and copy brine
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{1}{U}: Turn this face-down permanent");
setChoice(playerB, "Brine Elemental");
addTarget(playerB, "Brine Elemental");
// No face up trigger and choose from Vesuvan
// But brine's trigger must works on next turn 3 (skip untap)
setStrictChooseMode(true);
setStopAt(2, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Brine Elemental", 1);
assertPermanentCount(playerB, "Brine Elemental", 1);
Assert.assertTrue("Skip next turn has to be added to TurnMods", currentGame.getState().getTurnMods().size() == 1);
}

View file

@ -133,12 +133,12 @@ public class SpliceOnArcaneTest extends CardTestPlayerBase {
* The scenario was that I cast a Nourishing Shoal with a Goryo's Vengeance
* spliced to it targeting Griselbrand in my graveyard and exiling
* Worldspine Wurm. My opponent responded with a Snapcaster Mage, so to
* deprive him of his ability to reuse his counterspell, I cast the Goryo's
* Vengeance on the Griselbrand. This one resolved. He then used Terminate
* on the Griselbrand after I had activated it once. When the Shoal tried to
* resolve, it should have been countered due to no legal target. However,
* it caused me to gain 11 life. It did not resurrect Griselbrand
* (correctly), but it should have done nothing at all.
* deprive them of their ability to reuse their counterspell, I cast the
* Goryo's Vengeance on the Griselbrand. This one resolved. They then used
* Terminate on the Griselbrand after I had activated it once. When the
* Shoal tried to resolve, it should have been countered due to no legal
* target. However, it caused me to gain 11 life. It did not resurrect
* Griselbrand (correctly), but it should have done nothing at all.
* <p>
* I include the info about the Terminate because thinking through, it could
* be pertinent. I would guess what is going on here is one of two things.

View file

@ -177,7 +177,7 @@ public class SuspendTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 3);
// Imprint - When Knowledge Pool enters the battlefield, each player exiles the top three cards of their library
// Whenever a player casts a spell from their hand, that player exiles it. If the player does, he or she may cast another nonland card
// Whenever a player casts a spell from their hand, that player exiles it. If the player does, they may cast another nonland card
// exiled with Knowledge Pool without paying that card's mana cost.
addCard(Zone.HAND, playerB, "Knowledge Pool", 1);
addCard(Zone.BATTLEFIELD, playerB, "Plains", 6);

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep;
@ -362,4 +361,54 @@ public class TransformTest extends CardTestPlayerBase {
}
/**
* Having cast Phantasmal Image copying my opponent's flipped Thing in the
* Ice, I was left with a 0/4 Awoken Horror.
*
* https://github.com/magefree/mage/issues/5893
*
* The transform effect on the stack should fizzle. The card brought back
* from Exile should be a new object unless I am interpreting the rules
* incorrectly. The returned permanent uses the same GUID.
*/
@Test
public void testCopyTransformedThingInTheIce() {
// Defender
// Thing in the Ice enters the battlefield with four ice counters on it.
// Whenever you cast an instant or sorcery spell, remove an ice counter from Thing in the Ice. Then if it has no ice counters on it, transform it.
addCard(Zone.HAND, playerA, "Thing in the Ice"); // Creature {1}{U}
// Creatures you control get +1/+0 until end of turn.
addCard(Zone.HAND, playerA, "Banners Raised", 4); // Creature {R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
// You may have Phantasmal Image enter the battlefield as a copy of any creature
// on the battlefield, except it's an Illusion in addition to its other types and
// it has "When this creature becomes the target of a spell or ability, sacrifice it."
addCard(Zone.HAND, playerB, "Phantasmal Image", 1); // Creature {1}{U}
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Thing in the Ice");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Banners Raised");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Banners Raised");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Banners Raised");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Banners Raised");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Phantasmal Image");
addTarget(playerB, "Awoken Horror");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertGraveyardCount(playerA, "Banners Raised", 4);
assertPermanentCount(playerA, "Thing in the Ice", 0);
assertPermanentCount(playerA, "Awoken Horror", 1);
assertPowerToughness(playerA, "Awoken Horror", 7, 8);
assertPermanentCount(playerB, "Awoken Horror", 1);
assertPowerToughness(playerB, "Awoken Horror", 7, 8);
}
}

View file

@ -14,7 +14,7 @@ public class CitadelOfPainTest extends CardTestPlayerBase {
public void testDamage() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// At the beginning of each player's end step, Citadel of Pain deals X damage to that
// player, where X is the number of untapped lands he or she controls.
// player, where X is the number of untapped lands they control.
addCard(Zone.BATTLEFIELD, playerA, "Citadel of Pain");
setStopAt(1, PhaseStep.END_TURN);

View file

@ -15,7 +15,7 @@ public class PowerSurgeTest extends CardTestPlayerBase {
@Test
public void testDamageInPlayer() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands he or she controlled at the beginning of this turn.
// At the beginning of each player's upkeep, Power Surge deals X damage to that player, where X is the number of untapped lands they controlled at the beginning of this turn.
addCard(Zone.HAND, playerA, "Power Surge");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);

View file

@ -15,7 +15,7 @@ public class DestroyTheEvidanceTest extends CardTestPlayerBase {
// Destroy the Evidence - Sorcery {4}{B}
// Destroy target land. Its controller reveals cards from the top of his
// or her library until he or she reveals a land card, then puts those cards into their graveyard.
// or her library until they reveal a land card, then puts those cards into their graveyard.
/**
* The target land is destroyed

View file

@ -16,7 +16,7 @@ public class RoonOfTheHiddenRealmTest extends CardTestPlayerBase {
* Roon of the Hidden Realm is returning cards to their controler's control
* instead of the owner's control at the end of the turn. I used his ability
* on a Perplexing Chimera I gave my opponent and in the end of the turn it
* returned to the battlefield in his control.
* returned to the battlefield in their control.
*/
@Test
public void testReturnToBattlefieldForOwner() {

View file

@ -13,7 +13,7 @@ public class PaupersCageTest extends CardTestPlayerBase {
// Paupers' Cage
// At the beginning of each opponent's upkeep, if that player has two or fewer cards in hand,
// Paupers' Cage deals 2 damage to him or her.
// Paupers' Cage deals 2 damage to that player.
@Test
public void test_TooManyCards() {

View file

@ -0,0 +1,128 @@
package org.mage.test.cards.asthough;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class PlayTopCardFromLibraryTest extends CardTestPlayerBase {
/*
Bolas's Citadel
{3}{B}{B}{B}
You may look at the top card of your library any time.
You may play the top card of your library. If you cast a spell this way, pay life equal to its converted mana cost rather than pay its mana cost.
{T}, Sacrifice ten nonland permanents: Each opponent loses 10 life.
*/
@Test
public void test_CreaturePlay() {
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears"); // 2 CMC
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Balduvian Bears", 1);
assertLife(playerA, 20 - 2);
}
@Test
public void test_CreaturePlay2() {
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Balduvian Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
addCard(Zone.BATTLEFIELD, playerA, "Vizier of the Menagerie", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Balduvian Bears", 1);
}
@Test
public void test_ManaCostmodifications() {
//
// {5}{B}{B}
// You may cast Scourge of Nel Toth from your graveyard by paying {B}{B} and sacrificing two creatures rather than paying its mana cost.
addCard(Zone.GRAVEYARD, playerA, "Scourge of Nel Toth", 1);
addCard(Zone.BATTLEFIELD, playerA, "Kitesail Corsair", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scourge of Nel Toth");
setChoice(playerA, "Kitesail Corsair");
setChoice(playerA, "Kitesail Corsair");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Scourge of Nel Toth", 1);
assertLife(playerA, 20);
}
@Test
public void test_SplitRightPlay() {
// https://github.com/magefree/mage/issues/5912
// Bolas's citadel requires you to pay mana instead of life for a split card on top of library.
//
// Steps to reproduce:
//
// Bolas's Citadel in play, Revival//Revenge on top of library.
// Cast Revenge, choose target
// receive prompt to pay 4WB.
//
// Expected outcome
//
// No prompt for mana payment, payment of six life instead.
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Revival // Revenge", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1);
// Double your life total. Target opponent loses half their life, rounded up.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Revenge", playerB); // {4}{W}{B} = 6 life
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertLife(playerA, (20 - 6) * 2);
assertLife(playerB, 20 / 2);
}
@Test
public void test_SplitLeftPlay() {
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Revival // Revenge", 1);
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel", 1);
addCard(Zone.GRAVEYARD, playerA, "Balduvian Bears", 1);
// Return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Revival", "Balduvian Bears"); // {W/B}{W/B} = 2 life
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20 - 2);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Balduvian Bears", 0);
assertPermanentCount(playerA, "Balduvian Bears", 1);
}
}

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.asthough;
import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class SpendOtherManaTest extends CardTestPlayerBase {
@ -47,7 +45,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
/**
* Tron mana doesn't work with Oath of Nissa. (e.g. can't cast Chandra,
* Flamecaller with Urza's Tower, Power Plant, and Mine.)
*
* <p>
* AI don't get the Planeswalker as playable card (probably because of the
* as thought effect)
*/
@ -76,7 +74,7 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
* I was unable to cast Nissa, Voice of Zendikar using black mana with Oath
* of Nissa in play. Pretty sure Oath is working usually, so here were the
* conditions in my game:
*
* <p>
* -Cast Dark Petition with spell mastery -Attempt to cast Nissa, Voice of
* Zendikar using the triple black mana from Dark Petition
*/
@ -122,20 +120,84 @@ public class SpendOtherManaTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Hostage Taker"); // {2}{U}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hostage Taker");
setChoice(playerA, "Silvercoat Lion");
addTarget(playerA, "Silvercoat Lion");
// red mana must be used as any mana
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
activateManaAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{T}: Add {R}."); // red mana to pool
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Silvercoat Lion"); // cast it from exile with red mana from pool
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Hostage Taker", 1);
assertTappedCount("Mountain", true, 4);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
}
@Test
public void test_QuicksilverElemental_Normal() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
// You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elementals abilities.
addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
// {R}, {T}: Anaba Shaman deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
// gain abilities
checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
// use ability
checkPlayableAbility("must have new ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20 - 1);
}
@Test
public void test_QuicksilverElemental_Flicker() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// {U}: Quicksilver Elemental gains all activated abilities of target creature until end of turn.
// You may spend blue mana as though it were mana of any color to pay the activation costs of Quicksilver Elementals abilities.
addCard(Zone.BATTLEFIELD, playerA, "Quicksilver Elemental"); // Creature {1}{W}
// {R}, {T}: Anaba Shaman deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerB, "Anaba Shaman");
// Exile target nontoken permanent, then return it to the battlefield under its owners control.
addCard(Zone.HAND, playerA, "Flicker"); // {1}{W}
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
// gain abilities
checkPlayableAbility("must not have", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", false);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{U}:", "Anaba Shaman");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPlayableAbility("must have new ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}, {T}:", true);
// renew target
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flicker", "Anaba Shaman");
// use ability
checkPlayableAbility("must save ability", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", true);
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{R}, {T}:", playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Flicker", 1);
assertLife(playerA, 20);
assertLife(playerB, 20 - 1);
}
}

View file

@ -76,7 +76,7 @@ public class TragicSlipTest extends CardTestPlayerBase {
}
/*
Killed an opponent's Young Pyromancer with Ulcerate then flashed back Tragic Slip with Snapcaster Mage targeting his Tarmogoyf.
Killed an opponent's Young Pyromancer with Ulcerate then flashed back Tragic Slip with Snapcaster Mage targeting their Tarmogoyf.
Morbid didn't seem to work and only applied -1/-1 to the Tarmogoyf.
*/
@Test

View file

@ -83,11 +83,13 @@ public class AngelOfJubilationTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Food Chain");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, Sacrifice a permanent you control: Return target creature to its owner's hand.");
playerB.addChoice("Food Chain");
playerA.addTarget("Angel of Jubilation");
addTarget(playerB, "Angel of Jubilation"); // return to hand
setChoice(playerB, "Food Chain"); // cacrifice cost
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Angel of Jubilation", 0);
assertPermanentCount(playerB, "Food Chain", 0);

View file

@ -12,13 +12,12 @@ import org.mage.test.serverside.base.CardTestCommander4Players;
public class CommandersCastTest extends CardTestCommander4Players {
// Player order: A -> D -> C -> B
@Test
public void test_CastToBattlefieldOneTime() {
addCard(Zone.COMMAND, playerA, "Balduvian Bears", 1); // {1}{G}, 2/2, commander
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
showCommand("commanders", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showCommand("commanders", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears");
setStopAt(1, PhaseStep.END_TURN);
@ -71,7 +70,7 @@ public class CommandersCastTest extends CardTestCommander4Players {
public void test_PlayAsLandOneTime() {
addCard(Zone.COMMAND, playerA, "Academy Ruins", 1);
showAvaileableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Academy Ruins");
//castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Academy Ruins");
@ -114,8 +113,7 @@ public class CommandersCastTest extends CardTestCommander4Players {
waitStackResolved(5, PhaseStep.POSTCOMBAT_MAIN);
checkPermanentCount("after cast 2", 5, PhaseStep.POSTCOMBAT_MAIN, playerA, "Academy Ruins", 1);
showBattlefield("end battlefield", 5, PhaseStep.END_TURN, playerA);
// showBattlefield("end battlefield", 5, PhaseStep.END_TURN, playerA);
setStopAt(5, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();
@ -261,7 +259,7 @@ public class CommandersCastTest extends CardTestCommander4Players {
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 2);
// cast overload
showAvaileableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Weapon Surge with overload");
setChoice(playerA, "Yes"); // move to command zone
checkAbility("after", 1, PhaseStep.BEGIN_COMBAT, playerA, "Balduvian Bears", FirstStrikeAbility.class, true);

View file

@ -134,4 +134,60 @@ public class ConditionalPreventionTest extends CardTestPlayerBase {
assertHandCount(playerA, "Lightning Bolt", 0);
}
@Test
public void test_PrentableCombatDamage() {
// Prevent all damage that would be dealt to creatures.
addCard(Zone.BATTLEFIELD, playerA, "Bubble Matrix", 1);
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
//
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// player A must do damage
attack(1, playerA, "Balduvian Bears", playerB);
// player B can't do damage (bears must block and safe)
attack(4, playerB, "Balduvian Bears", playerA);
block(4, playerA, "Balduvian Bears", "Balduvian Bears");
setStrictChooseMode(true);
setStopAt(4, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Balduvian Bears", 1);
assertPermanentCount(playerB, "Balduvian Bears", 1);
assertLife(playerA, 20);
assertLife(playerB, 20 - 2);
}
@Test
public void test_UnpreventableCombatDamage() {
// Combat damage that would be dealt by creatures you control can't be prevented.
addCard(Zone.BATTLEFIELD, playerB, "Questing Beast", 1);
//
// Prevent all damage that would be dealt to creatures.
addCard(Zone.BATTLEFIELD, playerA, "Bubble Matrix", 1);
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
//
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// player A must do damage
attack(1, playerA, "Balduvian Bears", playerB);
// player B must be prevented by Bubble Matrix, but can't (Questing Beast)
// a -> b -- can't do damage (matrix)
// b -> a -- can do damage (matrix -> quest)
attack(4, playerB, "Balduvian Bears", playerA);
block(4, playerA, "Balduvian Bears", "Balduvian Bears");
setStrictChooseMode(true);
setStopAt(4, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Balduvian Bears", 0);
assertPermanentCount(playerB, "Balduvian Bears", 1);
assertLife(playerA, 20);
assertLife(playerB, 20 - 2);
}
}

View file

@ -29,7 +29,7 @@ public class DaxosTheReturnedTest extends CardTestPlayerBase {
// "This creature's power and toughness are each equal to the number of experience counters you have."
addCard(Zone.BATTLEFIELD, playerA, "Daxos the Returned");
// Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
// Whenever an opponent draws a card, Underworld Dreams deals 1 damage to that player.
addCard(Zone.HAND, playerA, "Underworld Dreams", 2); // {B}{B}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Underworld Dreams");

View file

@ -153,4 +153,58 @@ public class EndOfTurnMultiOpponentsTest extends CardTestMultiPlayerBaseWithRang
assertAllCommandsUsed();
}
// leaved players
// 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
// or until a specific point in that turn will last until that turn would have begun.
// They neither expire immediately nor last indefinitely.
@Test
public void test_UntilYourNextTurnMulti_Leaved() {
// Player order: A -> D -> C -> B
addCustomCardWithAbility("boost1", playerA, new SimpleStaticAbility(Zone.ALL, new BoostAllEffect(1, 1, Duration.UntilYourNextTurn)));
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 1, playerA, true, PhaseStep.END_TURN);
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 2, playerD, true, PhaseStep.END_TURN);
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 3, playerC, true, PhaseStep.END_TURN);
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 4, playerB, true, PhaseStep.END_TURN);
EndOfTurnOneOpponentTest.prepareStepChecks(this, "Duration.UntilYourNextTurn effect", 5, playerD, true, null);
addCard(Zone.BATTLEFIELD, playerA, cardBear2, 1);
addCard(Zone.BATTLEFIELD, playerB, cardBear2, 1);
addCard(Zone.BATTLEFIELD, playerC, cardBear2, 1);
addCard(Zone.BATTLEFIELD, playerD, cardBear2, 1);
//
// When Eye of Doom enters the battlefield, each player chooses a nonland permanent and puts a doom counter on it.
addCard(Zone.HAND, playerC, "Eye of Doom", 1);
addCard(Zone.BATTLEFIELD, playerC, "Forest", 4);
checkPlayerInGame("A must plays in 1", 1, PhaseStep.PRECOMBAT_MAIN, playerA, playerA, true);
attack(1, playerA, cardBear2);
checkPlayerInGame("A must plays in 2", 2, PhaseStep.PRECOMBAT_MAIN, playerD, playerA, true);
attack(2, playerD, cardBear2);
checkPlayerInGame("A must plays in 3 before", 3, PhaseStep.PRECOMBAT_MAIN, playerC, playerA, true);
attack(3, playerC, cardBear2);
concede(3, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPlayerInGame("A must leaved in 3 after", 3, PhaseStep.POSTCOMBAT_MAIN, playerC, playerA, false);
// test PlayerList.getNext processing
// play Eye of Doom, ask all players to put doom counter
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerC, "Eye of Doom");
addTarget(playerC, cardBear2);
addTarget(playerB, cardBear2);
//addTarget(playerA, cardBear2); // leaved
addTarget(playerD, cardBear2);
checkPlayerInGame("A must leaved in 4", 4, PhaseStep.POSTCOMBAT_MAIN, playerB, playerA, false);
attack(4, playerB, cardBear2);
checkPlayerInGame("A must leaved in 5", 5, PhaseStep.POSTCOMBAT_MAIN, playerD, playerA, false);
attack(5, playerD, cardBear2);
setStopAt(5, PhaseStep.CLEANUP);
setStrictChooseMode(true);
execute();
assertAllCommandsUsed();
}
}

View file

@ -188,7 +188,7 @@ public class LandTypeChangingEffectsTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
// At the beginning of each player's upkeep, that player puts a flood counter on target non-Island land he or she controls of their choice.
// At the beginning of each player's upkeep, that player puts a flood counter on target non-Island land they control of their choice.
// That land is an Island for as long as it has a flood counter on it.
// At the beginning of each end step, if all lands on the battlefield are Islands, remove all flood counters from them.
addCard(Zone.HAND, playerB, "Quicksilver Fountain", 1); // Artifact {3}

View file

@ -0,0 +1,137 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.test.cards.continuous;
import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
import mage.abilities.Ability;
import mage.abilities.keyword.FlashAbility;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author drmDev
*/
public class MerfolkTricksterTest extends CardTestPlayerBase {
/*
Merfolk Trickster (UU)
Creature Merfolk Wizard
Flash
When Merfolk Trickster enters the battlefield, tap target creature an opponent controls. It loses all abilities until end of turn.
*/
public final String mTrickster = "Merfolk Trickster";
@Test
public void test_TricksterAndFlyer_FlyingRemoved() {
addCard(Zone.BATTLEFIELD, playerA, "Flying Men"); // (U) 1/1 flyer
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.HAND, playerB, mTrickster);
attack(1, playerA, "Flying Men");
castSpell(1, PhaseStep.DECLARE_BLOCKERS, playerB, mTrickster);
addTarget(playerB, "Flying Men");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
assertTappedCount("Island", true, 2);
assertTapped("Flying Men", true);
Abilities<Ability> noAbilities = new AbilitiesImpl<>();
assertAbilities(playerA, "Flying Men", noAbilities); // no abilities, empty list
Abilities<Ability> flashAbility = new AbilitiesImpl<>();
flashAbility.add(FlashAbility.getInstance());
assertAbilities(playerB, mTrickster, flashAbility); // has flash
assertAllCommandsUsed();
}
@Test
public void test_TricksterAndFlyerBlocked_FlyingRemovedAndBlocked() {
addCard(Zone.BATTLEFIELD, playerA, "Flying Men"); // (U) 1/1 flyer
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.HAND, playerB, mTrickster);
attack(1, playerA, "Flying Men");
castSpell(1, PhaseStep.DECLARE_ATTACKERS, playerB, mTrickster);
addTarget(playerB, "Flying Men");
block(1, playerB, mTrickster, "Flying Men");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertTappedCount("Island", true, 2);
assertGraveyardCount(playerA, "Flying Men", 1);
assertPermanentCount(playerB, mTrickster, 1);
assertDamageReceived(playerB, mTrickster, 1);
assertAllCommandsUsed();
}
@Test
public void test_TricksterBlocksFootlightFiend_Survives() {
addCard(Zone.BATTLEFIELD, playerA, "Footlight Fiend"); // (R/B) 1/1 on death pings any target for 1
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.HAND, playerB, mTrickster);
attack(1, playerA, "Footlight Fiend");
castSpell(1, PhaseStep.DECLARE_ATTACKERS, playerB, mTrickster);
addTarget(playerB, "Footlight Fiend");
block(1, playerB, mTrickster, "Footlight Fiend");
addTarget(playerA, mTrickster);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertTappedCount("Island", true, 2);
assertPermanentCount(playerB, mTrickster, 1);
assertDamageReceived(playerB, mTrickster, 1);
//assertAllCommandsUsed(); // uncommenting this will force a failure since PlayerA cannot do a command to target Trickster, as expected
}
@Test
public void test_TricksterBlocksTibaltToken_Survives() {
/*
Tibalt, Rakish Instigator (2R)
Legendary Planeswalker Tibalt
Your opponents can't gain life.
-2: Create a 1/1 red Devil creature token with "When this creature dies, it deals 1 damage to any target."
*/
addCard(Zone.BATTLEFIELD, playerA, "Tibalt, Rakish Instigator");
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.HAND, playerB, mTrickster);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:");
attack(3, playerA, "Devil");
castSpell(3, PhaseStep.DECLARE_ATTACKERS, playerB, mTrickster);
addTarget(playerB, "Devil");
block(3, playerB, mTrickster, "Devil");
addTarget(playerA, mTrickster);
setStopAt(3, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertCounterCount("Tibalt, Rakish Instigator", CounterType.LOYALTY, 3);
assertTappedCount("Island", true, 2);
assertPermanentCount(playerB, mTrickster, 1);
assertDamageReceived(playerB, mTrickster, 1);
// assertAllCommandsUsed(); // uncommenting this should force a failure since PlayerA cannot do a command to target Trickster, as expected
}
}

View file

@ -18,7 +18,7 @@ public class PlayerLeavesGameTest extends CardTestMultiPlayerBaseWithRangeAll {
which give that player control of any objects or players end. Then, if that player controlled any objects on the stack
not represented by cards, those objects cease to exist. Then, if there are any objects still controlled by that player,
those objects are exiled. This is not a state-based action. It happens as soon as the player leaves the game.
If the player who left the game had priority at the time he or she left, priority passes to the next player in turn
If the player who left the game had priority at the time they left, priority passes to the next player in turn
order whos still in the game.
*/

View file

@ -22,8 +22,7 @@ public class PraetorsGraspTest extends CardTestPlayerBase {
addTarget(playerA, playerB);
addTarget(playerA, "Mountain");
showAvaileableAbilities("after", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showAvaileableAbilities("after", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.continuous;
import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
@ -23,20 +21,22 @@ public class PsychicIntrusionTest extends CardTestPlayerBase {
// Target opponent reveals their hand. You choose a nonland card from that player's
// graveyard or hand and exile it. You may cast that card for as long as it remains exiled,
// and you may spend mana as though it were mana of any color to cast that spell.
addCard(Zone.HAND, playerA, "Psychic Intrusion", 1);
addCard(Zone.HAND, playerA, "Psychic Intrusion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.HAND, playerB, "Elspeth, Sun's Champion", 1);
addCard(Zone.HAND, playerB, "Elspeth, Sun's Champion", 1); // {4}{W}{W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB);
addTarget(playerA, "Elspeth, Sun's Champion");
setChoice(playerA, "Elspeth, Sun's Champion");
// cast from exile with any mana
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Elspeth, Sun's Champion");
setStrictChooseMode(true);
setStopAt(3, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Psychic Intrusion", 1);
assertHandCount(playerB, "Elspeth, Sun's Champion", 0);

View file

@ -14,12 +14,12 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class SerraAscendantTest extends CardTestPlayerBase {
/**
* The game goes on; he plays his Serra Ascendant on turn one, passes the
* The game goes on; they play Serra Ascendant on turn one, pass the
* turn, you play your newly unbanned Wild Nacatl with a Stomping Ground and
* also pass the turn. On turn 2, he casts a Martyr of Sands and sacrifices
* it, revealing 3 white cards to gain 9 life and end up at 29. He goes to
* the combat phase, declares Serra as an attacker, and you happily block
* him, thinking that this is such a bad move from him. After the damage is
* also pass the turn. On turn 2, they cast a Martyr of Sands and sacrifice
* it, revealing 3 white cards to gain 9 life and end up at 29. They go to
* the combat phase, declare Serra as an attacker, and you happily block
* him, thinking that this is such a bad move from them. After the damage is
* dealt, the Serra is still there, bigger than ever.
*/
@Test

View file

@ -15,7 +15,7 @@ public class BronzeBombshellTest extends CardTestPlayerBase {
@Test
public void testEndlessWhispers() {
// When a player other than Bronze Bombshell's owner controls it, that player sacrifices it.
// If the player does, Bronze Bombshell deals 7 damage to him or her.
// If the player does, Bronze Bombshell deals 7 damage to the player.
addCard(Zone.BATTLEFIELD, playerA, "Bronze Bombshell", 1);
// Each creature has "When this creature dies, choose target opponent.

View file

@ -110,7 +110,7 @@ public class ExileAndReturnUnderYourControl extends CardTestPlayerBase {
/**
* My opponent cast Villainous Wealth and took control of my Sylvan Library.
* On his next turn, when Sylvan Library's trigger resolved, he kept the two
* On their next turn, when Sylvan Library's trigger resolved, they kept the two
* extra cards without paying life.
*/
@Test

View file

@ -42,10 +42,12 @@ public class GainControlDiedCastAgainTest extends CardTestPlayerBase {
attack(2, playerB, "Elesh Norn, Grand Cenobite");
block(2, playerA, "Keiga, the Tide Star", "Elesh Norn, Grand Cenobite");
addTarget(playerB, "Elesh Norn, Grand Cenobite");
addTarget(playerA, "Elesh Norn, Grand Cenobite");
setStrictChooseMode(true);
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20);

View file

@ -5,6 +5,7 @@
*/
package org.mage.test.cards.copy;
import mage.constants.CardType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
@ -56,4 +57,37 @@ public class CopyCreatureCardToTokenImplTest extends CardTestPlayerBase {
assertGraveyardCount(playerA, 2);
}
/* https://github.com/magefree/mage/issues/5904
I had a Faerie Artisans on the battlefield. My opponent played a Thrashing Brontodon.
In response to the Faerie Artisans ability, my opponent sacrificed the Brontodon to destroy an artifact.
When the Faerie Artisans trigger resolved, no token was created. */
@Test
public void testFaerieArtisans() {
// Flying
// Whenever a nontoken creature enters the battlefield under an opponent's control,
// create a token that's a copy of that creature except it's an artifact in addition to its other types.
// Then exile all other tokens created with Faerie Artisans.
addCard(Zone.BATTLEFIELD, playerA, "Faerie Artisans", 1); // Creature {3}{U}
addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr", 1); // Artifact creature 2/1
// {1}, Sacrifice Thrashing Brontodon: Destroy target artifact or enchantment.
addCard(Zone.HAND, playerB, "Thrashing Brontodon"); // Creature {1}{G}{G}
addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Thrashing Brontodon");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}, Sacrifice");
addTarget(playerB, "Alpha Myr");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerB, "Thrashing Brontodon", 1);
assertGraveyardCount(playerA, "Alpha Myr", 1);
assertPermanentCount(playerA, "Thrashing Brontodon", 1);
assertType("Thrashing Brontodon", CardType.ARTIFACT, true);
}
}

View file

@ -14,7 +14,7 @@ public class CopySpellTest extends CardTestPlayerBase {
@Test
public void copyChainOfVapor() {
// Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, he or she may copy this spell and may choose a new target for that copy.
// Return target nonland permanent to its owner's hand. Then that permanent's controller may sacrifice a land. If the player does, they may copy this spell and may choose a new target for that copy.
addCard(Zone.HAND, playerA, "Chain of Vapor", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 10);
@ -77,11 +77,14 @@ public class CopySpellTest extends CardTestPlayerBase {
assertAbility(playerB, "Silvercoat Lion", FlyingAbility.getInstance(), false);
}
/**
/*
* Reported bug: "Silverfur Partisan and fellow wolves did not trigger off
* of copies of Strength of Arms made by Zada, Hedron Grinder. Not sure
* about other spells, but I imagine similar results."
*/
// Perhaps someone knows the correct implementation for this test.
// Just target the Silverfur Partisan and hit done
// This test works fine in game. The @Ignore would not work for me either.
@Test
public void ZadaHedronSilverfurPartisan() {
@ -98,18 +101,17 @@ public class CopySpellTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
//castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Village Messenger");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Giant Growth", "Zada, Hedron Grinder");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
addTarget(playerA, "Silverfur Partisan");
assertGraveyardCount(playerA, "Giant Growth", 1);
assertPowerToughness(playerA, "Silverfur Partisan", 5, 5);
assertPowerToughness(playerA, "Zada, Hedron Grinder", 6, 6);
assertPermanentCount(playerA, "Wolf", 1); // created from Silverfur ability
}
*/
@Test
public void ZadaHedronGrinderBoostWithCharm() {
// Choose two -
@ -157,14 +159,14 @@ public class CopySpellTest extends CardTestPlayerBase {
* spell. Paying a card's splice cost follows the rules for paying
* additional costs in rules 601.2b and 601.2eg. 601.2b If the spell is
* modal the player announces the mode choice (see rule 700.2). If the
* player wishes to splice any cards onto the spell (see rule 702.46), he or
* she reveals those cards in their hand. 706.10. To copy a spell,
* activated ability, or triggered ability means to put a copy of it onto
* the stack; a copy of a spell isn't cast and a copy of an activated
* ability isn't activated. A copy of a spell or ability copies both the
* characteristics of the spell or ability and all decisions made for it,
* including modes, targets, the value of X, and additional or alternative
* costs. (See rule 601, Casting Spells.)
* player wishes to splice any cards onto the spell (see rule 702.46), they
* reveal those cards in their hand. 706.10. To copy a spell, activated
* ability, or triggered ability means to put a copy of it onto the stack; a
* copy of a spell isn't cast and a copy of an activated ability isn't
* activated. A copy of a spell or ability copies both the characteristics
* of the spell or ability and all decisions made for it, including modes,
* targets, the value of X, and additional or alternative costs. (See rule
* 601, Casting Spells.)
*/
@Test
public void ZadaHedronGrinderAndSplicedSpell() {
@ -197,7 +199,7 @@ public class CopySpellTest extends CardTestPlayerBase {
/**
* {4}{U} Enchantment (Enchant Player) Whenever enchanted player casts an
* instant or sorcery spell, each other player may copy that spell and may
* choose new targets for the copy he or she controls.
* choose new targets for the copy they control.
* <p>
* Reported bug: "A player with Curse of Echoes attached to them played
* Bribery and the player who controlled the curse had control of all 3

View file

@ -80,17 +80,17 @@ public class CryptoplasmTest extends CardTestPlayerBase {
* that ETB copying the first Cryptoplasm and is currently also a copy of
* the Divinity.
*
* Opponent attacks with his only Divinity of Pride (4/4) and a Serra
* Opponent attacks with their only Divinity of Pride (4/4) and a Serra
* Avenger (3/3). I block the Divinity with two of my Divinity copies (the
* Clever Impersonator and unenchanted Cryptoplasm) and the Avenger with the
* enchanted Divinity (originally a Cryptoplasm). My opponent's Divinity
* kills my two copies and dies, and then his Avenger dies and kills the
* kills my two copies and dies, and then their Avenger dies and kills the
* Divinity blocking it, also sending my Followed Footsteps down with it.
*
* How does any of that add up? Not only should his Divinity only kill one
* How does any of that add up? Not only should their Divinity only kill one
* of mine since it was a 4/4 and only becomes an 8/8 after dealing its
* damage (at which point it should be too late to go back and say the 4
* damage are now 8, since it was that exact damage that put him at 25
* damage are now 8, since it was that exact damage that put them at 25
* life), but even more confusing is how the Serra Avenger, which is a 3/3,
* somehow kills my 4/4 that had suffered no other damage that turn.
*

View file

@ -14,7 +14,7 @@ public class FlameshadowConjuringTest extends CardTestPlayerBase {
/**
* My opponent ran into an issue with Priest of the Blood Rite being copied
* with Flameshadow Conjuring. His copy was made and removed correctly at
* with Flameshadow Conjuring. Their copy was made and removed correctly at
* the end of the turn, but the "lose two life a turn" trigger still
* happened twice.
*

View file

@ -52,9 +52,9 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
* An opponent cast Phyrexian Metamorph and cloned another opponent's
* Maelstrom Wanderer(his Commander). The first opponent then dealt combat
* damage with Brago, King Eternal and chose to flicker several permanents,
* including the Phyrexian Metamorph/Maelstrom Wanderer, but he was not able
* to choose a new creature to clone when the Phyrexian Metamorph re-entered
* the battlefield.
* including the Phyrexian Metamorph/Maelstrom Wanderer, but that player was
* not able to choose a new creature to clone when the Phyrexian Metamorph
* re-entered the battlefield.
*/
@Test
public void testFlickerWithBrago() {
@ -182,7 +182,7 @@ public class PhyrexianMetamorphTest extends CardTestPlayerBase {
/**
* I cast Show and Tell, and put Sheoldred, Whispering One into play and my
* opponent put Phyrexian Metamorph into play and he was able to clone my
* opponent put Phyrexian Metamorph into play and they were able to clone my
* Sheoldred, Whispering One.
*
* 6/1/2011 If Phyrexian Metamorph somehow enters the battlefield at the

View file

@ -140,7 +140,7 @@ public class ProgenitorMimicTest extends CardTestPlayerBase {
* In a Commander FFA game, I controlled 5 vampires (one of which was
* Captivating Vampire). My opponent cast Progenitor Mimic, copying
* Captivating Vampire. I used the ability of my Captivating Vampire to gain
* control of his Mimic/Vampire but the buff didn't switch control. His
* control of their Mimic/Vampire but the buff didn't switch control. Their
* other vampire still got the buff even after I gained control of the
* Mimic/Vampire.
*

View file

@ -1,5 +1,9 @@
package org.mage.test.cards.copy;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.CardType;
import mage.constants.PhaseStep;
@ -7,6 +11,7 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
@ -154,4 +159,87 @@ public class SparkDoubleTest extends CardTestPlayerBase {
Assert.assertEquals("must add 1 loyalty", 4 + 1, spark.getCounters(currentGame).getCount(CounterType.LOYALTY));
Assert.assertEquals("must add 1 creature counter", 1, spark.getCounters(currentGame).getCount(CounterType.P1P1));
}
@Test
public void test_CopyOfSparksCopy_BySpell() {
/*
Spark Double isnt legendary if it copies a legendary permanent, and this exception is copiable.
If something else copies Spark Double later, that copy also wont be legendary.
If you control two or more permanents with the same name but only one is legendary, the legend rule doesnt apply. (2019-05-03)
it's applier copy check
*/
//
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
//
addCard(Zone.BATTLEFIELD, playerA, "Akroma, Angel of Wrath", 1); // legendary
//
// Create a 1/1 white Bird creature token with flying, then populate. (Create a token thats a copy of a creature token you control.)
addCard(Zone.HAND, playerA, "Eyes in the Skies"); // {3}{W}
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
//
// Create a token thats a copy of target creature you control.
addCard(Zone.HAND, playerA, "Quasiduplicate"); // {1}{U}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
// make copy of legendary creature (it's not legendary now)
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
setChoice(playerA, "Yes");
setChoice(playerA, "Akroma, Angel of Wrath");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPermanentCount("must have copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", 2);
// make copy of copy by CreateTokenCopyTargetEffect
// showBattlefield("before last copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Quasiduplicate");
addTarget(playerA, "Akroma, Angel of Wrath[only copy]");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPermanentCount("must have copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", 3);
// showBattlefield("after all", 1, PhaseStep.BEGIN_COMBAT, playerA);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertAllCommandsUsed();
}
@Test
public void test_CopyOfSparksCopy_ByAbility() {
Ability ability = new SimpleActivatedAbility(new CreateTokenCopyTargetEffect(), new ManaCostsImpl(""));
ability.addTarget(new TargetPermanent());
addCustomCardWithAbility("copy", playerA, ability);
addCard(Zone.HAND, playerA, "Spark Double"); // {3}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
//
addCard(Zone.BATTLEFIELD, playerA, "Akroma, Angel of Wrath", 1); // legendary
//
// Create a 1/1 white Bird creature token with flying, then populate. (Create a token thats a copy of a creature token you control.)
addCard(Zone.HAND, playerA, "Eyes in the Skies"); // {3}{W}
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
// make copy of legendary creature (it's not legendary now)
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spark Double");
setChoice(playerA, "Yes");
setChoice(playerA, "Akroma, Angel of Wrath");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPermanentCount("must have copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", 2);
// make copy of copy by CreateTokenCopyTargetEffect
// showBattlefield("before last copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("before last copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "create a token that");
addTarget(playerA, "Akroma, Angel of Wrath[only copy]");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
checkPermanentCount("must have copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma, Angel of Wrath", 3);
// showBattlefield("after all", 1, PhaseStep.BEGIN_COMBAT, playerA);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertAllCommandsUsed();
}
}

View file

@ -0,0 +1,641 @@
package org.mage.test.cards.cost.adventure;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class AdventureCardsTest extends CardTestPlayerBase {
String abilityBrazenBorrowerMainCast = "Cast Brazen Borrower";
String abilityBrazenBorrowerAdventureCast = "Cast Petty Theft";
@Test
public void testCastTreatsToShare() {
/*
* Curious Pair {1}{G}
* Creature Human Peasant
* 1/3
* ----
* Treats to Share {G}
* Sorcery Adventure
* Create a Food token.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCantCastTreatsToShareTwice() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertActionsCount(playerA, 1);
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastCuriousPair() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 0);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastTreatsToShareAndCuriousPair() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastTreatsToShareWithEdgewallInnkeeper() {
/*
* Edgewall Innkeeper {G}
* Creature Human Peasant
* Whenever you cast a creature spell that has an Adventure, draw a card.
* 1/1
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 0);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastCuriousPairWithEdgewallInnkeeper() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertHandCount(playerA, 1);
assertPermanentCount(playerA, "Food", 0);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastTreatsToShareAndCuriousPairWithEdgewallInnkeeper() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Edgewall Innkeeper");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 1);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastCuriousPairWithMysteriousPathlighter() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
addCard(Zone.BATTLEFIELD, playerA, "Mysterious Pathlighter");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 0);
assertPermanentCount(playerA, "Curious Pair", 1);
assertPowerToughness(playerA, "Curious Pair", 2, 4);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastMemoryTheft() {
/*
* Memory Theft {2}{B}
* Sorcery
* Target opponent reveals their hand. You choose a nonland card from it. That player discards that card.
* You may put a card that has an Adventure that player owns from exile into that player's graveyard.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Curious Pair");
addCard(Zone.HAND, playerA, "Opt");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
addCard(Zone.BATTLEFIELD, playerB, "Swamp");
addCard(Zone.HAND, playerB, "Memory Theft");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Memory Theft", playerA);
playerB.addChoice("Opt");
playerB.addChoice("Curious Pair");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertExileCount(playerA, "Curious Pair", 0);
assertGraveyardCount(playerA, 2);
}
@Test
public void testCastTreatsToShareWithLuckyClover() {
/*
* Lucky Clover {2}
* Artifact
* Whenever you cast an Adventure instant or sorcery spell, copy it. You may choose new targets for the copy.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Lucky Clover");
addCard(Zone.HAND, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 2);
assertPermanentCount(playerA, "Curious Pair", 0);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCastTreatsToShareAndCopy() {
/*
* Fork {R}{R}
* Instant
* Copy target instant or sorcery spell, except that the copy is red. You may choose new targets for the copy.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
addCard(Zone.HAND, playerA, "Curious Pair");
addCard(Zone.HAND, playerA, "Fork");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fork", "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 2);
assertPermanentCount(playerA, 5);
assertExileCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, 1);
assertGraveyardCount(playerA, "Fork", 1);
assertGraveyardCount(playerA, 1);
}
@Test
public void testCastTreatsToShareAndCounter() {
/*
* Counterspell {U}{U}
* Instant
* Counter target spell.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.BATTLEFIELD, playerB, "Island");
addCard(Zone.HAND, playerA, "Curious Pair");
addCard(Zone.HAND, playerB, "Counterspell");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 0);
assertPermanentCount(playerA, 1);
assertExileCount(playerA, 0);
assertGraveyardCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 1);
assertGraveyardCount(playerB, "Counterspell", 1);
assertGraveyardCount(playerB, 1);
}
@Test
public void testCastOpponentsHandTreatsToShare() {
/*
* Psychic Intrusion {3}{U}{B}
* Sorcery
* Target opponent reveals their hand. You choose a nonland card from that player's graveyard or hand and exile it.
* You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 6);
addCard(Zone.HAND, playerA, "Psychic Intrusion");
addCard(Zone.HAND, playerB, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Psychic Intrusion", playerB);
setChoice(playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertHandCount(playerB, 0);
assertPermanentCount(playerB, 0);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, 0);
assertExileCount(playerB, 0);
assertGraveyardCount(playerA, "Psychic Intrusion", 1);
assertGraveyardCount(playerA, 1);
}
@Test
public void testMultipleAdventures() {
/*
* Eager Cadet
* Creature Human Soldier
* 1/1
*/
/*
* Rimrock Knight {1}{R}
* Creature Dwarf Knight
* Rimrock Knight can't block.
* 3/1
* ----
* Boulder Rush {R}
* Instant Adventure
* Target creature gets +2/+0 until end of turn.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.BATTLEFIELD, playerA, "Eager Cadet");
addCard(Zone.HAND, playerA, "Rimrock Knight", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Boulder Rush", "Eager Cadet");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Boulder Rush", "Eager Cadet");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Rimrock Knight", 2);
assertPermanentCount(playerA, "Eager Cadet", 1);
assertPowerToughness(playerA, "Eager Cadet", 5, 1);
assertExileCount(playerA, 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testRimrockKnightPermanentText() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Rimrock Knight");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rimrock Knight");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Rimrock Knight", 1);
assertExileCount(playerA, 0);
assertGraveyardCount(playerA, 0);
Permanent rimrock = getPermanent("Rimrock Knight");
Assert.assertEquals(rimrock.getRules(currentGame).get(0), "{this} can't block.");
}
/*
* Tests for Rule 601.3e:
* 601.3e If a rule or effect states that only an alternative set of characteristics or a subset of characteristics
* are considered to determine if a card or copy of a card is legal to cast, those alternative characteristics
* replace the objects characteristics prior to determining whether the player may begin to cast it.
* Example: Garruks Horde says, in part, You may cast the top card of your library if its a creature card. If
* you control Garruks Horde and the top card of your library is a noncreature card with morph, you may cast it
* using its morph ability.
* Example: Melek, Izzet Paragon says, in part, You may cast the top card of your library if its an instant or
* sorcery card. If you control Melek, Izzet Paragon and the top card of your library is Giant Killer, an
* adventurer creature card whose Adventure is an instant named Chop Down, you may cast Chop Down but not Giant
* Killer. If instead you control Garruks Horde and the top card of your library is Giant Killer, you may cast
* Giant Killer but not Chop Down.
*/
@Test
public void testCastTreatsToShareWithMelek() {
/*
* Melek, Izzet Paragon {4}{U}{R}
* Legendary Creature Weird Wizard
* Play with the top card of your library revealed.
* You may cast the top card of your library if it's an instant or sorcery card.
* Whenever you cast an instant or sorcery spell from your library, copy it. You may choose new targets for the copy.
* 2/4
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, 4);
assertPermanentCount(playerA, "Food", 2);
assertPermanentCount(playerA, "Curious Pair", 0);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCantCastCuriousPairWithMelek() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Melek, Izzet Paragon");
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertActionsCount(playerA, 1);
assertPermanentCount(playerA, "Curious Pair", 0);
assertLibraryCount(playerA, 1);
}
@Test
public void testCastCuriousPairWithGarruksHorde() {
/*
* Garruk's Horde {5}{G}{G}
* Creature Beast
* Trample
* Play with the top card of your library revealed.
* You may cast the top card of your library if it's a creature card.
* 7/7
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curious Pair");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 0);
assertPermanentCount(playerA, "Curious Pair", 1);
assertExileCount(playerA, 0);
assertGraveyardCount(playerA, 0);
}
@Test
public void testCantCastTreatsToShareWithGarruksHorde() {
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Garruk's Horde");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
// showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertActionsCount(playerA, 1);
assertPermanentCount(playerA, "Food", 0);
assertLibraryCount(playerA, 1);
}
@Test
//@Ignore("Not yet working correctly.")
public void testCastTreatsToShareWithWrennAndSixEmblem() {
/*
* Wrenn and Six {R}{G}
* Legendary Planeswalker Wrenn
* +1: Return up to one target land card from your graveyard to your hand.
* 1: Wrenn and Six deals 1 damage to any target.
* 7: You get an emblem with "Instant and sorcery cards in your graveyard have retrace."
* Loyalty: 3
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Wrenn and Six");
addCard(Zone.GRAVEYARD, playerA, "Curious Pair");
addCard(Zone.HAND, playerA, "Forest"); // pay for retrace
addCounters(1, PhaseStep.UPKEEP, playerA, "Wrenn and Six", CounterType.LOYALTY, 5);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-7: You get an emblem");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// retrace - You may cast this card from your graveyard by discarding a land card as an additional cost to cast it
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setChoice(playerA, "Forest");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 0);
assertPermanentCount(playerA, "Wrenn and Six", 1);
assertEmblemCount(playerA, 1);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, "Forest", 1);
assertGraveyardCount(playerA, 1);
}
@Test
public void testCastTreatsToShareWithTeferiTimeRaveler() {
/*
* Teferi, Time Raveler {1}{W}{U}
* Legendary Planeswalker Teferi
* Each opponent can cast spells only any time they could cast a sorcery.
* +1: Until your next turn, you may cast sorcery spells as though they had flash.
* 3: Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card.
* Loyalty: 4
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Time Raveler");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Curious Pair");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Until your next");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("abils", 1, PhaseStep.BEGIN_COMBAT, playerA);
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Treats to Share");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, 3);
assertPermanentCount(playerA, "Food", 1);
assertPermanentCount(playerA, "Curious Pair", 0);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA, 0);
}
@Test
public void test_PlayableAbiities_NoneByMana() {
addCard(Zone.HAND, playerA, "Brazen Borrower", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// no playable by mana
checkPlayableAbility("main", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerMainCast, false);
checkPlayableAbility("adventure", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerAdventureCast, false);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
}
@Test
public void test_PlayableAbiities_NoneByTarget() {
// Brazen Borrower {1}{U}{U}
// Petty Theft {1}{U} Return target nonland permanent an opponent controls to its owners hand.
addCard(Zone.HAND, playerA, "Brazen Borrower", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
//addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// no playable by wrong target
checkPlayableAbility("main", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerMainCast, false);
checkPlayableAbility("adventure", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerAdventureCast, false);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
}
@Test
public void test_PlayableAbiities_OnlyAdventure() {
// Brazen Borrower {1}{U}{U}
// Petty Theft {1}{U} Return target nonland permanent an opponent controls to its owners hand.
addCard(Zone.HAND, playerA, "Brazen Borrower", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// only adventure
checkPlayableAbility("main", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerMainCast, false);
checkPlayableAbility("adventure", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerAdventureCast, true);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
}
@Test
public void test_PlayableAbiities_All() {
// Brazen Borrower {1}{U}{U}
// Petty Theft {1}{U} Return target nonland permanent an opponent controls to its owners hand.
addCard(Zone.HAND, playerA, "Brazen Borrower", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1);
// all
checkPlayableAbility("main", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerMainCast, true);
checkPlayableAbility("adventure", 1, PhaseStep.PRECOMBAT_MAIN, playerA, abilityBrazenBorrowerAdventureCast, true);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertAllCommandsUsed();
}
}

View file

@ -0,0 +1,61 @@
package org.mage.test.cards.cost.alternate;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class BolassCitadelTest extends CardTestPlayerBase {
@Test
public void testCastEagerCadet() {
/*
* Eager Cadet
* Creature Human Soldier
* 1/1
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel");
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Eager Cadet");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Eager Cadet");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Eager Cadet", 1);
assertGraveyardCount(playerA,0);
assertLife(playerA, 19);
}
@Test
public void testCastAdventure() {
/*
* Curious Pair {1}{G}
* Creature Human Peasant
* 1/3
* ----
* Treats to Share {G}
* Sorcery Adventure
* Create a Food token.
*/
setStrictChooseMode(true);
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel");
removeAllCardsFromLibrary(playerA);
addCard(Zone.LIBRARY, playerA, "Curious Pair");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Treats to Share");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertHandCount(playerA, 0);
assertPermanentCount(playerA, "Food", 1);
assertExileCount(playerA, "Curious Pair", 1);
assertGraveyardCount(playerA,0);
assertLife(playerA, 19);
}
}

View file

@ -18,7 +18,7 @@ public class AuraTargetRemovedTest extends CardTestPlayerBase {
/**
* Spreading Seas is bugged, opp casted it on my Field of Ruin, I sacced
* with the spell on stack but it resolved anyway and let him draw.
* with the spell on stack but it resolved anyway and let them draw.
*
* 303.4. Some enchantments have the subtype Aura. An Aura enters the
* battlefield attached to an object or player. What an Aura can be attached

View file

@ -13,7 +13,6 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
//addCard(Zone.BATTLEFIELD, playerA, "Hypersonic Dragon", 1); // can cast spells at any time
//addCard(Zone.HAND, playerA, "Breath of Life", 1); // {3}{W} // return creatures
//addCard(Zone.HAND, playerA, "Replenish", 1); // {3}{W} // return all enchantments
@Test
public void testOath_OwnCardTriggersOnOwnTurn() {
// A
@ -140,7 +139,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
// turn 1 - A
// cast oath A
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Replenish");
showBattlefield("A perms", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showBattlefield("A perms", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
// cast oath copy
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Copy Enchantment");
setChoice(playerA, "Yes"); // use copy effect
@ -194,15 +193,14 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
// turn 1 - A
// nothing
// turn 2 - B
// cast oath A
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Replenish");
// cast oath copy by opponent
showBattlefield("A perms", 2, PhaseStep.POSTCOMBAT_MAIN, playerA);
showBattlefield("B perms", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
showAvaileableAbilities("B abils", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
showHand("B hand", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
// showBattlefield("A perms", 2, PhaseStep.POSTCOMBAT_MAIN, playerA);
// showBattlefield("B perms", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
// showAvaileableAbilities("B abils", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
// showHand("B hand", 2, PhaseStep.POSTCOMBAT_MAIN, playerB);
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Copy Enchantment");
setChoice(playerB, "Yes"); // use copy effect
setChoice(playerB, "Oath of Lieges"); // target for copy
@ -210,7 +208,7 @@ public class OathOfLiegesTest extends CardTestPlayerBase {
checkPermanentCount("B have 1 oath", 2, PhaseStep.END_TURN, playerA, "Oath of Lieges", 1);
checkPermanentCount("A have 10 plains", 2, PhaseStep.END_TURN, playerA, "Plains", 10);
checkPermanentCount("B have 12 plains", 2, PhaseStep.END_TURN, playerB, "Plains", 12);
showLibrary("lib B", 2, PhaseStep.END_TURN, playerB);
// showLibrary("lib B", 2, PhaseStep.END_TURN, playerB);
// turn 3 - A
// oath A triggers for A and activates

View file

@ -1,9 +1,8 @@
package org.mage.test.cards.enchantments;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.junit.Ignore;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
@ -26,11 +25,14 @@ public class SkullclampTest extends CardTestPlayerBase {
* 704.5n.)
*
*/
@Test
// This test does not work, but the example works in the game fine.
@Ignore
public void testPerniciousDeed() {
// Equipped creature gets +1/-1.
// Whenever equipped creature dies, draw two cards.
// Equip {1}
addCard(Zone.LIBRARY, playerA, "Memnite", 2);
addCard(Zone.BATTLEFIELD, playerA, "Skullclamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);

View file

@ -7,6 +7,7 @@ import mage.constants.Zone;
import mage.filter.Filter;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -117,4 +118,48 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
Assert.assertFalse(emrakul.getAbilities().contains(FlyingAbility.getInstance())); // loses flying though
}
/**
* So Starfield of Nyx in play. Detention Sphere with a Song of the Dryads
* under it. Wrath of god on the stack. In response I Parallax Wave Honden
* of life's Web, Mirrari's Wake, Sphere of Safety, Aura Shards, and
* Enchantress's Presence to save them. Wrath resolves and Song of the
* Dryads come back along with the 5 named enchantments. Opp targets
* Starfield of Nyx with Song of the Dryads. When song of the dryads
* attaches all my enchantments stay creatures but as 1/1's instead of cmc.
* I untap draw and cast Humility. All my 1/1 enchantments die while opp's
* bruna, light of alabaster keeps her abilities. After mirrari's wake dies
* due to this I still have double mana. So yea, something broke big time
* there.
*/
@Test
@Ignore
public void testStarfieldOfNyxAndSongOfTheDryads() {
// Nontoken creatures you control get +1/+1 and have vigilance.
addCard(Zone.BATTLEFIELD, playerA, "Always Watching", 5);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
// At the beginning of your upkeep, you may return target enchantment card from your graveyard to the battlefield.
// As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in
// addition to its other types and has base power and base toughness each equal to its converted mana cost.
addCard(Zone.HAND, playerA, "Starfield of Nyx"); // "{4}{W}"
addCard(Zone.BATTLEFIELD, playerB, "Forest", 3);
// Enchanted permanent is a colorless Forest land.
addCard(Zone.HAND, playerB, "Song of the Dryads"); // Enchant Permanent {2}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Starfield of Nyx");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Song of the Dryads", "Starfield of Nyx");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Always Watching", 5);
assertPermanentCount(playerB, "Song of the Dryads", 1);
assertPowerToughness(playerA, "Always Watching", 0, 0, Filter.ComparisonScope.All);
assertPermanentCount(playerA, "Forest", 1);
}
}

View file

@ -0,0 +1,37 @@
package org.mage.test.cards.mana;
import mage.constants.ManaType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author apetresc
*/
public class LeylineOfAbundanceTest extends CardTestPlayerBase {
/**
* Creatures an opponent controls shouldn't trigger Leyline's ability to
* generate additional mana.
*/
@Test
public void testOpponentsManaCreatures() {
addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
addCard(Zone.BATTLEFIELD, playerA, "Leyline of Abundance");
addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves");
addCard(Zone.BATTLEFIELD, playerB, "Leyline of Abundance");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerB, "{T}: Add {G}");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
assertManaPool(playerB, ManaType.GREEN, 2);
assertManaPool(playerA, ManaType.GREEN, 0);
}
}

View file

@ -241,7 +241,7 @@ public class ManaPoolTest extends CardTestPlayerBase {
checkManaPool("mana", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "R", 4);
// use for ability
showAvaileableAbilities("before ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("before ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{X}:", playerB);
setChoice(playerA, "X=3");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);

View file

@ -28,5 +28,97 @@ public class PhyrexianManaTest extends CardTestPlayerBase {
// can be played only through life pay
Assert.assertTrue(life == 20 && hand == 1 || life == 18 && hand == 0);
}
@Test
public void testKrrikOnlyUsableByController() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth");
addCard(Zone.HAND, playerA, "Banehound");
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
addCard(Zone.HAND, playerB, "Banehound");
setChoice(playerA, "Yes");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Banehound");
setChoice(playerB, "Yes");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Banehound");
setStopAt(2, PhaseStep.END_TURN);
execute();
//PlayerA pays life but PlayerB cannot
assertLife(playerA, 18);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Banehound", 1);
assertPermanentCount(playerB, "Banehound", 1);
}
@Test
public void testKrrikTriggeredAbility() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth");
addCard(Zone.HAND, playerA, "Banehound");
addCard(Zone.HAND, playerA, "Crypt Ghast");
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
setChoice(playerA, "Yes"); //yes to pay 2 life to cast Crypt Ghast
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Crypt Ghast"); //3 mana used, 2 life paid (18 life total)
setChoice(playerA, "Yes"); //yes to pay 2 life to cast Banehound
setChoice(playerA, "Yes"); //yes to Extort
setChoice(playerA, "Yes"); //yes to pay 2 life to Extort
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Banehound"); //0 mana used, 4 life paid, 1 life gained (15 life total)
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 15);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Banehound", 1);
assertPermanentCount(playerA, "Crypt Ghast", 1);
}
@Test
public void testKrrikActivatedAbility() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth");
addCard(Zone.BATTLEFIELD, playerA, "Frozen Shade");
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
setChoice(playerA, "Yes"); //yes to pay 2 life to activate Frozen Shade's +1/+1 ability
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}: {this} gets +1/+1 until end of turn.");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 18);
assertLife(playerB, 20);
assertPowerToughness(playerA, "Frozen Shade", 1, 2);
}
@Test
public void testKrrikTrinispherePostPay() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "K'rrik, Son of Yawgmoth");
addCard(Zone.BATTLEFIELD, playerA, "Trinisphere");
addCard(Zone.HAND, playerA, "Dismember");
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
addCard(Zone.BATTLEFIELD, playerB, "Banehound");
setChoice(playerA, "No"); //don't pay 2 life for Dismember's Phyrexian cost
setChoice(playerA, "No"); //don't pay 2 life for Dismember's Phyrexian cost
setChoice(playerA, "Yes"); //yes to pay 2 life for Dismember's {B} cost via K'rrik
setChoice(playerA, "Yes"); //yes to pay 2 life for Dismember's {B} cost via K'rrik
//Dismember costs {1} now + life paid. Normally this would be {3} + life paid with true Phyrexian mana and Trinisphere active.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dismember", "Banehound");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerA, 16);
assertLife(playerB, 20);
assertTappedCount("Swamp", true, 1);
assertGraveyardCount(playerA, "Dismember", 1);
assertGraveyardCount(playerB, "Banehound", 1);
}
}

View file

@ -16,7 +16,7 @@ public class ModalTriggeredAbilityTest extends CardTestPlayerBase {
public void testBlizzardSpecterReturn() {
// Flying
// Whenever Blizzard Specter deals combat damage to a player, choose one
// - That player returns a permanent he or she controls to its owner's hand;
// - That player returns a permanent they control to its owner's hand;
// or that player discards a card.
addCard(Zone.BATTLEFIELD, playerB, "Blizzard Specter");
@ -41,7 +41,7 @@ public class ModalTriggeredAbilityTest extends CardTestPlayerBase {
public void testBlizzardSpecterDiscard() {
// Flying
// Whenever Blizzard Specter deals combat damage to a player, choose one
// - That player returns a permanent he or she controls to its owner's hand;
// - That player returns a permanent they control to its owner's hand;
// or that player discards a card.
addCard(Zone.BATTLEFIELD, playerB, "Blizzard Specter");

View file

@ -78,7 +78,7 @@ public class DamageEffectsTest extends CardTestPlayerBase {
/*
Vexing Devil {R}
Creature Devil
When Vexing Devil enters the battlefield, any opponent may have it deal 4 damage to him or her. If a player does, sacrifice Vexing Devil.
When Vexing Devil enters the battlefield, any opponent may have it deal 4 damage to them. If a player does, sacrifice Vexing Devil.
*/
String vDevil = "Vexing Devil";

View file

@ -40,7 +40,7 @@ public class DrawEffectsTest extends CardTestPlayerBase {
public void testNotionThief() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
// Flash
// If an opponent would draw a card except the first one he or she draws in each of their draw steps, instead that player skips that draw and you draw a card.
// If an opponent would draw a card except the first one they draw in each of their draw steps, instead that player skips that draw and you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Notion Thief", 1);
// Target player draws four cards.
@ -66,7 +66,7 @@ public class DrawEffectsTest extends CardTestPlayerBase {
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
// Flash
// If an opponent would draw a card except the first one he or she draws in each of their draw steps, instead that player skips that draw and you draw a card.
// If an opponent would draw a card except the first one they draw in each of their draw steps, instead that player skips that draw and you draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Notion Thief", 1);
// Each player discards their hand, then draws seven cards.
// Miracle {1}{R}

View file

@ -40,7 +40,7 @@ public class AttackRequirementTest extends CardTestPlayerBase {
// {G}: Wall of Tanglecord gains reach until end of turn. (It can block creatures with flying.)
addCard(Zone.BATTLEFIELD, playerA, "Wall of Tanglecord"); // 0/6
// Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you
// Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you
addCard(Zone.HAND, playerA, "Ghostly Prison");
// Juggernaut attacks each turn if able.

View file

@ -55,8 +55,8 @@ public class BlockRequirementTest extends CardTestPlayerBase {
}
/**
* Joraga Invocation is bugged big time. He cast it with 2 creatures out. I
* only had one untapped creature. Blocked one of his, hit Done, error
* Joraga Invocation is bugged big time. They cast it with 2 creatures out.
* I only had one untapped creature. Blocked one of theirs, hit Done, error
* message popped up saying the other one needed to be blocked in an
* infinite loop. Had to shut down the program via Task Manager.
*/
@ -93,12 +93,12 @@ public class BlockRequirementTest extends CardTestPlayerBase {
* Elemental Uprising - "it must be blocked this turn if able", not working
*
* The bug just happened for me today as well - the problem is "must be
* blocked" is not being enforced correctly. During opponent's main phase he
* casted Elemental Uprising targeting an untapped land. He attacked with
* two creatures, I had one creature to block with, and did not block the
* land-creature targeted by Elemental Uprising. Instead I blocked a 2/2 of
* his with my 2/3. I should have been forced to block the land targeted by
* Elemental Uprising.
* blocked" is not being enforced correctly. During opponent's main phase
* they cast Elemental Uprising targeting an untapped land. They attacked
* with two creatures, I had one creature to block with, and did not block
* the land-creature targeted by Elemental Uprising. Instead I blocked a 2/2
* of theirs with my 2/3. I should have been forced to block the land
* targeted by Elemental Uprising.
*/
@Test
public void testElementalUprising() {

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.restriction;
import mage.constants.PhaseStep;
@ -119,7 +118,7 @@ public class CantAttackTest extends CardTestPlayerBase {
@Test
public void testOrzhovAdvokist() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
// At the beginning of your upkeep, each player may put two +1/+1 counters on a creature he or she controls.
// At the beginning of your upkeep, each player may put two +1/+1 counters on a creature they control.
// If a player does, creatures that player controls can't attack you or a planeswalker you control until your next turn.
addCard(Zone.HAND, playerA, "Orzhov Advokist"); // Creature {2}{W} 1/4
@ -140,56 +139,56 @@ public class CantAttackTest extends CardTestPlayerBase {
assertTapped("Silvercoat Lion", false);
assertPowerToughness(playerB, "Silvercoat Lion", 4, 4);
}
/*
Reported bug: Medomai was able to attack on an extra turn when cheated into play.
*/
*/
@Test
public void testMedomaiShouldNotAttackOnExtraTurns() {
/*
Medomai the Ageless {4}{W}{U}
Legendary Creature Sphinx 4/4
Flying
Whenever Medomai the Ageless deals combat damage to a player, take an extra turn after this one.
Medomai the Ageless can't attack during extra turns.
*/
*/
String medomai = "Medomai the Ageless";
/*
Cauldron Dance {4}{B}{R} Instant
Cast Cauldron Dance only during combat.
Return target creature card from your graveyard to the battlefield. That creature gains haste. Return it to your hand at the beginning of the next end step.
You may put a creature card from your hand onto the battlefield. That creature gains haste. Its controller sacrifices it at the beginning of the next end step.
*/
*/
String cDance = "Cauldron Dance";
String dBlade = "Doom Blade"; // {1}{B} instant destroy target creature
String dBlade = "Doom Blade"; // {1}{B} instant destroy target creature
addCard(Zone.BATTLEFIELD, playerA, medomai);
addCard(Zone.HAND, playerA, dBlade);
addCard(Zone.HAND, playerA, cDance);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
// attack with Medomai, connect, and destroy him after combat
attack(1, playerA, medomai);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, dBlade, medomai);
// next turn granted, return Medomai to field with Cauldron and try to attack again
castSpell(2, PhaseStep.BEGIN_COMBAT, playerA, cDance);
addTarget(playerA, medomai);
attack(2, playerA, medomai);
// medomai should not have been allowed to attack, but returned to hand at beginning of next end step still
setStopAt(2, PhaseStep.END_TURN);
execute();
assertLife(playerB, 16); // one hit from medomai
assertGraveyardCount(playerA, dBlade, 1);
assertGraveyardCount(playerA, cDance, 1);
assertGraveyardCount(playerA, medomai, 0);
assertHandCount(playerA, medomai, 1);
}
@Test
public void basicMedomaiTestForExtraTurn() {
/*
@ -198,184 +197,248 @@ public class CantAttackTest extends CardTestPlayerBase {
Flying
Whenever Medomai the Ageless deals combat damage to a player, take an extra turn after this one.
Medomai the Ageless can't attack during extra turns.
*/
*/
String medomai = "Medomai the Ageless";
/*
Exquisite Firecraft {1}{R}{R}
Sorcery
Exquisite Firecraft deals 4 damage to any target.
*/
*/
String eFirecraft = "Exquisite Firecraft";
addCard(Zone.BATTLEFIELD, playerA, medomai);
addCard(Zone.HAND, playerA, eFirecraft);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
// attack with medomai, get extra turn, confirm cannot attack again with medomai and can cast sorcery
attack(1, playerA, medomai);
attack(2, playerA, medomai); // should not be allowed to
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerA, eFirecraft, playerB);
setStopAt(2, PhaseStep.END_TURN);
execute();
assertLife(playerB, 12); // 1 hit from medomai and firecraft = 8 damage
assertGraveyardCount(playerA, eFirecraft, 1);
assertPermanentCount(playerA, medomai, 1);
}
@Test
public void sphereOfSafetyPaidCostAllowsAttack() {
public void sphereOfSafetyPaidCostAllowsAttack() {
/*
Sphere of Safety {4}{W}
Enchantment
Creatures can't attack you or a planeswalker you control unless their controller pays {X} for each of those creatures, where X is the number of enchantments you control.
*/
*/
String sphere = "Sphere of Safety";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, sphere);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
attack(1, playerA, memnite);
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, sphere, 1);
assertLife(playerB, 19); // took the hit from memnite
assertTapped("Forest", true); // forest had to be tapped
}
@Test
public void sphereOfSafetyCostNotPaid_NoAttackAllowed() {
/*
Sphere of Safety {4}{W}
Enchantment
Creatures can't attack you or a planeswalker you control unless their controller pays {X} for each of those creatures, where X is the number of enchantments you control.
*/
*/
String sphere = "Sphere of Safety";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, sphere);
addCard(Zone.BATTLEFIELD, playerA, "Forest");
attack(1, playerA, memnite);
setChoice(playerA, "No");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, sphere, 1);
assertLife(playerB, 20); // no damage went through, did not elect to pay
assertTapped("Forest", false); // forest not tapped
}
@Test
public void collectiveResistanceCostPaid_AttackAllowed()
{
public void collectiveResistanceCostPaid_AttackAllowed() {
/*
Collective Restraint {3}{U}
Enchantment
Domain Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control.
*/
Domain Creatures can't attack you unless their controller pays {X} for each creature they control that's attacking you, where X is the number of basic land types among lands you control.
*/
String cRestraint = "Collective Restraint";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, cRestraint);
addCard(Zone.BATTLEFIELD, playerB, "Island"); // 1 basic land type = pay 1 to attack
addCard(Zone.BATTLEFIELD, playerA, "Forest");
attack(1, playerA, memnite);
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, cRestraint, 1);
assertLife(playerB, 19); // took the hit from memnite
assertTapped("Forest", true); // forest had to be tapped
}
@Test
public void collectiveResistanceCostNotPaid_NoAttackAllowed()
{
public void collectiveResistanceCostNotPaid_NoAttackAllowed() {
/*
Collective Restraint {3}{U}
Enchantment
Domain Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control.
*/
Domain Creatures can't attack you unless their controller pays {X} for each creature they control that's attacking you, where X is the number of basic land types among lands you control.
*/
String cRestraint = "Collective Restraint";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, cRestraint);
addCard(Zone.BATTLEFIELD, playerB, "Island"); // 1 basic land type = pay 1 to attack
addCard(Zone.BATTLEFIELD, playerA, "Forest");
attack(1, playerA, memnite);
setChoice(playerA, "No");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, cRestraint, 1);
assertLife(playerB, 20); // no damage went through, did not elect to pay
assertTapped("Forest", false); // forest not tapped
}
@Test
public void ghostlyPrison_PaidCost_AllowsAttack() {
public void ghostlyPrison_PaidCost_AllowsAttack() {
/*
Ghostly Prison {2}{W}
Enchantment
Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
*/
Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
*/
String gPrison = "Ghostly Prison";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, gPrison);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
attack(1, playerA, memnite);
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, gPrison, 1);
assertLife(playerB, 19); // took the hit from memnite
assertTappedCount("Forest", true, 2); // forests had to be tapped
}
@Test
public void ghostlyPrison_CostNotPaid_NoAttackAllowed() {
/*
Ghostly Prison {2}{W}
Enchantment
Creatures can't attack you unless their controller pays {2} for each creature he or she controls that's attacking you.
*/
Creatures can't attack you unless their controller pays {2} for each creature they control that's attacking you.
*/
String gPrison = "Ghostly Prison";
String memnite = "Memnite";
addCard(Zone.BATTLEFIELD, playerA, memnite); // {0} 1/1
addCard(Zone.BATTLEFIELD, playerB, gPrison);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
attack(1, playerA, memnite);
setChoice(playerA, "No");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerB, gPrison, 1);
assertLife(playerB, 20); // no damage went through, did not elect to pay
assertTapped("Forest", false); // no forests tapped
}
@Test
public void OpportunisticDragon() {
// Flying
// When Opportunistic Dragon enters the battlefield, choose target Human or artifact an opponent controls. For as long as Opportunistic Dragon remains on the battlefield, gain control of that permanent, it loses all abilities, and it can't attack or block.
addCard(Zone.HAND, playerA, "Opportunistic Dragon"); // Creature {2}{R}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Desperate Castaways"); // Creature - Human Pirate 2/3
// Other Pirates you control get +1/+1.
// At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn.
addCard(Zone.BATTLEFIELD, playerB, "Admiral Beckett Brass"); // Creature {1}{B}{B}{R}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Opportunistic Dragon");
addTarget(playerA, "Admiral Beckett Brass");
attack(3, playerA, "Admiral Beckett Brass"); // Can't attack
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerA, "Opportunistic Dragon", 1);
assertPermanentCount(playerA, "Admiral Beckett Brass", 1);
assertPowerToughness(playerA, "Desperate Castaways", 2, 3);
assertLife(playerA, 20);
assertLife(playerB, 20);
}
/* Opportunistic Dragon - can't block/can't attack effect did not end when opportunistic dragon was exiled */
@Test
public void OpportunisticDragonEndEffects() {
// Flying
// When Opportunistic Dragon enters the battlefield, choose target Human or artifact an opponent controls. For as long as Opportunistic Dragon remains on the battlefield, gain control of that permanent, it loses all abilities, and it can't attack or block.
addCard(Zone.HAND, playerA, "Opportunistic Dragon"); // Creature {2}{R}{R}
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.BATTLEFIELD, playerA, "Desperate Castaways"); // Creature - Human Pirate 2/3
// Other Pirates you control get +1/+1.
// At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn.
addCard(Zone.BATTLEFIELD, playerB, "Admiral Beckett Brass"); // Creature {1}{B}{B}{R} 3/3
addCard(Zone.BATTLEFIELD, playerB, "Desperate Castaways"); // Creature - Human Pirate 2/3
// Destroy target nonartifact, nonblack creature. It can't be regenerated.
addCard(Zone.HAND, playerB, "Terror"); // Instant {1}{B}
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Opportunistic Dragon");
addTarget(playerA, "Admiral Beckett Brass");
attack(3, playerA, "Admiral Beckett Brass"); // Can't attack
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerB, "Terror", "Opportunistic Dragon");
attack(4, playerB, "Admiral Beckett Brass"); // Can attack again
setStopAt(4, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerB, "Terror", 1);
assertGraveyardCount(playerA, "Opportunistic Dragon", 1);
assertPermanentCount(playerB, "Admiral Beckett Brass", 1);
assertPowerToughness(playerB, "Desperate Castaways", 3, 4);
assertLife(playerA, 17);
assertLife(playerB, 20);
}
}

View file

@ -14,7 +14,7 @@ public class CantCastTest extends CardTestPlayerBase {
/**
* I control Void Winnower. But my opponent can cast Jayemdae Tome (that's
* converted mana cost is even) He can cast other even spell. Test casting
* converted mana cost is even) They can cast other even spell. Test casting
* cost 4
*/
@Test

View file

@ -0,0 +1,31 @@
package org.mage.test.cards.single;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class ArchfiendOfSpiteTest extends CardTestPlayerBase {
@Test
public void damageTriggerTest() {
addCard(Zone.BATTLEFIELD, playerA, "Archfiend of Spite");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
setStopAt(1, PhaseStep.UNTAP);
execute();
assertPermanentCount(playerA, "Archfiend of Spite", 1);
assertLife(playerB, 20);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Archfiend of Spite");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
setStrictChooseMode(true);
execute();
assertPermanentCount(playerA, "Archfiend of Spite", 1);
assertPermanentCount(playerB, "Mountain", 1);
assertDamageReceived(playerA, "Archfiend of Spite", 3);
assertLife(playerB, 17);
}
}

View file

@ -22,7 +22,7 @@ public class DivergentTransformationsTest extends CardTestPlayerBase {
Divergent Transformations {6}{R}
Instant
Undaunted (This spell costs 1 less to cast for each opponent.)
Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until he or she reveals a creature card,
Exile two target creatures. For each of those creatures, its controller reveals cards from the top of their library until they reveal a creature card,
puts that card onto the battlefield, then shuffles the rest into their library.
*/
String dTransformations = "Divergent Transformations";

View file

@ -6,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* also tests regenerate and tests that permanents with protection can be
* sacrificed
*
@ -46,10 +45,13 @@ public class FiendOfTheShadowsTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Swamp");
attack(1, playerA, "Fiend of the Shadows");
addTarget(playerB, "Swamp");
playLand(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Swamp");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 17);

View file

@ -99,6 +99,7 @@ public class MisdirectionTest extends CardTestPlayerBase {
}
// check to change target permanent creature legal to to a creature the opponent of the spell controller controls
// target to illegal target can't be tested
@Test
public void test_ChangePublicExecution() {
// Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
@ -129,41 +130,5 @@ public class MisdirectionTest extends CardTestPlayerBase {
assertGraveyardCount(playerB, "Custodian of the Trove", 1);
assertPermanentCount(playerB, "Pillarfield Ox", 1);
assertPowerToughness(playerB, "Pillarfield Ox", 0, 4);
}
// check to change target permanent creature not legal to to a creature the your opponent controls
@Test
public void test_ChangePublicExecution2() {
// Destroy target creature an opponent controls. Each other creature that player controls gets -2/-0 until end of turn.
addCard(Zone.HAND, playerA, "Public Execution");
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
addCard(Zone.BATTLEFIELD, playerA, "Keeper of the Lens", 1);
/*
Misdirection {3}{U}{U}
Instant
You may exile a blue card from your hand rather than pay Misdirection's mana cost.
Change the target of target spell with a single target.
*/
addCard(Zone.HAND, playerB, "Misdirection");
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 1);
addCard(Zone.BATTLEFIELD, playerB, "Custodian of the Trove", 1); // 4/3
addCard(Zone.BATTLEFIELD, playerB, "Island", 5);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Public Execution", "Custodian of the Trove");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Misdirection", "Public Execution", "Public Execution");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Public Execution", 1);
assertGraveyardCount(playerB, "Misdirection", 1);
assertPermanentCount(playerA, "Keeper of the Lens", 1);
assertPermanentCount(playerB, "Pillarfield Ox", 1);
assertPowerToughness(playerB, "Pillarfield Ox", 0, 4);
assertGraveyardCount(playerB, "Custodian of the Trove", 1);
}
}

View file

@ -49,8 +49,8 @@ public class NecroticPlagueTest extends CardTestPlayerBase {
* Enchantment Aura, 2BB
* Enchant creature
* Enchanted creature has "At the beginning of your upkeep, sacrifice this creature."
* When enchanted creature dies, its controller chooses target creature one of his or
* her opponents controls. Return Necrotic Plague from its owner's graveyard to the
* When enchanted creature dies, its controller chooses target creature one of their
* opponents controls. Return Necrotic Plague from its owner's graveyard to the
* battlefield attached to that creature.
*/
addCard(Zone.HAND, playerA, "Necrotic Plague");

View file

@ -39,7 +39,7 @@ public class ParallaxWaveTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
// Fading 5 (This enchantment enters the battlefield with five fade counters on it. At the beginning of your upkeep, remove a fade counter from it. If you can't, sacrifice it.)
// Remove a fade counter from Parallax Wave: Exile target creature.
// When Parallax Wave leaves the battlefield, each player returns to the battlefield all cards he or she owns exiled with Parallax Wave.
// When Parallax Wave leaves the battlefield, each player returns to the battlefield all cards they own exiled with Parallax Wave.
addCard(Zone.HAND, playerA, "Parallax Wave");
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);

View file

@ -0,0 +1,33 @@
package org.mage.test.cards.single;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
public class SyrKonradTheGrimTest extends CardTestPlayerBase {
@Test
public void leavesOwnGraveyardTriggerTest() {
addCard(Zone.HAND, playerA, "Rest in Peace");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Syr Konrad, the Grim");
// These leaving the graveyard *should* cause loss of life
addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears", 2);
// These ones *shouldn't*
addCard(Zone.GRAVEYARD, playerB, "Grizzly Bears");
setStopAt(1, PhaseStep.UNTAP);
execute();
assertLife(playerB, 20);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rest in Peace");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerA, 0);
assertGraveyardCount(playerB, 0);
assertLife(playerA, 20);
assertLife(playerB, 18);
}
}

View file

@ -15,7 +15,6 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
Enchantment
Whenever you cast an instant or sorcery spell, copy it for each other instant and sorcery spell youve cast before it this turn. You may choose new targets for the copies.
*/
@Test
public void test_CalcBeforeStorm() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -233,7 +232,6 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Augmenting Automaton");
// turn 1
// 1a
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
checkLife("0x copy", 1, PhaseStep.BEGIN_COMBAT, playerB, 20 - 3);
@ -255,7 +253,6 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
assertAllCommandsUsed();
}
@Test
public void test_WaitStackResolvedWithBolts() {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 5);
@ -282,6 +279,8 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
You control enchanted permanent.
Cycling {2} ({2}, Discard this card: Draw a card.)
*/
// Test fails sometimes with the following message:
// java.lang.AssertionError: b 0x copy after control - PlayerA have wrong life: 20 <> 17 expected:<17> but was:<20>
@Test
public void test_GetControlNotCounts() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
@ -296,7 +295,6 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Lay Claim");
// turn 2
// pump card for A
// 1
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
@ -313,7 +311,6 @@ public class ThousandYearStormTest extends CardTestPlayerBase {
checkLife("b 0x copy after control", 3, PhaseStep.UPKEEP, playerA, 20 - 3);
// turn 4
// pump for B
// 1
castSpell(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);

View file

@ -7,7 +7,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author escplan9
*/
public class DecimatorBeetleTest extends CardTestPlayerBase {
@ -19,29 +18,33 @@ When Decimator Beetle enters the battlefield, put a -1/-1 counter on target crea
Whenever Decimator Beetle attacks, remove a -1/-1 counter from target creature you control and put a -1/-1 counter on up to one target creature defending player controls.
*/
private final String decimator = "Decimator Beetle";
@Test
public void targetOpponentCreatureWithDecimator() {
String grizzly = "Grizzly Bears"; // {1}{G} 2/2
String hillGiant = "Hill Giant"; // {3}{R} 3/3
addCard(Zone.HAND, playerA, decimator);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, grizzly);
addCard(Zone.BATTLEFIELD, playerB, hillGiant);
// put -1/-1 on own creature
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, decimator);
addTarget(playerA, grizzly);
// remove -1/-1 from own creature and put to defender control
attack(3, playerA, decimator);
addTarget(playerA, grizzly);
addTarget(playerA, hillGiant);
addTarget(playerA, grizzly); // remove
addTarget(playerA, hillGiant); // put
setStrictChooseMode(true);
setStopAt(3, PhaseStep.END_COMBAT);
execute();
assertAllCommandsUsed();
assertPowerToughness(playerA, grizzly, 2, 2); // had -1/-1 counter, but removed on attack
assertPowerToughness(playerB, hillGiant, 2, 2); // gets -1/-1 counter from decimator attack ability
assertCounterCount(playerA, grizzly, CounterType.M1M1, 0);

View file

@ -99,7 +99,7 @@ public class SpellQuellerTest extends CardTestPlayerBase {
}
/*
Reported bug: "...Spell Queller exiled my Nissa, Vastwood Seeker. Next turn he processed Nissa with Wasteland Strangler and killed my Tireless Tracker.
Reported bug: "...Spell Queller exiled my Nissa, Vastwood Seeker. Next turn they processed Nissa with Wasteland Strangler and killed my Tireless Tracker.
I then cast Quarantine Field, targeting Spell Queller and Wasteland Strangler. That's when the error message occurred. (fatal exception)"
*/
@Test

View file

@ -122,7 +122,7 @@ public class TheGitrogMonsterTest extends CardTestPlayerBase {
// Rags Sorcery {2}{B}{B}
// All creatures get -2/-2 until end of turn.
// Riches Sorcery {5}{U}{U}
// Each opponent chooses a creature he or she controls. You gain control of each of those creatures.
// Each opponent chooses a creature they control. You gain control of each of those creatures.
addCard(Zone.GRAVEYARD, playerB, "Rags // Riches", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 7);

View file

@ -67,6 +67,7 @@ public class LaquatussChampionTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 7);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 7);
addCard(Zone.HAND, playerA, "Laquatus's Champion");
// Destroy target creature. It can't be regenerated.
addCard(Zone.HAND, playerA, "Terminate");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Laquatus's Champion");

View file

@ -15,7 +15,7 @@ public class BurningEarthTest extends CardTestPlayerBase {
/**
* Burning Earth - It doesn't cause the damage it should. My opponent taps a
* Blood Crypt and an Overgrown Tomb for black and green mana respectively
* and casts his card all the while without taking any damage.
* and casts their card all the while without taking any damage.
*
*/
@Test

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.triggers;
import mage.constants.PhaseStep;
@ -7,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class EnterLeaveBattlefieldExileTargetTest extends CardTestPlayerBase {
@ -25,9 +23,12 @@ public class EnterLeaveBattlefieldExileTargetTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Angel of Serenity");
addTarget(playerA, "Silvercoat Lion^Pillarfield Ox");
setChoice(playerA, "Yes");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Angel of Serenity", 1);
assertExileCount("Silvercoat Lion", 1);

View file

@ -14,8 +14,8 @@ public class GolemsHeartTest extends CardTestPlayerBase {
/*
My opponent and I were both playing artifact decks.
He had Golem's Heart out.
He wasn't gaining life when I or he was casting spells.
They had Golem's Heart out.
They weren't gaining life when I or they cast spells.
*/
@Test
public void testFirstTriggeredAbility() {

View file

@ -30,8 +30,8 @@ public class PossibilityStormTest extends CardTestPlayerBase {
public void TestWithZoeticCavern() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
// Whenever a player casts a spell from their hand, that player exiles it, then exiles cards from
// the top of their library until he or she exiles a card that shares a card type with it. That
// player may cast that card without paying its mana cost. Then he or she puts all cards exiled with
// the top of their library until they exile a card that shares a card type with it. That
// player may cast that card without paying its mana cost. Then they put all cards exiled with
// Possibility Storm on the bottom of their library in a random order.
addCard(Zone.BATTLEFIELD, playerA, "Possibility Storm", 1);
@ -74,8 +74,8 @@ public class PossibilityStormTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Whenever a player casts a spell from their hand, that player exiles it, then exiles cards from
// the top of their library until he or she exiles a card that shares a card type with it. That
// player may cast that card without paying its mana cost. Then he or she puts all cards exiled with
// the top of their library until they exile a card that shares a card type with it. That
// player may cast that card without paying its mana cost. Then they put all cards exiled with
// Possibility Storm on the bottom of their library in a random order.
addCard(Zone.BATTLEFIELD, playerA, "Possibility Storm", 1);

View file

@ -40,7 +40,7 @@ public class ShuffleTriggeredTest extends CardTestPlayerBase {
* lasse, dann triggert Widespread Panic für ihn (sollte garnicht triggern).
* Bei Bribery ist es genauso.
*
* If I have an opponent shuffle his library using Knowledge Exploitation, Widespread Panic triggers for him (shoudn't trigger at all). Same thing with Bribery.
* If I have an opponent shuffle their library using Knowledge Exploitation, Widespread Panic triggers for them (shoudn't trigger at all). Same thing with Bribery.
*/
@Test
public void testWidespreadPanicDoesNotTriggerIfOpponentShufflesPlayersLibrary() {

View file

@ -233,7 +233,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
once for each instances of the word target in the text
of a spell or ability. In this case, the target can't be changed
due to Spellskite already being a target.
*/
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
@ -258,8 +258,6 @@ public class SpellskiteTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
setChoice(playerB, "Yes"); // pay 2 life
showBattlefield("B battle", 1, PhaseStep.BEGIN_COMBAT, playerB);
showGraveyard("B grave", 1, PhaseStep.BEGIN_COMBAT, playerB);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
@ -274,7 +272,7 @@ public class SpellskiteTest extends CardTestPlayerBase {
public void testThatSplitDamageCanGetRedirected() {
/* Standard redirect test
The Spellskite should die from the 5 damage that was redirected to it
*/
*/
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.triggers;
import mage.abilities.keyword.TrampleAbility;
@ -8,7 +7,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class ZadaHedronGrinderTest extends CardTestPlayerBase {
@ -43,7 +41,70 @@ public class ZadaHedronGrinderTest extends CardTestPlayerBase {
assertAbility(playerA, "Zada, Hedron Grinder", TrampleAbility.getInstance(), true);
assertPowerToughness(playerA, "Silvercoat Lion", 4, 2);
assertAbility(playerA, "Silvercoat Lion", TrampleAbility.getInstance(), true);
}
@Test
public void testTargetsByTestPlayer() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for
// each other creature you control that the spell could target. Each copy targets a different one of those creatures.
addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1); // 3/3
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
//
// Put a +1/+1 counter on target creature. That creature gains reach until end of turn.
addCard(Zone.HAND, playerA, "Arbor Armament", 1); // {G}
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// cast
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arbor Armament", "Zada, Hedron Grinder");
addTarget(playerA, "Balduvian Bears^Silvercoat Lion");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Arbor Armament", 1);
assertPowerToughness(playerA, "Zada, Hedron Grinder", 3 + 1, 3 + 1);
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
assertPowerToughness(playerA, "Balduvian Bears", 2 + 1, 2 + 1);
}
@Test
public void testTargetsByAI() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
// Whenever you cast an instant or sorcery spell that targets only Zada, Hedron Grinder, copy that spell for
// each other creature you control that the spell could target. Each copy targets a different one of those creatures.
addCard(Zone.BATTLEFIELD, playerA, "Zada, Hedron Grinder", 1); // 3/3
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
//
// Put a +1/+1 counter on target creature. That creature gains reach until end of turn.
addCard(Zone.HAND, playerA, "Arbor Armament", 1); // {G}
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
// cast
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Arbor Armament", "Zada, Hedron Grinder");
//addTarget(playerA, "Balduvian Bears^Silvercoat Lion");
//setStrictChooseMode(true); // no strict mode for AI
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Arbor Armament", 1);
assertPowerToughness(playerA, "Zada, Hedron Grinder", 3 + 1, 3 + 1);
assertPowerToughness(playerA, "Silvercoat Lion", 2 + 1, 2 + 1);
assertPowerToughness(playerA, "Balduvian Bears", 2 + 1, 2 + 1);
}
}

View file

@ -44,7 +44,7 @@ public class ChandrasPhoenixTest extends CardTestPlayerBase {
// +1: Chandra Nalaar deals 1 damage to target player.
// -X: Chandra Nalaar deals X damage to target creature.
// -8: Chandra Nalaar deals 10 damage to target player and each creature he or she controls.
// -8: Chandra Nalaar deals 10 damage to target player and each creature they control.
addCard(Zone.BATTLEFIELD, playerA, "Chandra Nalaar", 1);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1", playerB);

View file

@ -0,0 +1,87 @@
package org.mage.test.cards.triggers.damage;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class SyrCarahTheBoldTest extends CardTestPlayerBase {
@Test
public void test_Damage() {
removeAllCardsFromLibrary(playerA);
removeAllCardsFromHand(playerA);
// When Syr Carah, the Bold or an instant or sorcery spell you control deals damage to a player, exile the top card of your library. You may play that card this turn.
// {T}: Syr Carah deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerA, "Syr Carah, the Bold", 1);
//
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
//
addCard(Zone.LIBRARY, playerA, "Swamp", 5);
//
// {1}, {T}, Sacrifice Aeolipile: It deals 2 damage to any target.
addCard(Zone.BATTLEFIELD, playerB, "Aeolipile", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
// 1 - triggers on ability damage
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: {source} deals", playerB);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
checkLife("damage 1", 1, PhaseStep.PRECOMBAT_MAIN, playerB, 20 - 1);
// 2 - triggers on spell damage
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN);
checkLife("damage 2", 1, PhaseStep.POSTCOMBAT_MAIN, playerB, 20 - 1 - 3);
// 3 - NONE triggers on another ability damage
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}, {T}, Sacrifice", playerA);
checkLife("damage 3", 2, PhaseStep.BEGIN_COMBAT, playerA, 20 - 2);
// 4 - triggers on combat damage
attack(3, playerA, "Syr Carah, the Bold", playerB);
checkLife("damage 4", 3, PhaseStep.POSTCOMBAT_MAIN, playerB, 20 - 1 - 3 - 3);
setStrictChooseMode(true);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
@Test
public void test_DamageWithCopyAbility() {
removeAllCardsFromLibrary(playerA);
removeAllCardsFromHand(playerA);
// When Syr Carah, the Bold or an instant or sorcery spell you control deals damage to a player, exile the top card of your library. You may play that card this turn.
// {T}: Syr Carah deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerA, "Syr Carah, the Bold", 1);
//
addCard(Zone.LIBRARY, playerA, "Swamp", 5);
//
// {T}: Embermage Goblin deals 1 damage to any target.
addCard(Zone.BATTLEFIELD, playerB, "Embermage Goblin", 1);
//
// Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy.
// Equip 3
addCard(Zone.BATTLEFIELD, playerB, "Illusionist's Bracers", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 3);
// equip to copy abilities
// showAvaileableAbilities("abils", 2, PhaseStep.PRECOMBAT_MAIN, playerB);
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Equip {3}", "Embermage Goblin");
setChoice(playerB, "No"); // no new target
// 3 - 2x damage (copy), but no trigger
// java.lang.ClassCastException: mage.game.stack.StackAbility cannot be cast to mage.game.stack.Spell
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: {source} deals", playerA);
checkLife("damage 3", 2, PhaseStep.END_TURN, playerA, 20 - 1 - 1);
setStrictChooseMode(true);
setStopAt(3, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
}

View file

@ -16,7 +16,7 @@ public class AngelicDestinyTest extends CardTestPlayerBase {
/**
* I killed my opponent's Champion of the Parish, which was enchanted with Angelic Destiny.
* However the Angelic Destiny went to the graveyard instead of returning his hand.
* However the Angelic Destiny went to the graveyard instead of returning to their hand.
*
*/
@Test

View file

@ -11,9 +11,9 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class BrainMaggotTest extends CardTestPlayerBase {
/**
* When Brain Maggot enters the battlefield, target opponent reveals his or
* her hand and you choose a nonland card from it. Exile that card until
* Brain Maggot leaves the battlefield.
* When Brain Maggot enters the battlefield, target opponent reveals their
* hand and you choose a nonland card from it. Exile that card until Brain
* Maggot leaves the battlefield.
*/
@Test
public void testCardFromHandWillBeExiled() {
@ -48,7 +48,7 @@ public class BrainMaggotTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brain Maggot");
addTarget(playerA, playerB);
setChoice(playerA, "Bloodflow Connoisseur");
showExile("exile", 1, PhaseStep.BEGIN_COMBAT, playerB);
// showExile("exile", 1, PhaseStep.BEGIN_COMBAT, playerB);
checkExileCount("blood must be in exile", 1, PhaseStep.BEGIN_COMBAT, playerB, "Bloodflow Connoisseur", 1);
// return

View file

@ -0,0 +1,168 @@
package org.mage.test.cards.triggers.dies;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.filter.Filter;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
*
* @author LevelX2
*/
public class ElendaTheDuskRoseTest extends CardTestPlayerBase {
@Test
public void testAddCounter() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
// Lifelink
// Whenever another creature dies, put a +1/+1 counter on Elenda, The Dusk Rose.
// When Elenda dies, create X 1/1 white Vampire creature tokens with lifelink, where X is Elenda's power.
addCard(Zone.HAND, playerA, "Elenda, the Dusk Rose", 1); // {2}{W}{B} 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Elenda, the Dusk Rose");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion");
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Elenda, the Dusk Rose", 1);
assertGraveyardCount(playerA, "Lightning Bolt", 1);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
assertPowerToughness(playerA, "Elenda, the Dusk Rose", 2, 2);
}
@Test
public void testCreateVampireTokens() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
// Lifelink
// Whenever another creature dies, put a +1/+1 counter on Elenda, The Dusk Rose.
// When Elenda dies, create X 1/1 white Vampire creature tokens with lifelink, where X is Elenda's power.
addCard(Zone.HAND, playerA, "Elenda, the Dusk Rose", 1); // {2}{W}{B} 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Elenda, the Dusk Rose");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion");
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Elenda, the Dusk Rose");
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Elenda, the Dusk Rose", 0);
assertGraveyardCount(playerA, "Lightning Bolt", 2);
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Elenda, the Dusk Rose", 1);
assertPermanentCount(playerA, "Vampire", 2);
assertPowerToughness(playerA, "Vampire", 1, 1, Filter.ComparisonScope.All);
}
@Test
public void testKillAndReanimate() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); /// 2/2
// Whenever a creature is put into your graveyard from the battlefield, you may sacrifice Angelic Renewal. If you do, return that card to the battlefield.
addCard(Zone.BATTLEFIELD, playerA, "Angelic Renewal", 1);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
addCard(Zone.HAND, playerB, "Lightning Bolt", 2);
// Lifelink
// Whenever another creature dies, put a +1/+1 counter on Elenda, The Dusk Rose.
// When Elenda dies, create X 1/1 white Vampire creature tokens with lifelink, where X is Elenda's power.
addCard(Zone.HAND, playerA, "Elenda, the Dusk Rose", 1); // {2}{W}{B} 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Elenda, the Dusk Rose");
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion");
castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Elenda, the Dusk Rose");
setChoice(playerA, "No"); // use Angelic Renewal on Silvercoat Lion
setChoice(playerA, "Yes"); // use Angelic Renewal on Elenda, the Dusk Rose
setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Elenda, the Dusk Rose", 1);
assertPowerToughness(playerA, "Elenda, the Dusk Rose", 1, 1);
assertGraveyardCount(playerB, "Lightning Bolt", 2);
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Elenda, the Dusk Rose", 0);
assertPermanentCount(playerA, "Vampire", 2);
assertPowerToughness(playerA, "Vampire", 1, 1, Filter.ComparisonScope.All);
}
@Test
public void testKillMultipleAndReanimate() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); /// 2/2
// Whenever a creature is put into your graveyard from the battlefield, you may sacrifice Angelic Renewal. If you do, return that card to the battlefield.
addCard(Zone.BATTLEFIELD, playerA, "Angelic Renewal", 1);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 3);
// Sweltering Suns deals 3 damage to each creature.
// Cycling {3} ({3}, Discard this card: Draw a card.)
addCard(Zone.HAND, playerB, "Sweltering Suns", 1); // Sorcery {1}{R}{R}
// Lifelink
// Whenever another creature dies, put a +1/+1 counter on Elenda, The Dusk Rose.
// When Elenda dies, create X 1/1 white Vampire creature tokens with lifelink, where X is Elenda's power.
addCard(Zone.HAND, playerA, "Elenda, the Dusk Rose", 1); // {2}{W}{B} 1/1
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Elenda, the Dusk Rose");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Sweltering Suns");
setChoice(playerA, "Yes"); // use Angelic Renewal on Elenda, the Dusk Rose
setChoice(playerA, "No"); // use Angelic Renewal on Silvercoat Lion
setStopAt(2, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Angelic Renewal", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 0);
assertPermanentCount(playerA, "Elenda, the Dusk Rose", 1);
assertPowerToughness(playerA, "Elenda, the Dusk Rose", 1, 1);
assertGraveyardCount(playerB, "Sweltering Suns", 1);
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
assertGraveyardCount(playerA, "Elenda, the Dusk Rose", 0);
assertPermanentCount(playerA, "Vampire", 1);
assertPowerToughness(playerA, "Vampire", 1, 1, Filter.ComparisonScope.All);
}
}

View file

@ -0,0 +1,33 @@
package org.mage.test.cards.triggers.dies;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author drmDev
*/
public class FootlightFiendTest extends CardTestPlayerBase {
@Test
public void test_GrizzlyBearBlocksFootlightFiend_BothDie()
{
addCard(Zone.BATTLEFIELD, playerA, "Footlight Fiend"); // (R/B) 1/1 on death pings any target for 1
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears"); // (G) 2/2
attack(1, playerA, "Footlight Fiend");
block(1, playerB, "Grizzly Bears", "Footlight Fiend");
addTarget(playerA, "Grizzly Bears");
setStopAt(1, PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Footlight Fiend", 1);
assertGraveyardCount(playerB, "Grizzly Bears", 1);
assertAllCommandsUsed();
}
}

View file

@ -15,7 +15,7 @@ public class ShowstopperTest extends CardTestPlayerBase {
/**
* Tests that the dies triggered ability of silvercoat lion (gained by Showstopper)
* triggers as he dies from Ligning Bolt
* triggers as he dies from Lightning Bolt
*
*/
@Test

View file

@ -8,14 +8,12 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author LevelX2, JayDi85
*/
public class TidehollowScullerTest extends CardTestPlayerBase {
/**
* Test if the same Tidehollow Sculler is cast multiple times, the correct
* corresponding exiled cards are returned
*/
@Test
public void test_CastOneCardFromHandWillBeExiled() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
@ -30,7 +28,6 @@ public class TidehollowScullerTest extends CardTestPlayerBase {
//
addCard(Zone.HAND, playerB, "Bloodflow Connoisseur", 1);
// cast and exile from hand
checkHandCardCount("B hand must have blood", 1, PhaseStep.UPKEEP, playerB, "Bloodflow Connoisseur", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tidehollow Sculler");
@ -86,7 +83,7 @@ public class TidehollowScullerTest extends CardTestPlayerBase {
checkPermanentCount("A must have 2 tide", 2, PhaseStep.UPKEEP, playerA, "Tidehollow Sculler", 2);
checkHandCardCount("B hand must have 0 blood", 2, PhaseStep.UPKEEP, playerB, "Bloodflow Connoisseur", 0);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "@tide.1");
showHand("B hand", 2, PhaseStep.BEGIN_COMBAT, playerB);
// showHand("B hand", 2, PhaseStep.BEGIN_COMBAT, playerB);
checkPermanentCount("A must have 1 tide", 2, PhaseStep.BEGIN_COMBAT, playerA, "Tidehollow Sculler", 1);
checkHandCardCount("B hand must have 1 blood", 2, PhaseStep.BEGIN_COMBAT, playerB, "Bloodflow Connoisseur", 1);
// destroy 2 and return card to hand
@ -115,4 +112,4 @@ public class TidehollowScullerTest extends CardTestPlayerBase {
}
}
}
}

View file

@ -14,9 +14,9 @@ public class TouchOfMoongloveTest extends CardTestPlayerBase {
/**
* I blocked my opponent's Pharika's Disciple with a Cleric of the Forward
* Order and Guardian Automaton. He cast Touch of Moonglove on his Pharika's
* Disciple and both of my creatures were killed, but I only lost 2 life
* instead of 4.(and gained 3 from Guardian Automaton dying).
* Order and Guardian Automaton. They cast Touch of Moonglove on their
* Pharika's Disciple and both of my creatures were killed, but I only lost
* 2 life instead of 4.(and gained 3 from Guardian Automaton dying).
*
*/
@Test

View file

@ -7,17 +7,18 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Whisperwood Elemental - Elemental {3}{G}{G}
* At the beginning of your end step, manifest the top card of your library.
* Sacrifice Whisperwood Elemental: Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library."
* Whisperwood Elemental - Elemental {3}{G}{G} At the beginning of your end
* step, manifest the top card of your library. Sacrifice Whisperwood Elemental:
* Until end of turn, face-up, nontoken creatures you control gain "When this
* creature dies, manifest the top card of your library."
*
* @author LevelX2
*/
public class WhisperwoodElementalTest extends CardTestPlayerBase {
/**
* Tests that the dies triggered ability of silvercoat lion (gained by sacrificed Whisperwood Elemental)
* triggers as he dies from Ligning Bolt
* Tests that the dies triggered ability of silvercoat lion (gained by
* sacrificed Whisperwood Elemental) triggers as he dies from Lightning Bolt
*/
@Test
public void testDiesTriggeredAbility() {
@ -29,8 +30,6 @@ public class WhisperwoodElementalTest extends CardTestPlayerBase {
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Until end of turn, face-up, nontoken creatures you control gain \"When this creature dies, manifest the top card of your library.");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Silvercoat Lion");
showBattlefield("A battle", 1, PhaseStep.END_TURN, playerA);
showGraveyard("A grave", 1, PhaseStep.END_TURN, playerA);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();

View file

@ -16,7 +16,7 @@ public class XathridNecromancerTest extends CardTestPlayerBase {
/**
* My opponent had 2 Human Tokens from Gather the Townsfolk and a Xathrid Necromancer.
* ( Whenever Xathrid Necromancer or another Human creature you control dies, put a 2/2 black Zombie creature token onto the battlefield tapped. )
* All 3 of them died in combat but he only got 1 Zombie token.
* All 3 of them died in combat but they only got 1 Zombie token.
* There was no first strike damage involved.
*
*/

View file

@ -542,4 +542,31 @@ public class AttackBlockRestrictionsTest extends CardTestPlayerBase {
assertLife(playerA, 20);
assertLife(playerB, 20);
}
@Test
public void irresistiblePreyMustBeBlockedTest() {
addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
addCard(Zone.BATTLEFIELD, playerA, "Alpha Myr");
addCard(Zone.BATTLEFIELD, playerA, "Forest");
addCard(Zone.HAND, playerA, "Irresistible Prey");
addCard(Zone.BATTLEFIELD, playerB, "Bronze Sable");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Irresistible Prey", "Llanowar Elves"); // must be blocked
attack(1, playerA, "Llanowar Elves");
attack(1, playerA, "Alpha Myr");
// attempt to block the creature that doesn't have "must be blocked"
block(1, playerB, "Bronze Sable", "Alpha Myr");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerA, "Irresistible Prey", 1);
assertGraveyardCount(playerA, "Llanowar Elves", 1);
assertGraveyardCount(playerB, "Bronze Sable", 1);
assertTapped("Alpha Myr", true);
assertLife(playerB, 18);
}
}

View file

@ -1,4 +1,3 @@
package org.mage.test.commander.duel;
import java.io.FileNotFoundException;
@ -82,4 +81,84 @@ public class CommanderReplaceEffectTest extends CardTestCommanderDuelBase {
assertPermanentCount(playerA, "Gift of Immortality", 1);
}
// https://github.com/magefree/mage/issues/5905
/* From the rulings of Soulherder:
If a creature is exiled but ends up in another zone (most likely because
its a players commander in the Commander variant), Soulherders first ability triggers.
I exiled an opponents Commander, but Soulherder did not trigger.*/
@Test
public void soulherderAndExiledCommanders() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
// Whenever a creature is exiled from the battlefield, put a +1/+1 counter on Soulherder.
// At the beginning of your end step, you may exile another target creature you control,
// then return that card to the battlefield under its owner's control.
addCard(Zone.HAND, playerA, "Soulherder", 1); // Creature {1}{W}{U}
// Daxos of Meletis can't be blocked by creatures with power 3 or greater.
// Whenever Daxos of Meletis deals combat damage to a player, exile the top card of that player's library. You gain life equal to that card's converted mana cost. Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Daxos of Meletis");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Soulherder");
setChoice(playerA, "Yes"); // Use Soulherder's triggered ability
addTarget(playerA, "Daxos of Meletis");
setChoice(playerA, "Yes"); // Move Daxos to command Zone
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertPermanentCount(playerA, "Soulherder", 1);
assertPermanentCount(playerA, "Daxos of Meletis", 0);
assertCommandZoneCount(playerA, "Daxos of Meletis", 1);
assertPowerToughness(playerA, "Soulherder", 2, 2);
}
@Test
public void soulherderAndDestroyedCommanders() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
// Whenever a creature is exiled from the battlefield, put a +1/+1 counter on Soulherder.
// At the beginning of your end step, you may exile another target creature you control,
// then return that card to the battlefield under its owner's control.
addCard(Zone.HAND, playerA, "Soulherder", 1); // Creature {1}{W}{U}
// Farm {2}{W} - Instant
// Destroy target attacking or blocking creature.
// Market {2}{U} - Sorcery
// Aftermath (Cast this spell only from your graveyard. Then exile it.)
// Draw two cards, then discard two cards.
addCard(Zone.HAND, playerB, "Farm // Market", 1);
addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
// Daxos of Meletis can't be blocked by creatures with power 3 or greater.
// Whenever Daxos of Meletis deals combat damage to a player, exile the top card of that player's library. You gain life equal to that card's converted mana cost. Until end of turn, you may cast that card and you may spend mana as though it were mana of any color to cast it.
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Daxos of Meletis");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Soulherder");
setChoice(playerA, "No"); // Use Soulherder's triggered ability
attack(3, playerA, "Daxos of Meletis");
castSpell(3, PhaseStep.DECLARE_BLOCKERS, playerB, "Farm", "Daxos of Meletis");
setChoice(playerA, "Yes"); // Move Daxos to command Zone
setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 40);
assertPermanentCount(playerA, "Soulherder", 1);
assertHandCount(playerB, "Farm // Market", 0);
assertGraveyardCount(playerB, "Farm // Market", 1);
assertPermanentCount(playerA, "Daxos of Meletis", 0);
assertCommandZoneCount(playerA, "Daxos of Meletis", 1);
assertPowerToughness(playerA, "Soulherder", 1, 1);
}
}

View file

@ -27,10 +27,9 @@ public class OpalPalaceTest extends CardTestCommanderDuelBase {
// equal to the number of times it's been cast from the command zone this game.
addCard(Zone.BATTLEFIELD, playerA, "Opal Palace", 1);
showHand("hand", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
showCommand("command", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
showAvaileableAbilities("abi", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showHand("hand", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showCommand("command", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
// showAvaileableAbilities("abi", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}");
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}, {T}");
setChoice(playerA, "Opal Palace"); // activate mana replace effect first (+3 counters)

View file

@ -1,14 +1,14 @@
package org.mage.test.load;
import java.util.UUID;
import mage.constants.PlayerAction;
import mage.interfaces.callback.CallbackClient;
import mage.interfaces.callback.ClientCallback;
import mage.remote.Session;
import mage.utils.CompressUtil;
import mage.view.*;
import org.apache.log4j.Logger;
import java.util.UUID;
/**
* @author JayDi85
*/
@ -23,19 +23,46 @@ public class LoadCallbackClient implements CallbackClient {
private boolean gameOver;
private String gameResult = "unknown";
private boolean needToConcede = false; // will concede on first priority
private boolean joinGameChat = false; // process CHATMESSAGE
private volatile int controlCount;
private GameView gameView;
public LoadCallbackClient(boolean joinGameChat) {
this.joinGameChat = joinGameChat;
}
@Override
public void processCallback(ClientCallback callback) {
callback.decompressData();
controlCount = 0;
callback.setData(CompressUtil.decompress(callback.getData()));
log.info(getLogStartInfo() + "callback: " + callback.getMethod());
// ignore bloaded logs
switch (callback.getMethod()) {
case CHATMESSAGE:
case GAME_INFORM:
case GAME_UPDATE:
break;
default:
log.info(getLogStartInfo() + "callback: " + callback.getMethod());
}
switch (callback.getMethod()) {
case GAME_INIT:
this.gameId = callback.getObjectId();
if (joinGameChat) {
session.joinChat(session.getGameChatId(gameId).get());
}
break;
case CHATMESSAGE: {
ChatMessage message = (ChatMessage) callback.getData();
log.info("Chat message: " + message.getMessage());
break;
}
case START_GAME: {
TableClientMessage message = (TableClientMessage) callback.getData();
log.info(getLogStartInfo() + "game started");
@ -50,7 +77,7 @@ public class LoadCallbackClient implements CallbackClient {
case GAME_INFORM_PERSONAL: {
GameClientMessage message = (GameClientMessage) callback.getData();
gameView = message.getGameView();
log.info(getLogStartInfo() + "Inform: " + message.getMessage());
//log.info(getLogStartInfo() + "Inform: " + message.getMessage());
break;
}
@ -126,9 +153,7 @@ public class LoadCallbackClient implements CallbackClient {
break;
// skip callbacks (no need to react)
case GAME_INIT:
case GAME_UPDATE:
case CHATMESSAGE:
case JOINED_TABLE:
break;

Some files were not shown because too many files have changed in this diff Show more