diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/ScalelordReckonerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/ScalelordReckonerTest.java new file mode 100644 index 00000000000..36182bd1c81 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/ScalelordReckonerTest.java @@ -0,0 +1,39 @@ +package org.mage.test.cards.single.c17; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author xenohedron + */ +public class ScalelordReckonerTest extends CardTestPlayerBase { + + private static final String scalelord = "Scalelord Reckoner"; // 4/4 Flying + // Whenever a Dragon you control becomes the target of a spell or ability an opponent controls, + // destroy target nonland permanent that player controls. + + @Test + public void testScalelordReckoner() { + + String machete = "Trusty Machete"; // a nonland permanent to destroy + String shock = "Shock"; // a spell to target with + + addCard(Zone.BATTLEFIELD, playerA, scalelord); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerB, machete, 1); + addCard(Zone.HAND, playerB, shock, 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, shock, scalelord); + addTarget(playerA, machete); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_COMBAT); + execute(); + + assertDamageReceived(playerA, scalelord, 2); + assertGraveyardCount(playerB, machete, 1); + + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/vow/BrineComberTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/vow/BrineComberTest.java index a15f46b2c07..5dd058345d9 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/vow/BrineComberTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/vow/BrineComberTest.java @@ -14,10 +14,11 @@ public class BrineComberTest extends CardTestPlayerBase { * Brine Comber * {1}{W}{U} * Creature — Spirit - * * Whenever Brine Comber enters the battlefield or becomes the target of an Aura spell, create a 1/1 white Spirit creature token with flying. - * * Disturb {W}{U} (You may cast this card from your graveyard transformed for its disturb cost.) + * Brinebound Gift + * Enchant creature + * Whenever Brinebound Gift enters the battlefield or enchanted creature becomes the target of an Aura spell, create a 1/1 white Spirit creature token with flying. */ private static final String comber = "Brine Comber"; @@ -74,4 +75,26 @@ public class BrineComberTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Hopeful Eidolon", 1); assertPowerToughness(playerA, comber, 1+1, 1+1); } + + @Test + public void testDisturbSideTrigger() { + setStrictChooseMode(true); + + String hatchling = "Kraken Hatchling"; // 0/4 + String umbra = "Hyena Umbra"; // Aura - gives +1/+1 and first strike + addCard(Zone.BATTLEFIELD, playerA, hatchling); + addCard(Zone.BATTLEFIELD, playerA, "Tundra", 3); + addCard(Zone.GRAVEYARD, playerA, comber); + addCard(Zone.HAND, playerA, umbra); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Brinebound Gift using Disturb", hatchling); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, umbra, hatchling); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Spirit Token", 2); // one from enter, one from target of next Aura + assertPermanentCount(playerA, "Brinebound Gift", 1); + assertPowerToughness(playerA, hatchling, 1, 5); + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTargetTriggerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTargetTriggerTest.java new file mode 100644 index 00000000000..6141bbd80e7 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/BecomesTargetTriggerTest.java @@ -0,0 +1,457 @@ +package org.mage.test.cards.triggers; + +import mage.abilities.keyword.FlyingAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.Filter; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class BecomesTargetTriggerTest extends CardTestPlayerBase { + + @Test + public void testAshenmoorLiege() { + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.HAND, playerA, "Claustrophobia"); // {1}{U}{U} + + // Other black creatures you control get +1/+1. + // Other red creatures you control get +1/+1. + // Whenever Ashenmoor Liege becomes the target of a spell or ability an opponent controls, that player loses 4 life. + addCard(Zone.BATTLEFIELD, playerB, "Ashenmoor Liege", 1); // 4/1 + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Claustrophobia", "Ashenmoor Liege"); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertLife(playerA, 16); + assertPermanentCount(playerA, "Claustrophobia", 1); + assertPowerToughness(playerB, "Ashenmoor Liege", 4, 1); + } + + @Test + public void testVeneratedRotpriest() { + String rotpriest = "Venerated Rotpriest"; // 1/2 + // Whenever a creature you control becomes the target of a spell, target opponent gets a poison counter. + String growth = "Giant Growth"; + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 1); + addCard(Zone.BATTLEFIELD, playerA, rotpriest); + addCard(Zone.HAND, playerA, growth); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, growth, rotpriest); + addTarget(playerA, playerB); // to get a poison counter + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertCounterCount(playerB, CounterType.POISON, 1); + assertPowerToughness(playerA, rotpriest, 4, 5); + } + + private static final String gKeeper = "Glyph Keeper"; // 5/3 Flying + // Whenever this creature becomes the target of a spell or ability for the first time in a turn, counter that spell or ability. + private static final String bolt = "Lightning Bolt"; + + @Test + public void testGlyphKeeperCountersFirstSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.HAND, playerA, bolt); + + addCard(Zone.BATTLEFIELD, playerB, gKeeper); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, bolt, 1); + assertPermanentCount(playerB, gKeeper, 1); + } + + @Test + public void testGlyphKeeperCountersFirstSpellEachTurn() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.HAND, playerA, bolt, 2); + + addCard(Zone.BATTLEFIELD, playerB, gKeeper); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, bolt, 2); + assertPermanentCount(playerB, gKeeper, 1); + } + + @Test + public void testGlyphKeeperCountersFirstSpellButNotSecondSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.HAND, playerA, bolt, 2); + + addCard(Zone.BATTLEFIELD, playerB, gKeeper); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, bolt, gKeeper); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.DECLARE_ATTACKERS); + execute(); + + assertGraveyardCount(playerA, bolt, 2); + assertPermanentCount(playerB, gKeeper, 0); + } + + @Test + public void testGlyphKeeperCountersFirstAbilityButNotSecondOne() { + /* + Soulstinger {3}{B} + Creature - Scorpion Demon 4/5 + When Soulstinger enters the battlefield, put two -1/-1 counter on target creature you control. + When Soulstinger dies, you may put a -1/-1 counter on target creature for each -1/-1 counter on Soulstinger. + */ + String sStinger = "Soulstinger"; + + /* + Cartouche of Strength {2}{G} + Enchantment - Aura Cartouche + Enchant creature you control + When Cartouche of Strength enters the battlefield, you may have enchanted creature fight target creature an opponent controls. + Enchanted creature gets +1/+1 and has trample. + */ + String cStrength = "Cartouche of Strength"; + String memnite = "Memnite"; // {0} 1/1 + + addCard(Zone.BATTLEFIELD, playerA, gKeeper); + addCard(Zone.HAND, playerA, sStinger); + addCard(Zone.HAND, playerA, cStrength); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6); + addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); + addCard(Zone.BATTLEFIELD, playerB, memnite); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sStinger); + addTarget(playerA, gKeeper); // should be countered by Glyph Keeper clause as first ability targetting it + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cStrength, gKeeper); // should not be countered anymore + setChoice(playerA, true); + addTarget(playerA, memnite); // Cartouche of Strength fight + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + setStrictChooseMode(true); + execute(); + + assertPermanentCount(playerA, gKeeper, 1); + assertGraveyardCount(playerA, sStinger, 0); // countered + assertGraveyardCount(playerA, cStrength, 0); // should not be countered + assertPermanentCount(playerA, cStrength, 1); + assertGraveyardCount(playerB, memnite, 1); // dies from fight + assertPowerToughness(playerA, gKeeper, 6, 4, Filter.ComparisonScope.All); + // Soul Stinger should never have given it two -1/-1 counters + // And Cartouche of Strength gives +1/+1 + assertCounterCount(playerA, gKeeper, CounterType.M1M1, 0); + } + + @Test + public void testDiffusionSliver() { + String diffusion = "Diffusion Sliver"; // 1/1 Sliver + // Whenever a Sliver creature you control becomes the target of a spell or ability an opponent controls, + // counter that spell or ability unless its controller pays {2}. + String metallic = "Metallic Sliver"; // 1/1 Sliver + + addCard(Zone.BATTLEFIELD, playerA, diffusion); + addCard(Zone.BATTLEFIELD, playerA, metallic); + + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, bolt, 1); + addCard(Zone.BATTLEFIELD, playerB, "Cunning Sparkmage", 1); // 0/1 Haste + // {T}: Cunning Sparkmage deals 1 damage to any target. + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, bolt, metallic); + setChoice(playerB, false); // choose not to pay + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{T}: {this} deals", diffusion); + setChoice(playerB, false); // choose not to pay + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerB, bolt, 1); + assertTapped("Cunning Sparkmage", true); + assertPermanentCount(playerA, diffusion, 1); + assertPermanentCount(playerA, metallic, 1); + } + + @Test + public void testThunderbreakRegent() { + String dragon = "Thunderbreak Regent"; // 4/4 + // Whenever a Dragon you control becomes the target of a spell or ability an opponent controls, Thunderbreak Regent deals 3 damage to that player. + + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.BATTLEFIELD, playerA, dragon); + addCard(Zone.HAND, playerB, bolt); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, bolt, dragon); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertDamageReceived(playerA, dragon, 3); + assertLife(playerB, 17); + } + + @Test + public void testCloudCover() { + String cloud = "Cloud Cover"; // Enchantment + // Whenever another permanent you control becomes the target of a spell or ability an opponent controls, + // you may return that permanent to its owner’s hand. + String myr = "Omega Myr"; // 1/2 + + addCard(Zone.BATTLEFIELD, playerB, "Cunning Sparkmage"); + addCard(Zone.BATTLEFIELD, playerA, cloud); + addCard(Zone.BATTLEFIELD, playerA, myr); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{T}: {this} deals", myr); + setChoice(playerA, true); // return to hand + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertHandCount(playerA, myr, 1); + assertTapped("Cunning Sparkmage", true); + } + + @Test + public void testIllusionaryArmor() { + String armor = "Illusionary Armor"; // Enchantment - Aura {4}{U} + // Enchant creature + // Enchanted creature gets +4/+4. + // When enchanted creature becomes the target of a spell or ability, sacrifice Illusionary Armor. + String beast = "Axebane Beast"; // 3/4 + + addCard(Zone.BATTLEFIELD, playerA, beast); + addCard(Zone.BATTLEFIELD, playerA, "Island", 5); + addCard(Zone.HAND, playerA, armor); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, bolt); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, armor, beast); + checkPT("Boosted", 1, PhaseStep.BEGIN_COMBAT, playerA, beast, 7, 8); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, bolt, beast); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, armor, 1); + assertPowerToughness(playerA, beast, 3, 4); + assertDamageReceived(playerA, beast, 3); + } + + @Test + public void testFracturedLoyalty() { + String hatchling = "Kraken Hatchling"; // 0/4 + String aura = "Fractured Loyalty"; // Enchantment - Aura {1}{R} + // Whenever enchanted creature becomes the target of a spell or ability, + // that spell or ability's controller gains control of that creature. (This effect lasts indefinitely.) + + addCard(Zone.BATTLEFIELD, playerA, hatchling); + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.HAND, playerA, aura); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, bolt); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, aura, hatchling); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, bolt, hatchling); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerB, bolt, 1); + assertPermanentCount(playerA, hatchling, 0); + assertDamageReceived(playerB, hatchling, 3); + } + + @Test + public void testDormantGomazoa() { + String gomazoa = "Dormant Gomazoa"; // 5/5 Flying {1}{U}{U} + // Dormant Gomazoa enters the battlefield tapped. + // Dormant Gomazoa doesn't untap during your untap step. + // Whenever you become the target of a spell, you may untap Dormant Gomazoa. + + addCard(Zone.HAND, playerA, gomazoa); + addCard(Zone.BATTLEFIELD, playerA, "Island", 3); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, bolt); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, gomazoa); + checkPermanentTapped("Enters tapped", 1, PhaseStep.BEGIN_COMBAT, playerA, gomazoa, true, 1); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, bolt, playerA); + setChoice(playerA, true); // choose to untap + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerB, bolt, 1); + assertTapped(gomazoa, false); + assertLife(playerA, 17); + } + + private static final String mammoth = "Battle Mammoth"; // 6/5 Trample + // Whenever a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card. + private static final String bear = "Runeclaw Bear"; // 2/2 + private static final String cBond = "Common Bond"; // 1GW Instant + // Put a +1/+1 counter on target creature. Put a +1/+1 counter on target creature. + + @Test + public void testBattleMammothSeparateTargets() { + addCard(Zone.BATTLEFIELD, playerA, mammoth); + addCard(Zone.BATTLEFIELD, playerA, bear); + addCard(Zone.BATTLEFIELD, playerB, "Savannah", 3); + addCard(Zone.HAND, playerB, cBond); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, cBond, mammoth+"^"+bear); + setChoice(playerA, "Whenever"); // order two triggers + setChoice(playerA, true); // draw a card + setChoice(playerA, true); // draw a card + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, cBond, 1); + assertPowerToughness(playerA, mammoth, 7, 6); + assertPowerToughness(playerA, bear, 3, 3); + assertHandCount(playerA, 2); + } + + @Test + public void testBattleMammothSameTarget() { + addCard(Zone.BATTLEFIELD, playerA, mammoth); + addCard(Zone.BATTLEFIELD, playerA, bear); + addCard(Zone.BATTLEFIELD, playerB, "Savannah", 3); + addCard(Zone.HAND, playerB, cBond); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, cBond, bear+"^"+bear); + // Should be only one trigger here + setChoice(playerA, true); // draw a card + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, cBond, 1); + assertPowerToughness(playerA, bear, 4, 4); + assertHandCount(playerA, 1); + } + + @Test + public void testBattleMammothRepeatAbility() { + addCard(Zone.BATTLEFIELD, playerA, mammoth); + addCard(Zone.BATTLEFIELD, playerA, bear); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 8); + addCard(Zone.BATTLEFIELD, playerB, "Shapers of Nature"); // 3/3 + // {3}{G}: Put a +1/+1 counter on target creature. + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{3}{G}: Put", bear); + setChoice(playerA, true); // draw a card + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{3}{G}: Put", bear); + setChoice(playerA, true); // draw a card + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, bear, 4, 4); + assertHandCount(playerA, 2); + } + + @Test + public void testAngelicCubDoubleTarget() { + String cub = "Angelic Cub"; // 1/1 + // Whenever Angelic Cub becomes the target of a spell or ability for the first time each turn, put a +1/+1 counter on it. + // As long as Angelic Cub has three or more +1/+1 counters on it, it has flying. + + addCard(Zone.BATTLEFIELD, playerA, cub); + addCard(Zone.BATTLEFIELD, playerA, "Savannah", 3); + addCard(Zone.HAND, playerA, cBond); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cBond, cub+"^"+cub); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, cub, 4, 4); + assertAbility(playerA, cub, FlyingAbility.getInstance(), true); + } + + @Test + public void testUnsettledMarinerFieldOfRuin() { + // Reported bug: #10530 + String mariner = "Unsettled Mariner"; // 2/2 + // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, + // counter that spell or ability unless its controller pays {1}. + String ruin = "Field of Ruin"; // 2/2 + // {2}, {T}, Sacrifice Field of Ruin: Destroy target nonbasic land an opponent controls. + // Each player searches their library for a basic land card, puts it onto the battlefield, then shuffles. + + addCard(Zone.BATTLEFIELD, playerA, mariner); + addCard(Zone.BATTLEFIELD, playerA, "Evolving Wilds"); + addCard(Zone.BATTLEFIELD, playerB, ruin); + addCard(Zone.BATTLEFIELD, playerB, "Wastes", 2); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{2}, {T}, Sacrifice"); + addTarget(playerB, "Evolving Wilds"); + setChoice(playerB, false); // choose not to pay + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, 0); + assertGraveyardCount(playerB, ruin, 1); + } + + @Test + public void testCounterAbilitySacrificedSource() { + // related to #10530, but this one works fine regardless... + String mariner = "Unsettled Mariner"; // 2/2 + // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, + // counter that spell or ability unless its controller pays {1}. + String felidar = "Felidar Cub"; // 2/2 + // Sacrifice Felidar Cub: Destroy target enchantment. + String anthem = "Glorious Anthem"; // Creatures you control get +1/+1. + + addCard(Zone.BATTLEFIELD, playerA, mariner); + addCard(Zone.BATTLEFIELD, playerA, anthem); + addCard(Zone.BATTLEFIELD, playerB, felidar); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice"); + addTarget(playerB, anthem); + setChoice(playerB, false); // choose not to pay + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerB, felidar, 1); + assertPowerToughness(playerA, mariner, 3, 3); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/TargetedTriggeredTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/TargetedTriggeredTest.java deleted file mode 100644 index a58df8f083f..00000000000 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/TargetedTriggeredTest.java +++ /dev/null @@ -1,183 +0,0 @@ - -package org.mage.test.cards.triggers; - -import mage.constants.PhaseStep; -import mage.constants.Zone; -import mage.counters.CounterType; -import mage.filter.Filter; -import org.junit.Ignore; -import org.junit.Test; -import org.mage.test.serverside.base.CardTestPlayerBase; - -/** - * - * @author LevelX2 - */ -public class TargetedTriggeredTest extends CardTestPlayerBase { - - /** - * Tests that the first spell that targets Kira, Great Glass-Spinner is - * countered. - * - */ - @Test - // this does not currently work in test (????), because the target event will be fired earlier during tests, - // so the zone change counter for the fixed target of the counterspell will not work - // UPDATE: seems to work fine now? 04/19/2017 escplan9 - public void testKiraGreatGlassSpinnerFirstSpellTurn() { - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); - addCard(Zone.HAND, playerA, "Lightning Bolt"); - - addCard(Zone.BATTLEFIELD, playerB, "Kira, Great Glass-Spinner", 1); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Kira, Great Glass-Spinner"); - - setStopAt(1, PhaseStep.BEGIN_COMBAT); - execute(); - - assertGraveyardCount(playerA, "Lightning Bolt", 1); - - assertPermanentCount(playerB, "Kira, Great Glass-Spinner", 1); - } - - /** - * With Ashenmoor Liege on the battlefield, my opponent casts Claustrophobia - * on it without losing 4hp. - */ - @Test - public void testAshenmoorLiege() { - addCard(Zone.BATTLEFIELD, playerA, "Island", 3); - addCard(Zone.HAND, playerA, "Claustrophobia"); // {1}{U}{U} - - // Other black creatures you control get +1/+1. - // Other red creatures you control get +1/+1. - // Whenever Ashenmoor Liege becomes the target of a spell or ability an opponent controls, that player loses 4 life. - addCard(Zone.BATTLEFIELD, playerB, "Ashenmoor Liege", 1); // 4/1 - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Claustrophobia", "Ashenmoor Liege"); - - setStopAt(1, PhaseStep.BEGIN_COMBAT); - execute(); - - assertLife(playerA, 16); - - assertPermanentCount(playerA, "Claustrophobia", 1); - assertPowerToughness(playerB, "Ashenmoor Liege", 4, 1); - } - - @Test - public void testGlyphKeeperCountersFirstSpell() { - - /* - Glyph Keeper {3}{U}{U} - Creature - Sphinx - Flying 5/3 - Whenever this creature becomes the target of a spell or ability for the first time in a turn, counter that spell or ability." - */ - String gKeeper = "Glyph Keeper"; - String bolt = "Lightning Bolt"; // {R} instant deal 3 dmg - - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); - addCard(Zone.HAND, playerA, bolt); - - addCard(Zone.BATTLEFIELD, playerB, gKeeper); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); - - setStopAt(1, PhaseStep.BEGIN_COMBAT); - execute(); - - assertGraveyardCount(playerA, bolt, 1); - assertPermanentCount(playerB, gKeeper, 1); - } - - @Test - public void testGlyphKeeperCountersFirstSpellButNotSecondSpell() { - - /* - Glyph Keeper {3}{U}{U} - Creature - Sphinx - Flying 5/3 - Whenever this creature becomes the target of a spell or ability for the first time in a turn, counter that spell or ability." - */ - String gKeeper = "Glyph Keeper"; - String bolt = "Lightning Bolt"; // {R} instant deal 3 dmg - - addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); - addCard(Zone.HAND, playerA, bolt, 2); - - addCard(Zone.BATTLEFIELD, playerB, gKeeper); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, gKeeper); - castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, bolt, gKeeper); - - setStopAt(1, PhaseStep.DECLARE_ATTACKERS); - execute(); - - assertGraveyardCount(playerA, bolt, 2); - assertPermanentCount(playerB, gKeeper, 0); - } - - /* - NOTE: test was failing due to card bug, resolved as of 04/20/2017. See issue #3180 - I had a Glyph Keeper on board (cloned with Vizier of many faces). -- note this test is a simplified version, next test will test on the Clone if needed - First I played a Soulstinger and targeted the Glyph Keeper, the ability was countered. Then on the same main phase I played a Cartouche of Strength targeting the Glyph Keeper, that was also countered. - Only the first should have been countered. - */ - @Test - public void testGlyphKeeperCountersFirstAbilityButNotSecondOne() { - - /* - Glyph Keeper {3}{U}{U} - Creature - Sphinx - Flying 5/3 - Whenever this creature becomes the target of a spell or ability for the first time in a turn, counter that spell or ability." - */ - String gKeeper = "Glyph Keeper"; - - /* - Soulstinger {3}{B} - Creature - Scorpion Demon 4/5 - When Soulstinger enters the battlefield, put two -1/-1 counter on target creature you control. - When Soulstinger dies, you may put a -1/-1 counter on target creature for each -1/-1 counter on Soulstinger. - */ - String sStinger = "Soulstinger"; - - /* - Cartouche of Strength {2}{G} - Enchantment - Aura Cartouche - Enchant creature you control - When Cartouche of Strength enters the battlefield, you may have enchanted creature fight target creature an opponent controls. - Enchanted creature gets +1/+1 and has trample. - */ - String cStrength = "Cartouche of Strength"; - String memnite = "Memnite"; // {0} 1/1 - - addCard(Zone.BATTLEFIELD, playerA, gKeeper); - addCard(Zone.HAND, playerA, sStinger); - addCard(Zone.HAND, playerA, cStrength); - addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6); - addCard(Zone.BATTLEFIELD, playerA, "Forest", 6); - addCard(Zone.BATTLEFIELD, playerB, memnite); - - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sStinger); - addTarget(playerA, gKeeper); // should be countered by Glyph Keeper clause as first ability targetting it - waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); - castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cStrength, gKeeper); // should not be countered anymore - setChoice(playerA, true); - addTarget(playerA, memnite); // Cartouche of Strength fight - - setStopAt(1, PhaseStep.BEGIN_COMBAT); - setStrictChooseMode(true); - execute(); - - assertPermanentCount(playerA, gKeeper, 1); - assertGraveyardCount(playerA, sStinger, 0); // countered - assertGraveyardCount(playerA, cStrength, 0); // should not be countered - assertPermanentCount(playerA, cStrength, 1); - assertGraveyardCount(playerB, memnite, 1); // dies from fight - assertPowerToughness(playerA, gKeeper, 6, 4, Filter.ComparisonScope.All); // Soul Stinger should never have given it two -1/-1 counters - //And Cartouche of Strength gives +1/+1 - assertCounterCount(playerA, gKeeper, CounterType.M1M1, 0); - } -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java index bb493a311b0..b07ff85a931 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/watchers/KiraGreatGlassSpinnerTest.java @@ -17,17 +17,19 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { Flying Creatures you control have "Whenever this creature becomes the target of a spell or ability for the first time each turn, counter that spell or ability." */ - private final String kira = "Kira, Great Glass-Spinner"; - private final String ugin = "Ugin, the Spirit Dragon"; + private static final String kira = "Kira, Great Glass-Spinner"; + private static final String ugin = "Ugin, the Spirit Dragon"; + private static final String bolt = "Lightning Bolt"; @Test public void counterFirst() { - addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters + addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyalty counters addCard(Zone.BATTLEFIELD, playerA, kira); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage", kira); // Ugin ability + setStrictChooseMode(true); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -38,8 +40,7 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { @Test public void counterFirstResolveSecond() { - String ugin = "Ugin, the Spirit Dragon"; - addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters + addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyalty counters addCard(Zone.BATTLEFIELD, playerA, "Island", 4); addCard(Zone.HAND, playerA, "Unsummon", 1); @@ -48,6 +49,7 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Unsummon", kira); + setStrictChooseMode(true); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -59,12 +61,13 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { @Test public void counterFirstThisTurn_counterFirstOnNextTurn() { - addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyality counters + addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyalty counters addCard(Zone.BATTLEFIELD, playerA, kira); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage to", kira); // Ugin ability activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage to", kira); // Ugin ability + setStrictChooseMode(true); setStopAt(3, PhaseStep.END_TURN); execute(); @@ -72,4 +75,105 @@ public class KiraGreatGlassSpinnerTest extends CardTestPlayerBase { assertCounterCount(playerA, ugin, CounterType.LOYALTY, 11); } + + @Test + public void testKiraGreatGlassSpinnerFirstSpellTurn() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); + addCard(Zone.HAND, playerA, bolt); + addCard(Zone.BATTLEFIELD, playerB, kira, 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bolt, kira); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, bolt, 1); + assertPermanentCount(playerB, kira, 1); + } + + @Test + public void testKiraGreatGlassSpinnerRightAbility() { + // Reported bug: #8026 + addCard(Zone.BATTLEFIELD, playerA, "Steadfast Guard", 1); // 2/2 Vigilance + addCard(Zone.BATTLEFIELD, playerA, "Angelic Benediction", 1); // Exalted + // Whenever a creature you control attacks alone, you may tap target creature. + addCard(Zone.BATTLEFIELD, playerB, kira, 1); + + attack(1, playerA, "Steadfast Guard", playerB); + setChoice(playerA, "Whenever"); // choose trigger order - exalted at top of stack + addTarget(playerA, kira); // creature to tap + //setChoice(playerA, true); // choose yes to tap - gets countered before choice needed + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 17); // exalted pumps 2/2 to 3/3, so 3 life lost + assertTapped(kira, false); // tap ability was countered + } + + @Test + public void testKiraGreatGlassSpinnerRightAbilityOtherOrder() { + // Reported bug: #8026 + addCard(Zone.BATTLEFIELD, playerA, "Steadfast Guard", 1); // 2/2 Vigilance + addCard(Zone.BATTLEFIELD, playerA, "Angelic Benediction", 1); // Exalted + // Whenever a creature you control attacks alone, you may tap target creature. + addCard(Zone.BATTLEFIELD, playerB, kira, 1); + + attack(1, playerA, "Steadfast Guard", playerB); + setChoice(playerA, "exalted"); // just in case... try the other trigger order + addTarget(playerA, kira); // creature to tap + //setChoice(playerA, true); // choose yes to tap - gets countered before choice needed + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); + execute(); + + assertLife(playerB, 17); // exalted pumps 2/2 to 3/3, so 3 life lost + assertTapped(kira, false); // tap ability was countered + } + + @Test + public void counterFirstBlinkCounterNext() { + addCard(Zone.BATTLEFIELD, playerA, ugin); // starts with 7 Loyalty counters + addCard(Zone.BATTLEFIELD, playerA, "Plateau", 2); + addCard(Zone.HAND, playerA, "Shock", 1); + addCard(Zone.HAND, playerA, "Cloudshift", 1); + addCard(Zone.BATTLEFIELD, playerA, kira); + + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+2: {this} deals 3 damage", kira); // Ugin ability, countered + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Cloudshift", kira); // not countered (second time being targeted) + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Shock", kira); // countered (zcc has changed, so first time again) + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, kira, 1); + assertCounterCount(playerA, ugin, CounterType.LOYALTY, 9); + assertGraveyardCount(playerA, "Shock", 1); + assertGraveyardCount(playerA, "Cloudshift", 1); + } + + @Test + public void counterCorrectlyMultipleOnStack() { + addCard(Zone.BATTLEFIELD, playerA, "Forest", 5); + addCard(Zone.HAND, playerA, "Battlegrowth", 1); // Instant {G} Put a +1/+1 counter on target creature. + addCard(Zone.HAND, playerA, "Dragonscale Boon", 1); // Instant {3}{G} Put two +1/+1 counters on target creature and untap it. + addCard(Zone.BATTLEFIELD, playerA, kira); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Battlegrowth", kira); // countered + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragonscale Boon", kira); // not countered (second target) + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, kira, 1); + assertGraveyardCount(playerA, "Battlegrowth", 1); + assertGraveyardCount(playerA, "Dragonscale Boon", 1); + assertPowerToughness(playerA, kira, 4, 4); + } + }