mirror of
https://github.com/magefree/mage.git
synced 2026-01-22 11:19:55 -08:00
Merge origin/master
This commit is contained in:
commit
47fb2c1ac5
71 changed files with 1992 additions and 497 deletions
|
|
@ -0,0 +1,48 @@
|
|||
package org.mage.test.cards.abilities.equipped;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
|
||||
*/
|
||||
public class KusariGamaTest extends CardTestPlayerBase {
|
||||
|
||||
// reported bug: trigger occurs but no damage is dealt
|
||||
@Test
|
||||
public void testTriggeredAbilityDealsDamage() {
|
||||
|
||||
// Kusari-Gama - Artifact Equipment - Equip {3}
|
||||
// Equipped creature has "2: This creature gets +1/+0 until end of turn."
|
||||
// Whenever equipped creature deals damage to a blocking creature, Kusari-Gama deals that much damage to each other creature defending player controls.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kusari-Gama");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sylvan Advocate"); // 2/3 vigilance {1}{G}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Wall of Omens"); // 0/4 {1}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2); // 2/2 {1}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Hill Giant"); // 3/3 {3}{R}
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {3}", "Sylvan Advocate");
|
||||
attack(1, playerA, "Sylvan Advocate");
|
||||
block(1, playerB, "Wall of Omens", "Sylvan Advocate");
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Kusari-Gama", 1);
|
||||
assertPermanentCount(playerB, "Wall of Omens", 1);
|
||||
assertPermanentCount(playerB, "Hill Giant", 1);
|
||||
|
||||
Permanent wallPerm = getPermanent("Wall of Omens", playerB);
|
||||
Permanent giantPerm = getPermanent("Hill Giant", playerB);
|
||||
Assert.assertEquals("Wall of Omens should have 2 damage dealt to it", 2, wallPerm.getDamage());
|
||||
Assert.assertEquals("Hill Giant should have 2 damage dealt to it", 2, giantPerm.getDamage());
|
||||
|
||||
assertGraveyardCount(playerB, "Silvercoat Lion", 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
|
||||
Assert.assertEquals("Nighthowler has to be a creature", true, nighthowler.getCardType().contains(CardType.CREATURE));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSightlessBrawlerCantAttackAloneEnforced() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
|
@ -373,14 +373,14 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
// Enchanted creature gets +3/+2 and can't attack alone.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sightless Brawler");
|
||||
|
||||
attack(1, playerA, "Sightless Brawler");
|
||||
setStopAt(1,PhaseStep.END_COMBAT);
|
||||
attack(1, playerA, "Sightless Brawler");
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertLife(playerB, 20);
|
||||
assertTapped("Sightless Brawler", false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSightlessBrawlerAttacksWithOthers() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
|
@ -389,18 +389,18 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
// Bestow 4W (If you cast this card for its bestow cost, it's an Aura spell with enchant creature. It becomes a creature again if it's not attached to a creature.)
|
||||
// Sightless Brawler can't attack alone.
|
||||
// Enchanted creature gets +3/+2 and can't attack alone.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sightless Brawler");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sightless Brawler"); // 3/2
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Elite Vanguard"); // {W} 2/1 creature
|
||||
|
||||
attack(1, playerA, "Sightless Brawler");
|
||||
attack(1, playerA, "Elite Vanguard");
|
||||
setStopAt(1,PhaseStep.END_COMBAT);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertLife(playerB, 15);
|
||||
assertTapped("Sightless Brawler", true);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSightlessBrawlerBestowedCantAttackAloneEnforced() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
|
@ -414,15 +414,15 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sightless Brawler using bestow", "Elite Vanguard");
|
||||
attack(1, playerA, "Elite Vanguard");
|
||||
setStopAt(1,PhaseStep.END_COMBAT);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertHandCount(playerA, "Sightless Brawler", 0);
|
||||
assertLife(playerB, 20);
|
||||
assertTapped("Elite Vanguard", false);
|
||||
assertPowerToughness(playerA, "Elite Vanguard", 5, 3); // 2/1 + 3/2 = 5/3
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSightlessBrawlerBestowedAttacksWithOthers() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
|
@ -438,9 +438,9 @@ public class BestowTest extends CardTestPlayerBase {
|
|||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sightless Brawler using bestow", "Elite Vanguard");
|
||||
attack(1, playerA, "Elite Vanguard");
|
||||
attack(1, playerA, "Memnite");
|
||||
setStopAt(1,PhaseStep.END_COMBAT);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertHandCount(playerA, "Sightless Brawler", 0);
|
||||
assertLife(playerB, 14);
|
||||
assertTapped("Elite Vanguard", true);
|
||||
|
|
|
|||
|
|
@ -115,5 +115,45 @@ public class EscalateTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerB, "Gaddock Teeg", 1);
|
||||
assertLife(playerB, 17);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpellQuellerInteraction_ThreeCMC_ThreeModes() {
|
||||
|
||||
// {1}{W}{U} Flash Flying 2/3 Spirit
|
||||
// When Spell Queller enters the battlefield, exile target spell with converted mana cost 4 or less.
|
||||
// When Spell Queller leaves the battlefield, the exiled card's owner may cast that card without paying its mana cost.
|
||||
addCard(Zone.HAND, playerB, "Spell Queller");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Wall of Omens"); // {1}{W} 0/4
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 1);
|
||||
|
||||
// Escalate {1} (Pay this cost for each mode chosen beyond the first.)
|
||||
// Choose one or more —
|
||||
// * Target player discards all the cards in his or her hand, then draws that many cards.
|
||||
// * Collective Defiance deals 4 damage to target creature.
|
||||
// * Collective Defiance deals 3 damage to target opponent.
|
||||
addCard(Zone.HAND, playerA, "Collective Defiance"); // {1}{R}{R} sorcery
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Collective Defiance", "mode=2Wall of Omens");
|
||||
setModeChoice(playerA, "1"); // opponent discards hand and draws that many
|
||||
setModeChoice(playerA, "2"); // deal 4 dmg to target creature (Wall of Omens)
|
||||
setModeChoice(playerA, "3"); // deal 3 dmg to opponent
|
||||
addTarget(playerA, playerB); // mode 1
|
||||
addTarget(playerA, playerB); // mode 3
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Spell Queller");
|
||||
addTarget(playerB, "Collective Defiance");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, "Spell Queller", 1);
|
||||
assertHandCount(playerA, "Collective Defiance", 0);
|
||||
assertExileCount("Collective Defiance", 1);
|
||||
assertGraveyardCount(playerA, "Collective Defiance", 0);
|
||||
assertPermanentCount(playerB, "Wall of Omens", 1);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -244,15 +244,15 @@ public class FlashbackTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Silent Departure", 1);
|
||||
assertGraveyardCount(playerA, "Runic Repetition", 1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAltarsReap() {
|
||||
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Island", 2);
|
||||
addCard(Zone.GRAVEYARD, playerA, "Altar's Reap", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Underground Sea", 4);
|
||||
addCard(Zone.HAND, playerA, "Snapcaster Mage", 1);
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
|
||||
setChoice(playerA, "Altar's Reap");
|
||||
|
||||
|
|
@ -261,7 +261,48 @@ public class FlashbackTest extends CardTestPlayerBase {
|
|||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
|
||||
assertGraveyardCount(playerA, "Snapcaster Mage", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fracturing Gust is bugged. In a match against Affinity, it worked
|
||||
* properly when cast from hand. When I cast it from graveyard c/o
|
||||
* Snapcaster Mage flashback, it destroyed my opponent's Darksteel Citadels,
|
||||
* which it did not do when cast from my hand.
|
||||
*/
|
||||
@Test
|
||||
public void testSnapcasterMageWithIcefallRegent() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.HAND, playerA, "Snapcaster Mage", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
// Destroy target creature. It can't be regenerated.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Terminate");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Berserkers' Onslaught", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Icefall Regent", 1);
|
||||
|
||||
// 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.
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Snapcaster Mage");
|
||||
setChoice(playerA, "Terminate");
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Flashback"); // Flashback Terminate
|
||||
addTarget(playerA, "Icefall Regent");
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Snapcaster Mage", 1);
|
||||
assertGraveyardCount(playerB, "Icefall Regent", 1);
|
||||
assertExileCount("Terminate", 1);
|
||||
|
||||
assertTappedCount("Mountain", true, 2);
|
||||
assertTappedCount("Island", true, 2);
|
||||
assertTappedCount("Swamp", true, 2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,6 +225,8 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
*/
|
||||
@Test
|
||||
public void testPineWalkerWithUnboostEffect() {
|
||||
// Morph {4}{G}
|
||||
// Whenever Pine Walker or another creature you control is turned face up, untap that creature.
|
||||
addCard(Zone.HAND, playerA, "Pine Walker");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 8);
|
||||
|
||||
|
|
@ -641,24 +643,25 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerA, "Pine Walker", 5, 5);
|
||||
assertTapped("Pine Walker", false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reflector Mage bouncing a creature that can be played as a morph should not prevent the card
|
||||
* from being replayed as a morph. Morph creatures are nameless.
|
||||
*
|
||||
* Reported bug:
|
||||
* Face-up morph creatures that are bounced by Reflector Mage should be able to be replayed as morphs
|
||||
* without the "until the next turn" restriction."
|
||||
* Reflector Mage bouncing a creature that can be played as a morph should
|
||||
* not prevent the card from being replayed as a morph. Morph creatures are
|
||||
* nameless.
|
||||
*
|
||||
* Reported bug: Face-up morph creatures that are bounced by Reflector Mage
|
||||
* should be able to be replayed as morphs without the "until the next turn"
|
||||
* restriction."
|
||||
*/
|
||||
@Test
|
||||
public void testReflectorMageBouncesFaceupCreatureReplayAsMorph() {
|
||||
|
||||
// {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand.
|
||||
|
||||
// {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand.
|
||||
// That creature's owner can't cast spells with the same name as that creature until your next turn.
|
||||
addCard(Zone.HAND, playerA, "Reflector Mage"); // 2/3
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
|
||||
|
||||
//Tap: Add {G}, {U}, or {R} to your mana pool.
|
||||
// Morph 2 (You may cast this card face down as a 2/2 creature for 3. Turn it face up any time for its morph cost.)
|
||||
// When Rattleclaw Mystic is turned face up, add {G}{U}{R} to your mana pool.
|
||||
|
|
@ -666,36 +669,37 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerB, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reflector Mage");
|
||||
addTarget(playerA, "Rattleclaw Mystic");
|
||||
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Rattleclaw Mystic");
|
||||
setChoice(playerB, "Yes"); // cast it face down as 2/2 creature
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Reflector Mage", 1);
|
||||
assertPermanentCount(playerB, "Rattleclaw Mystic", 0);
|
||||
|
||||
assertPermanentCount(playerA, "Reflector Mage", 1);
|
||||
assertPermanentCount(playerB, "Rattleclaw Mystic", 0);
|
||||
assertHandCount(playerB, "Rattleclaw Mystic", 0); // should have been replayed
|
||||
assertPermanentCount(playerB, "", 1); // Rattleclaw played as a morph
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reflector Mage bouncing a creature that can be played as a morph should not prevent the card
|
||||
* from being replayed as a morph. Morph creatures are nameless.
|
||||
*
|
||||
* Reported bug:
|
||||
* Face-up morph creatures that are bounced by Reflector Mage should be able to be replayed as morphs
|
||||
* without the "until the next turn" restriction."
|
||||
*
|
||||
* Reflector Mage bouncing a creature that can be played as a morph should
|
||||
* not prevent the card from being replayed as a morph. Morph creatures are
|
||||
* nameless.
|
||||
*
|
||||
* Reported bug: Face-up morph creatures that are bounced by Reflector Mage
|
||||
* should be able to be replayed as morphs without the "until the next turn"
|
||||
* restriction."
|
||||
*
|
||||
* Testing bouncing a face-down creature played next turn face-up.
|
||||
*/
|
||||
@Test
|
||||
public void testReflectorMageBouncesMorphCreatureReplayAsFaceup() {
|
||||
|
||||
|
||||
//Tap: Add {G}, {U}, or {R} to your mana pool.
|
||||
// Morph 2 (You may cast this card face down as a 2/2 creature for 3. Turn it face up any time for its morph cost.)
|
||||
// When Rattleclaw Mystic is turned face up, add {G}{U}{R} to your mana pool.
|
||||
|
|
@ -703,28 +707,28 @@ public class MorphTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Forest");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
|
||||
// {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand.
|
||||
|
||||
// {1}{W}{U} When Reflector Mage enters the battlefield, return target creature an opponent controls to its owner's hand.
|
||||
// That creature's owner can't cast spells with the same name as that creature until your next turn.
|
||||
addCard(Zone.HAND, playerB, "Reflector Mage"); // 2/3
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
|
||||
addCard(Zone.HAND, playerB, "Reflector Mage"); // 2/3
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rattleclaw Mystic");
|
||||
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
|
||||
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Reflector Mage");
|
||||
addTarget(playerB, "");
|
||||
|
||||
|
||||
castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Rattleclaw Mystic");
|
||||
setChoice(playerA, "No"); // cast it face down as 2/2 creature
|
||||
|
||||
setStopAt(3, PhaseStep.BEGIN_COMBAT);
|
||||
|
||||
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, "Reflector Mage", 1);
|
||||
assertPermanentCount(playerA, "Rattleclaw Mystic", 1);
|
||||
|
||||
assertPermanentCount(playerB, "Reflector Mage", 1);
|
||||
assertPermanentCount(playerA, "Rattleclaw Mystic", 1);
|
||||
assertHandCount(playerA, "Rattleclaw Mystic", 0); // should have been replayed faceup
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
|
|
@ -38,15 +37,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
|||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ProliferateTest extends CardTestPlayerBase{
|
||||
public class ProliferateTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Volt Charge {2}{R}
|
||||
* Instant
|
||||
* Volt Charge deals 3 damage to target creature or player.
|
||||
* Proliferate. (You choose any number of permanents and/or players with counters
|
||||
* on them, then give each another counter of a kind already there.)
|
||||
* Volt Charge {2}{R} Instant Volt Charge deals 3 damage to target creature
|
||||
* or player. Proliferate. (You choose any number of permanents and/or
|
||||
* players with counters on them, then give each another counter of a kind
|
||||
* already there.)
|
||||
*/
|
||||
@Test
|
||||
public void testCastFromHandMovedToExile() {
|
||||
|
|
@ -55,11 +52,9 @@ public class ProliferateTest extends CardTestPlayerBase{
|
|||
|
||||
addCard(Zone.HAND, playerA, "Volt Charge");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volt Charge", playerB);
|
||||
addTarget(playerA, "Chandra, Pyromaster");
|
||||
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
|
@ -69,19 +64,22 @@ public class ProliferateTest extends CardTestPlayerBase{
|
|||
assertCounterCount("Chandra, Pyromaster", CounterType.LOYALTY, 5); // 4 + 1 from proliferate
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Counters aren't cancelling each other out. Reproducible with any creature (graft and bloodthirst in my case)
|
||||
* with a single +1/+1 counter on it, with a single -1/-1 placed on it (Grim Affliction, Instill Infection, etc).
|
||||
* The counters should cancel each other out, leaving neither on the creature, which they don't (though visually
|
||||
* there aren't any counters sitting on the card). Triggering proliferate at any point now (Thrumming Bird,
|
||||
* Steady Progress, etc) will give you the option to add another of either counter, where you shouldn't have any as an option.
|
||||
* Counters aren't cancelling each other out. Reproducible with any creature
|
||||
* (graft and bloodthirst in my case) with a single +1/+1 counter on it,
|
||||
* with a single -1/-1 placed on it (Grim Affliction, Instill Infection,
|
||||
* etc). The counters should cancel each other out, leaving neither on the
|
||||
* creature, which they don't (though visually there aren't any counters
|
||||
* sitting on the card). Triggering proliferate at any point now (Thrumming
|
||||
* Bird, Steady Progress, etc) will give you the option to add another of
|
||||
* either counter, where you shouldn't have any as an option.
|
||||
*/
|
||||
@Test
|
||||
public void testValidTargets() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
// Put a +1/+1 counter on target creature.
|
||||
addCard(Zone.HAND, playerA, "Battlegrowth"); // {G}
|
||||
// Proliferate. (You choose any number of permanents and/or players with counters on them, then give each another counter of a kind already there.)
|
||||
|
|
@ -90,27 +88,27 @@ public class ProliferateTest extends CardTestPlayerBase{
|
|||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Sporeback Troll"); // has two +1/+1 counter
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 3);
|
||||
// Put a -1/-1 counter on target creature, then proliferate.
|
||||
// Put a -1/-1 counter on target creature, then proliferate.
|
||||
addCard(Zone.HAND, playerB, "Grim Affliction"); // {B}{2}
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Battlegrowth", "Silvercoat Lion");
|
||||
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Grim Affliction", "Silvercoat Lion");
|
||||
// proliferate Sporeback Troll
|
||||
|
||||
|
||||
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Steady Progress");
|
||||
// Silvercoat Lion may not be a valid target now
|
||||
|
||||
|
||||
setStopAt(2, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
|
||||
assertGraveyardCount(playerA, "Battlegrowth", 1);
|
||||
assertGraveyardCount(playerA, "Steady Progress", 1);
|
||||
assertGraveyardCount(playerB, "Grim Affliction", 1);
|
||||
|
||||
assertCounterCount("Silvercoat Lion", CounterType.P1P1, 0); // no valid target because no counter
|
||||
assertCounterCount("Sporeback Troll", CounterType.P1P1, 3); // 2 + 1 from proliferate
|
||||
assertPowerToughness(playerB, "Sporeback Troll", 3, 3);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ public class UndyingTest extends CardTestPlayerBase {
|
|||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Elite Vanguard", 1);
|
||||
assertCounterCount(playerA, "Elite Vanguard", CounterType.P1P1, 1);
|
||||
assertPowerToughness(playerA, "Elite Vanguard", 3, 2);
|
||||
}
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ public class UndyingTest extends CardTestPlayerBase {
|
|||
assertGraveyardCount(playerA, "Lightning Bolt", 1);
|
||||
assertPermanentCount(playerB, "Strangleroot Geist", 0);
|
||||
assertPermanentCount(playerA, "Strangleroot Geist", 1);
|
||||
assertCounterCount(playerA, "Strangleroot Geist", CounterType.P1P1, 1);
|
||||
assertPowerToughness(playerA, "Strangleroot Geist", 3, 2);
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +213,7 @@ public class UndyingTest extends CardTestPlayerBase {
|
|||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
assertPermanentCount(playerA, "Mikaeus, the Unhallowed", 1);
|
||||
assertCounterCount(playerA, "Silvercoat Lion", CounterType.P1P1, 1);
|
||||
assertPowerToughness(playerA, "Silvercoat Lion", 4, 4);
|
||||
|
||||
}
|
||||
|
|
@ -272,4 +275,45 @@ public class UndyingTest extends CardTestPlayerBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* I stole my opponents Vorapede using Simic Manipulator and shortly after
|
||||
* someone played Wrath of God. Instead of returning to my opponent's board,
|
||||
* Vorapede came back under my control. The rules text for Undying states
|
||||
* that it should return under its owner's control, not its controller's.
|
||||
*/
|
||||
@Test
|
||||
public void testUndyingCreatureReturnsUnderOwnersControl() {
|
||||
|
||||
// Creature — Insect
|
||||
// Vigilance, trample
|
||||
// Undying (When this creature dies, if it had no +1/+1 counters on it, return it to the battlefield under its owner's control with a +1/+1 counter on it.)
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Vorapede"); // {2}{G}{G}{G} 5/4
|
||||
addCard(Zone.HAND, playerB, "Doom Blade"); // {1}{B} destroy target non-black creature
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
|
||||
|
||||
// {2}{R} sorcery - Gain control of target creature until end of turn. Untap that creature. It gains haste until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Act of Treason");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
|
||||
|
||||
// playerA takes control of Vorapede from playerB
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Act of Treason", "Vorapede");
|
||||
attack(1, playerA, "Vorapede");
|
||||
// playerB kills Vorapede under the control of playerA now
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Doom Blade", "Vorapede");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 15);
|
||||
assertGraveyardCount(playerA, "Act of Treason", 1);
|
||||
assertGraveyardCount(playerB, "Doom Blade", 1);
|
||||
|
||||
// Vorapede should return under control of playerA, not playerB
|
||||
assertPermanentCount(playerB, "Vorapede", 1);
|
||||
assertPermanentCount(playerA, "Vorapede", 0);
|
||||
assertCounterCount(playerB, "Vorapede", CounterType.P1P1, 1);
|
||||
assertPowerToughness(playerB, "Vorapede", 6, 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,4 +106,37 @@ public class MovingCounterTest extends CardTestPlayerBase {
|
|||
assertPowerToughness(playerA, "Ruin Processor", 3, 4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The card Leech Bonder (or the token mechanic) doesn't seem to work quite
|
||||
* as intended. If moving a -1/-1 counter from the Leech Bonder onto an
|
||||
* enemy creature with 1/1 the creature stays as a 1/1 with the token being
|
||||
* displayed on it. Going by the rules the creature should have 0/0 and thus
|
||||
* be put into the graveyard.
|
||||
*/
|
||||
@Test
|
||||
public void testLeechBonder() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
|
||||
// Leech Bonder enters the battlefield with two -1/-1 counters on it.
|
||||
// {U}, {untap}: Move a counter from target creature onto another target creature.
|
||||
addCard(Zone.HAND, playerA, "Leech Bonder", 1);// Creature 3/3 - {2}{U}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ley Druid", 1); // 1/1
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Leech Bonder");
|
||||
|
||||
attack(3, playerA, "Leech Bonder");
|
||||
|
||||
activateAbility(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "{U},", "Leech Bonder");
|
||||
addTarget(playerA, "Ley Druid");
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 19);
|
||||
|
||||
assertGraveyardCount(playerB, "Ley Druid", 1);
|
||||
assertPowerToughness(playerA, "Leech Bonder", 2, 2);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ import mage.abilities.keyword.IndestructibleAbility;
|
|||
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;
|
||||
|
||||
|
|
@ -115,4 +117,47 @@ public class GideonTest extends CardTestPlayerBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* When you use Gideon, Battle-Forged (flipped version of Kytheon from Magic
|
||||
* Origins) and use his 0 ability to turn him into a creature and equip the
|
||||
* Stitcher's Graft from EMN, he should have to be sacced at the end of
|
||||
* turn.
|
||||
*/
|
||||
@Test
|
||||
public void testGideonBattleForgedSacrifice() {
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
|
||||
// At end of combat, if Kytheon, Hero of Akros and at least two other creatures attacked this combat, exile Kytheon,
|
||||
// then return him to the battlefield transformed under his owner's control.
|
||||
// {2}{W}: Kytheon gains indestructible until end of turn.
|
||||
// Gideon, Battle-Forged
|
||||
// +2: Up to one target creature an opponent controls attacks Gideon, Battle-Forged during its controller's next turn if able.
|
||||
// +1: Until your next turn, target creature gains indestructible. Untap that creature.
|
||||
// +0: Until end of turn, Gideon, Battle-Forged becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Kytheon, Hero of Akros");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
|
||||
// Equipped creature gets +3/+3.
|
||||
// Whenever equipped creature attacks, it doesn't untap during its controller's next untap step.
|
||||
// Whenever Stitcher's Graft becomes unattached from a permanent, sacrifice that permanent.
|
||||
// Equip {2}
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Stitcher's Graft", 1);
|
||||
|
||||
attack(2, playerB, "Kytheon, Hero of Akros");
|
||||
attack(2, playerB, "Silvercoat Lion");
|
||||
attack(2, playerB, "Pillarfield Ox");
|
||||
|
||||
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerB, "+0: Until ");
|
||||
activateAbility(4, PhaseStep.PRECOMBAT_MAIN, playerB, "Equip {2}", "Gideon, Battle-Forged");
|
||||
attack(4, playerB, "Gideon, Battle-Forged"); // 7 damage
|
||||
|
||||
setStopAt(5, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerB, "Silvercoat Lion", 1);
|
||||
assertLife(playerA, 7);
|
||||
Permanent equipment = getPermanent("Stitcher's Graft", playerB);
|
||||
Assert.assertTrue("Stitcher's Graft may no longer be equipped", equipment.getAttachedTo() == null);
|
||||
assertPermanentCount(playerB, "Gideon, Battle-Forged", 0);
|
||||
assertGraveyardCount(playerB, "Kytheon, Hero of Akros", 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package org.mage.test.cards.replacement;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
|
||||
*/
|
||||
public class ClergyOfTheHolyNimbusTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testBasicRegeneration() {
|
||||
|
||||
// If Clergy of the Holy Nimbus would be destroyed, regenerate it.
|
||||
// {1}: Clergy of the Holy Nimbus can't be regenerated this turn. Only any opponent may activate this ability.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Clergy of the Holy Nimbus"); // {W} 1/1
|
||||
addCard(Zone.HAND, playerA, "Doom Blade"); // {1}{B} destroy target non-black creature
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Doom Blade", "Clergy of the Holy Nimbus");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Doom Blade", 1);
|
||||
assertPermanentCount(playerB, "Clergy of the Holy Nimbus", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCannotBeRegeneratedSpell() {
|
||||
|
||||
// If Clergy of the Holy Nimbus would be destroyed, regenerate it.
|
||||
// {1}: Clergy of the Holy Nimbus can't be regenerated this turn. Only any opponent may activate this ability.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Clergy of the Holy Nimbus"); // {W} 1/1
|
||||
addCard(Zone.HAND, playerA, "Wrath of God"); // {2}{W}{W} destroy all creatures, they cannot be regenerated
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wrath of God");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Wrath of God", 1);
|
||||
assertGraveyardCount(playerB, "Clergy of the Holy Nimbus", 1);
|
||||
}
|
||||
|
||||
// in game testing works correctly - not sure if the ability is being activated or not here.
|
||||
@Ignore
|
||||
@Test
|
||||
public void testOpponentPaysOneToNotAllowRegeneration() {
|
||||
|
||||
// If Clergy of the Holy Nimbus would be destroyed, regenerate it.
|
||||
// {1}: Clergy of the Holy Nimbus can't be regenerated this turn. Only any opponent may activate this ability.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Clergy of the Holy Nimbus"); // {W} 1/1
|
||||
addCard(Zone.HAND, playerA, "Doom Blade"); // {1}{B} destroy target non-black creature
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}:");
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Doom Blade", "Clergy of the Holy Nimbus");
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Doom Blade", 1);
|
||||
assertGraveyardCount(playerB, "Clergy of the Holy Nimbus", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,11 @@ public class AltarOfTheLostTest extends CardTestPlayerBase {
|
|||
|
||||
@Test
|
||||
public void testCard() {
|
||||
// Altar of the Lost enters the battlefield tapped.
|
||||
// {tap}: Add two mana in any combination of colors to your mana pool. Spend this mana only to cast spells with flashback from a graveyard.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Altar of the Lost");
|
||||
// Put two 1/1 white Spirit creature tokens with flying onto the battlefield.
|
||||
// Flashback {1}{B}
|
||||
addCard(Zone.GRAVEYARD, playerA, "Lingering Souls");
|
||||
|
||||
setChoice(playerA, "Black");
|
||||
|
|
|
|||
|
|
@ -381,7 +381,9 @@ public class TestPlayer implements Player {
|
|||
@Override
|
||||
public boolean priority(Game game) {
|
||||
int numberOfActions = actions.size();
|
||||
for (PlayerAction action : actions) {
|
||||
List<PlayerAction> tempActions = new ArrayList<>();
|
||||
tempActions.addAll(actions);
|
||||
for (PlayerAction action : tempActions) {
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getStep() == game.getStep().getType()) {
|
||||
|
||||
if (action.getAction().startsWith("activate:")) {
|
||||
|
|
@ -478,7 +480,7 @@ public class TestPlayer implements Player {
|
|||
int turns = Integer.parseUnsignedInt(groups[1].substring(6));
|
||||
game.rollbackTurns(turns);
|
||||
actions.remove(action);
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue