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
09dd373909
239 changed files with 8772 additions and 583 deletions
|
|
@ -111,5 +111,40 @@ public class LandfallTest extends CardTestPlayerBase {
|
|||
assertLife(playerB, 20);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Searing Blaze's landfall doesn't appear to be working. My opponent played
|
||||
* a mountain, then played searing blaze targeting my Tasigur, the Golden
|
||||
* Fang. It only dealt 1 damage to me, where it should've dealt 3, because
|
||||
* my opponent had played a land.
|
||||
*/
|
||||
@Test
|
||||
public void testSearingBlaze() {
|
||||
// Searing Blaze deals 1 damage to target player and 1 damage to target creature that player controls.
|
||||
// Landfall - If you had a land enter the battlefield under your control this turn, Searing Blaze deals 3 damage to that player and 3 damage to that creature instead.
|
||||
addCard(Zone.HAND, playerA, "Searing Blaze",1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain",1);
|
||||
addCard(Zone.HAND, playerA, "Mountain");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion",1);
|
||||
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Searing Blaze");
|
||||
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Mountain", 2);
|
||||
assertGraveyardCount(playerA, "Searing Blaze" , 1);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 17);
|
||||
|
||||
assertGraveyardCount(playerB, "Silvercoat Lion" , 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* 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.oneshot.counterspell;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class CounterspellTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
It looks like Boom//Bust can't be countered (although it says it's countered in the log).
|
||||
|
||||
Code: Select all
|
||||
13:10: Benno casts Boom [8ce] targeting Mountain [4c8] Island [80c]
|
||||
13:10: Benno casts Counterspell [2b7] targeting Boom [8ce]
|
||||
13:10: Benno puts Boom [8ce] from stack into his or her graveyard
|
||||
13:10: Boom is countered by Counterspell [2b7]
|
||||
13:10: Benno puts Counterspell [2b7] from stack into his or her graveyard
|
||||
13:10: Mountain [4c8] was destroyed
|
||||
13:10: Island [80c] was destroyed
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testCounterSplitSpell() {
|
||||
// Boom - Sorcery {1}{R}
|
||||
// Destroy target land you control and target land you don't control.
|
||||
addCard(Zone.HAND, playerA, "Boom // Bust");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
|
||||
addCard(Zone.HAND, playerB, "Counterspell");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Boom", "Mountain^Island");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Boom");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Boom // Bust", 1);
|
||||
assertGraveyardCount(playerB, "Counterspell", 1);
|
||||
|
||||
assertPermanentCount(playerA, "Mountain", 2);
|
||||
assertPermanentCount(playerB, "Island", 2);
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.copy;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PhyrexianMetamorphTest extends CardTestPlayerBase {
|
||||
|
||||
|
||||
@Test
|
||||
public void testCopyCreature() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
|
||||
addCard(Zone.HAND, playerA, "Cloudshift");
|
||||
|
||||
//Flying
|
||||
// Vanishing 3 (This permanent enters the battlefield with three time counters on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it.)
|
||||
// When Aven Riftwatcher enters the battlefield or leaves the battlefield, you gain 2 life.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Aven Riftwatcher"); // 2/3
|
||||
|
||||
// When Ponyback Brigade enters the battlefield or is turned face up, put three 1/1 red Goblin creature tokens onto the battlefield.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ponyback Brigade"); // 2/2
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph");
|
||||
setChoice(playerA, "Aven Riftwatcher");
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cloudshift", "Aven Riftwatcher");
|
||||
setChoice(playerA, "Ponyback Brigade");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertGraveyardCount(playerA, "Cloudshift", 1);
|
||||
|
||||
assertPermanentCount(playerA, "Ponyback Brigade", 1);
|
||||
assertPermanentCount(playerA, "Goblin", 3);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testFlickerWithBrago() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
|
||||
|
||||
// You may have Phyrexian Metamorph enter the battlefield as a copy of any artifact or creature on the battlefield, except it's an artifact in addition to its other types.
|
||||
addCard(Zone.HAND, playerA, "Phyrexian Metamorph"); // {3}{UP}
|
||||
|
||||
// Flying
|
||||
// When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Brago, King Eternal"); // 2/4
|
||||
|
||||
// Creatures you control have haste.
|
||||
// Cascade, cascade
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Maelstrom Wanderer"); // 7/5
|
||||
// When Ponyback Brigade enters the battlefield or is turned face up, put three 1/1 red Goblin creature tokens onto the battlefield.
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Ponyback Brigade"); // 2/2
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phyrexian Metamorph");
|
||||
setChoice(playerA, "Maelstrom Wanderer");
|
||||
|
||||
attack(3, playerA, "Brago, King Eternal");
|
||||
addTarget(playerA, "Maelstrom Wanderer");
|
||||
setChoice(playerA, "Ponyback Brigade");
|
||||
|
||||
setStopAt(3, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 18);
|
||||
|
||||
assertPermanentCount(playerA, "Ponyback Brigade", 1);
|
||||
assertPermanentCount(playerA, "Goblin", 3);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.copy;
|
||||
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
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 LevelX2
|
||||
*/
|
||||
public class TheMimeoplasmTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* I cast either Phyrexian Metamorph or Phantasmal Image and copied The
|
||||
* Mimeoplasm which was copying a Primeval Titan, but my clone became
|
||||
* another Mimeoplasm, so it exiled two creatures from graveyards and cloned
|
||||
* one of those instead.
|
||||
*
|
||||
* Copying cards that are copy of other cards copies the original, rather
|
||||
* than the copy.
|
||||
* To wit, when The Mimeoplasm is out (and lets say is a copy of Elvish
|
||||
* Mystic), and someone then plays Clone choosing to enter as the cloned
|
||||
* Elvish Mystic, they are incorrectly getting The Mimeoplasm instead.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testCloneMimeoplasm() {
|
||||
// As The Mimeoplasm enters the battlefield, you may exile two creature cards from graveyards.
|
||||
// If you do, it enters the battlefield as a copy of one of those cards with a number of additional +1/+1 counters on it equal to the power of the other card.
|
||||
addCard(Zone.HAND, playerA, "The Mimeoplasm", 1); // {2}{G}{U}{B}
|
||||
|
||||
addCard(Zone.HAND, playerA, "Clone", 1); // {3}{U}
|
||||
|
||||
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion", 1); // 2/2
|
||||
addCard(Zone.GRAVEYARD, playerB, "Aven Riftwatcher", 1); // 2/3
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 7);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
|
||||
|
||||
|
||||
castSpell(1,PhaseStep.PRECOMBAT_MAIN, playerA, "The Mimeoplasm");
|
||||
setChoice(playerA, "Aven Riftwatcher");
|
||||
setChoice(playerA, "Silvercoat Lion");
|
||||
|
||||
castSpell(1,PhaseStep.PRECOMBAT_MAIN, playerA, "Clone");
|
||||
setChoice(playerA, "Aven Riftwatcher");
|
||||
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, "Clone", 0);
|
||||
|
||||
assertLife(playerA, 24);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
assertPermanentCount(playerA, "Aven Riftwatcher", 2);
|
||||
assertPowerToughness(playerA, "Aven Riftwatcher", 4, 5);
|
||||
assertPowerToughness(playerA, "Aven Riftwatcher", 2, 3);
|
||||
|
||||
assertGraveyardCount(playerB, 0);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class SoulFoundryTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Soul Foundry imprinted with Bloodline Keeper costs 8 colorless mana to
|
||||
* use the ability instead of 4 (the converted mana cost of Bloodline
|
||||
* Keeper).
|
||||
*/
|
||||
@Test
|
||||
public void testBloodlineKeeper() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
|
||||
// Imprint - When Soul Foundry enters the battlefield, you may exile a creature card from your hand.
|
||||
// {X}, {T}: Put a token that's a copy of the exiled card onto the battlefield. X is the converted mana cost of that card.
|
||||
addCard(Zone.HAND, playerA, "Soul Foundry"); // {4}
|
||||
addCard(Zone.HAND, playerA, "Bloodline Keeper");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Foundry");
|
||||
setChoice(playerA, "Yes");
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},{T}: Put a token");
|
||||
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Soul Foundry", 1);
|
||||
|
||||
assertExileCount("Bloodline Keeper", 1);
|
||||
assertPermanentCount(playerA, "Bloodline Keeper", 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.cards.triggers;
|
||||
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class PossibilityStormTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* There's currently a bug with Possibility Storm and Zoetic Cavern. The way
|
||||
* it's supposed to work is the P. Storm trigger exiles Zoetic Cavern and
|
||||
* then uses last known information about the spell to determine the type of
|
||||
* card the trigger is looking for(creature in this instance). Instead it's
|
||||
* basing the type solely off what's printed on the card. What happened to
|
||||
* me earlier was the trigger skipped right over an Emrakul and then
|
||||
* revealed a Flooded Strand. I was prompted whether or not I wanted to
|
||||
* "cast" Flooded Strand without paying it's cost. Eventually I clicked yes
|
||||
* and it produced a Game Error that resulted in rollback. I recreated the
|
||||
* error against an AI opponent and copied the code. Can't actually post it
|
||||
* because the filter on this site claims it makes my post look too
|
||||
* "spammy". Here's a screenshot of it instead(in spoiler tag).
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void TestWithZoeticCavern() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
|
||||
// Whenever a player casts a spell from his or her hand, that player exiles it, then exiles cards from
|
||||
// the top of his or her 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
|
||||
// Possibility Storm on the bottom of his or her library in a random order.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Possibility Storm", 2);
|
||||
|
||||
// {T}: Add {1} to your mana pool.
|
||||
// Morph {2}
|
||||
addCard(Zone.HAND, playerA, "Zoetic Cavern");
|
||||
|
||||
addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
|
||||
skipInitShuffling();
|
||||
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Zoetic Cavern");
|
||||
setChoice(playerA, "Yes");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Zoetic Cavern", 0);
|
||||
|
||||
boolean zoeticCavernInLibrary = false;
|
||||
for (Card card: playerA.getLibrary().getCards(currentGame)) {
|
||||
if (card.getName().equals("Zoetic Cavern")) {
|
||||
zoeticCavernInLibrary = true;
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("Zoetic Cavern has to be in the library", true, zoeticCavernInLibrary);
|
||||
|
||||
assertPermanentCount(playerA, "Silvercoat Lion", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
|||
*/
|
||||
public class CastCommanderTest extends CardTestCommanderDuelBase {
|
||||
@Test
|
||||
public void testFirstAbility() {
|
||||
public void testCastCommander() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ob Nixilis of the Black Oath");
|
||||
|
|
@ -50,5 +50,5 @@ public class CastCommanderTest extends CardTestCommanderDuelBase {
|
|||
assertLife(playerB, 40);
|
||||
|
||||
assertPermanentCount(playerA, "Ob Nixilis of the Black Oath", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package org.mage.test.commander.duel;
|
||||
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class TeferiMageOfZhalfirTest extends CardTestCommanderDuelBase {
|
||||
|
||||
@Override
|
||||
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
|
||||
setDecknamePlayerA("CommanderDuel_UW.dck"); // Commander = Daxos of Meletis
|
||||
return super.createNewGameAndPlayers();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void castCommanderWithFlash() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Mage of Zhalfir");
|
||||
|
||||
castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, "Daxos of Meletis");
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Daxos of Meletis", 1);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommanderDamage() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 6);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
// Enchant creature
|
||||
// Enchanted creature gets +4/+4, has flying and first strike, and is an Angel in addition to its other types.
|
||||
// When enchanted creature dies, return Angelic Destiny to its owner's hand.
|
||||
addCard(Zone.HAND, playerA, "Angelic Destiny");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Teferi, Mage of Zhalfir");
|
||||
|
||||
// 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.PRECOMBAT_MAIN, playerA, "Angelic Destiny","Daxos of Meletis");
|
||||
|
||||
attack(3, playerA, "Daxos of Meletis");
|
||||
attack(5, playerA, "Daxos of Meletis");
|
||||
attack(7, playerA, "Daxos of Meletis");
|
||||
attack(9, playerA, "Daxos of Meletis");
|
||||
|
||||
setStopAt(9, PhaseStep.POSTCOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Daxos of Meletis", 1);
|
||||
assertPowerToughness(playerA, "Daxos of Meletis", 6, 6);
|
||||
|
||||
Assert.assertEquals("Player A has won because of commander damage", true, playerA.hasWon());
|
||||
Assert.assertEquals("Player A has lost because of commander damage", true, playerB.hasLost());
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ package org.mage.test.player;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -91,6 +92,7 @@ import mage.target.TargetPermanent;
|
|||
import mage.target.TargetPlayer;
|
||||
import mage.target.TargetSource;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCreaturePermanentAmount;
|
||||
|
|
@ -604,17 +606,53 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (target instanceof TargetCardInGraveyard) {
|
||||
TargetCardInGraveyard targetCardInGraveyard = ((TargetCardInGraveyard) target);
|
||||
Set<UUID> possibleTargets = new HashSet<>();
|
||||
for(UUID playerId: this.getInRange()) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
possibleTargets.addAll(player.getGraveyard());
|
||||
}
|
||||
}
|
||||
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (UUID targetId : possibleTargets) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
for (String targetName : targetList) {
|
||||
if (targetObject.getName().equals(targetName)) {
|
||||
List<UUID> alreadyTargetted = targetCardInGraveyard.getTargets();
|
||||
if (targetCardInGraveyard.canTarget(targetObject.getId(), game)) {
|
||||
if (alreadyTargetted != null && !alreadyTargetted.contains(targetObject.getId())) {
|
||||
targetCardInGraveyard.add(targetObject.getId(), game);
|
||||
choices.remove(choose2);
|
||||
targetFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (targetFound && targetCardInGraveyard.isChosen()) {
|
||||
choices.remove(choose2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target instanceof TargetSource) {
|
||||
Set<UUID> possibleTargets;
|
||||
TargetSource t = ((TargetSource) target);
|
||||
possibleTargets = t.possibleTargets(sourceId, computerPlayer.getId(), game);
|
||||
for (UUID targetId : possibleTargets) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
for (String choose2 : choices) {
|
||||
String[] targetList = choose2.split("\\^");
|
||||
boolean targetFound = false;
|
||||
for (String targetName : targetList) {
|
||||
for (UUID targetId : possibleTargets) {
|
||||
MageObject targetObject = game.getObject(targetId);
|
||||
if (targetObject != null) {
|
||||
if (targetObject.getName().equals(targetName)) {
|
||||
List<UUID> alreadyTargetted = target.getTargets();
|
||||
if (t.canTarget(targetObject.getId(), game)) {
|
||||
|
|
|
|||
|
|
@ -42,12 +42,18 @@ import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl;
|
|||
|
||||
public abstract class CardTestCommanderDuelBase extends CardTestPlayerAPIImpl {
|
||||
|
||||
public CardTestCommanderDuelBase() {
|
||||
super();
|
||||
this.deckNameA = "CommanderDuel.dck";
|
||||
this.deckNameB = "CommanderDuel.dck";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
|
||||
Game game = new CommanderDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, 0, 40);
|
||||
|
||||
playerA = createPlayer(game, playerA, "PlayerA","CommanderDuel.dck");
|
||||
playerB = createPlayer(game, playerB, "PlayerB","CommanderDuel.dck");
|
||||
playerA = createPlayer(game, playerA, "PlayerA",deckNameA);
|
||||
playerB = createPlayer(game, playerB, "PlayerB",deckNameB);
|
||||
return game;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,17 @@ import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl;
|
|||
*/
|
||||
public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl {
|
||||
|
||||
public CardTestPlayerBase() {
|
||||
deckNameA = "RB Aggro.dck";
|
||||
deckNameB = "RB Aggro.dck";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
|
||||
Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ONE, 0, 20);
|
||||
|
||||
playerA = createPlayer(game, playerA, "PlayerA");
|
||||
playerB = createPlayer(game, playerB, "PlayerB");
|
||||
playerA = createPlayer(game, playerA, "PlayerA", deckNameA);
|
||||
playerB = createPlayer(game, playerB, "PlayerB", deckNameB);
|
||||
return game;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
|
||||
protected GameOptions gameOptions;
|
||||
|
||||
protected String deckNameA;
|
||||
protected String deckNameB;
|
||||
|
||||
protected enum ExpectedType {
|
||||
TURN_NUMBER,
|
||||
RESULT,
|
||||
|
|
@ -1009,6 +1012,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
|
|||
player.addTarget("targetPlayer="+targetPlayer.getName());
|
||||
}
|
||||
|
||||
public void setDecknamePlayerA(String deckname) {
|
||||
deckNameA = deckname;
|
||||
}
|
||||
|
||||
public void setDecknamePlayerB(String deckname) {
|
||||
deckNameB = deckname;
|
||||
}
|
||||
|
||||
protected void skipInitShuffling() {
|
||||
gameOptions.skipInitShuffling = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue