move zoneChangeCounter to GameState - Card is now immutable

This commit is contained in:
betasteward 2015-03-29 08:30:31 -04:00
parent 45aa5f675c
commit 6405c8d2f0
101 changed files with 899 additions and 257 deletions

View file

@ -0,0 +1,173 @@
/*
* 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.keywords;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class KickerTest extends CardTestPlayerBase {
/**
* 702.32. Kicker
* 702.32a Kicker is a static ability that functions while the spell with kicker is on the stack. Kicker
* [cost] means You may pay an additional [cost] as you cast this spell. Paying a spells kicker
* cost(s) follows the rules for paying additional costs in rules 601.2b and 601.2eg.
* 702.32b The phrase Kicker [cost 1] and/or [cost 2] means the same thing as Kicker [cost 1],
* kicker [cost 2].
* 702.32c Multikicker is a variant of the kicker ability. Multikicker [cost] means You may pay an
* additional [cost] any number of times as you cast this spell. A multikicker cost is a kicker cost.
* 702.32d If a spells controller declares the intention to pay any of that spells kicker costs, that spell
* has been kicked. If a spell has two kicker costs or has multikicker, it may be kicked multiple
* times. See rule 601.2b.
* 702.32e Objects with kicker or multikicker have additional abilities that specify what happens if
* they are kicked. These abilities are linked to the kicker or multikicker abilities printed on that
* object: they can refer only to those specific kicker or multikicker abilities. See rule 607, Linked
* Abilities.
* 702.32f Objects with more than one kicker cost have abilities that each correspond to a specific
* kicker cost. They contain the phrases if it was kicked with its [A] kicker and if it was kicked
* with its [B] kicker, where A and B are the first and second kicker costs listed on the card,
* respectively. Each of those abilities is linked to the appropriate kicker ability.
* 702.32g If part of a spells ability has its effect only if that spell was kicked, and that part of the
* ability includes any targets, the spells controller chooses those targets only if that spell was
* kicked. Otherwise, the spell is cast as if it did not have those targets. See rule 601.2c.
*
*/
/**
* AEther Figment
* Creature Illusion 1/1, 1U (2)
* Kicker {3} (You may pay an additional {3} as you cast this spell.)
* AEther Figment can't be blocked.
* If AEther Figment was kicked, it enters the battlefield with two +1/+1 counters on it.
*
*/
@Test
public void testUseKicker() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.HAND, playerA, "AEther Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "AEther Figment");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "AEther Figment", 1);
assertCounterCount("AEther Figment", CounterType.P1P1, 2);
assertPowerToughness(playerA, "AEther Figment", 3, 3);
}
@Test
public void testDontUseKicker() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.HAND, playerA, "AEther Figment");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "AEther Figment");
setChoice(playerA, "No");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "AEther Figment", 1);
assertCounterCount("AEther Figment", CounterType.P1P1, 0);
assertPowerToughness(playerA, "AEther Figment", 1, 1);
}
/**
* Apex Hawks
* Creature Bird 2/2, 2W (3)
* Multikicker {1}{W} (You may pay an additional {1}{W} any number of times as you cast this spell.)
* Flying
* Apex Hawks enters the battlefield with a +1/+1 counter on it for each time it was kicked.
*
*/
@Test
public void testUseMultikickerOnce() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerA, "Apex Hawks");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Apex Hawks");
setChoice(playerA, "Yes");
setChoice(playerA, "No");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Apex Hawks", 1);
assertCounterCount("Apex Hawks", CounterType.P1P1, 1);
assertPowerToughness(playerA, "Apex Hawks", 3, 3);
}
@Test
public void testUseMultikickerTwice() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.HAND, playerA, "Apex Hawks");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Apex Hawks");
setChoice(playerA, "Yes");
setChoice(playerA, "Yes");
setChoice(playerA, "No");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Apex Hawks", 1);
assertCounterCount("Apex Hawks", CounterType.P1P1, 2);
assertPowerToughness(playerA, "Apex Hawks", 4, 4);
}
@Test
public void testDontUseMultikicker() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.HAND, playerA, "Apex Hawks");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Apex Hawks");
setChoice(playerA, "No");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Apex Hawks", 1);
assertCounterCount("Apex Hawks", CounterType.P1P1, 0);
assertPowerToughness(playerA, "Apex Hawks", 2, 2);
}
}

View file

@ -0,0 +1,140 @@
/*
* 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.keywords;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class StormTest extends CardTestPlayerBase {
/**
* 702.39. Storm
* 702.39a Storm is a triggered ability that functions on the stack. Storm means When you cast this
* spell, put a copy of it onto the stack for each other spell that was cast before it this turn. If the
* spell has any targets, you may choose new targets for any of the copies.
* 702.39b If a spell has multiple instances of storm, each triggers separately.
*
*/
/**
* Grapeshot
* Sorcery, 1R (2)
* Grapeshot deals 1 damage to target creature or player.
* Storm (When you cast this spell, copy it for each spell cast before it
* this turn. You may choose new targets for the copies.)
*
*/
@Test
public void testStorm1x() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Zone.HAND, playerA, "Grapeshot");
addCard(Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 15);
}
@Test
public void testStorm2x() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
addCard(Zone.HAND, playerA, "Grapeshot");
addCard(Zone.HAND, playerA, "Lightning Bolt", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 11);
}
@Test
public void testStorm3x() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.HAND, playerA, "Grapeshot");
addCard(Zone.HAND, playerA, "Lightning Bolt", 3);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 7);
}
@Test
public void testStorm4x() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
addCard(Zone.HAND, playerA, "Grapeshot");
addCard(Zone.HAND, playerA, "Lightning Bolt", 4);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 3);
}
@Test
public void testNoStorm() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.HAND, playerA, "Grapeshot");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Grapeshot", playerB);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertLife(playerB, 19);
}
}

View file

@ -0,0 +1,131 @@
/*
* 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.continuous;
import mage.constants.CardType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class MarchOfTheMachinesTest extends CardTestPlayerBase {
/**
* March of the Machines
* Enchantment, 3U (4)
* Each noncreature artifact is an artifact creature with power and toughness
* each equal to its converted mana cost. (Equipment that's a creature can't
* equip a creature.)
*
*/
/**
* Abzan Banner
* Artifact, 3 (3)
* {T}: Add {W}, {B}, or {G} to your mana pool.
* {W}{B}{G}, {T}, Sacrifice Abzan Banner: Draw a card.
*/
@Test
public void testNonCreatureArtifactsBecomeCreatures() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
addCard(Zone.BATTLEFIELD, playerA, "Abzan Banner");
addCard(Zone.BATTLEFIELD, playerA, "Alloy Myr");
addCard(Zone.HAND, playerA, "March of the Machines");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "March of the Machines");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Alloy Myr", 2, 2);
assertPermanentCount(playerA, "Abzan Banner", 1);
assertPowerToughness(playerA, "Abzan Banner", 3, 3);
assertType("Abzan Banner", CardType.CREATURE, true);
}
@Test
public void testArtifactsRevertBack() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
addCard(Zone.BATTLEFIELD, playerA, "Abzan Banner");
addCard(Zone.HAND, playerA, "March of the Machines");
addCard(Zone.HAND, playerB, "Disenchant");
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "March of the Machines");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Disenchant", "March of the Machines");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Abzan Banner", 1);
assertType("Abzan Banner", CardType.CREATURE, false);
}
@Test
public void testEquipmentDetaches() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
addCard(Zone.BATTLEFIELD, playerA, "Avacyn's Collar");
addCard(Zone.BATTLEFIELD, playerA, "Ornithopter");
addCard(Zone.HAND, playerA, "March of the Machines");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Ornithopter");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "March of the Machines");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Ornithopter", 1);
assertPowerToughness(playerA, "Ornithopter", 0, 2);
assertPermanentCount(playerA, "Avacyn's Collar", 1);
assertPowerToughness(playerA, "Avacyn's Collar", 1, 1);
assertType("Avacyn's Collar", CardType.CREATURE, true);
}
@Test
public void testZeroCostIsDestroyed() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 4);
addCard(Zone.BATTLEFIELD, playerA, "Accorder's Shield");
addCard(Zone.HAND, playerA, "March of the Machines");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "March of the Machines");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Accorder's Shield", 0);
assertGraveyardCount(playerA, "Accorder's Shield", 1);
}
}

View file

@ -0,0 +1,122 @@
/*
* 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.dynamicvalue;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class SweepTest extends CardTestPlayerBase {
/**
* Plow Through Reito
* 1W
* Instant -- Arcane
* Sweep -- Return any number of Plains you control to their owner's hand.
* Target creature gets +1/+1 until end of turn for each Plains returned this way.
*
*/
@Test
public void testSweep1x() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
addCard(Zone.HAND, playerA, "Plow Through Reito");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plow Through Reito");
addTarget(playerA, "Plains");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Raging Goblin", 1);
assertPermanentCount(playerA, "Plains", 4);
assertPowerToughness(playerA, "Raging Goblin", 2, 2);
}
@Test
public void testSweep2x() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
addCard(Zone.HAND, playerA, "Plow Through Reito");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plow Through Reito");
addTarget(playerA, "Plains^Plains");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Raging Goblin", 1);
assertPermanentCount(playerA, "Plains", 3);
assertPowerToughness(playerA, "Raging Goblin", 3, 3);
}
@Test
public void testSweep3x() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
addCard(Zone.HAND, playerA, "Plow Through Reito");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plow Through Reito");
addTarget(playerA, "Plains^Plains^Plains");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Raging Goblin", 1);
assertPermanentCount(playerA, "Plains", 2);
assertPowerToughness(playerA, "Raging Goblin", 4, 4);
}
@Test
public void testSweep0x() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.BATTLEFIELD, playerA, "Raging Goblin");
addCard(Zone.HAND, playerA, "Plow Through Reito");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plow Through Reito");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Raging Goblin", 1);
assertPermanentCount(playerA, "Plains", 5);
assertPowerToughness(playerA, "Raging Goblin", 1, 1);
}
}

View file

@ -11,6 +11,28 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*/
public class HuntmasterOfTheFellsTest extends CardTestPlayerBase {
/**
* Huntmaster of the Fells
* Creature Human Werewolf 2/2, 2RG (4)
* Whenever this creature enters the battlefield or transforms into Huntmaster
* of the Fells, put a 2/2 green Wolf creature token onto the battlefield and
* you gain 2 life.
* At the beginning of each upkeep, if no spells were cast last turn, transform
* Huntmaster of the Fells.
*
*/
/**
* Ravager of the Fells
* Creature Werewolf 4/4
* Trample
* Whenever this creature transforms into Ravager of the Fells, it deals 2
* damage to target opponent and 2 damage to up to one target creature that
* player controls.
* At the beginning of each upkeep, if a player cast two or more spells last
* turn, transform Ravager of the Fells.
*/
@Test
public void testCard() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);

View file

@ -31,6 +31,7 @@ import java.io.FilenameFilter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.mage.test.serverside.base.MageTestPlayerBase.currentGame;
/**
* Base class for all tests.
@ -259,7 +260,7 @@ public abstract class MageTestBase {
Card card = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) {
if (gameZone.equals(Zone.BATTLEFIELD)) {
PermanentCard p = new PermanentCard(card, null);
PermanentCard p = new PermanentCard(card, null, currentGame);
p.setTapped(tapped);
perms.add(p);
} else {

View file

@ -239,7 +239,7 @@ public abstract class MageTestPlayerBase {
Card card = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) {
if (gameZone.equals(Zone.BATTLEFIELD)) {
PermanentCard p = new PermanentCard(card, null);
PermanentCard p = new PermanentCard(card, null, currentGame);
p.setTapped(tapped);
perms.add(p);
} else {

View file

@ -124,7 +124,7 @@ public abstract class CardTestAPIImpl extends MageTestBase implements CardTestAP
if (card == null) {
throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
}
PermanentCard p = new PermanentCard(card, null);
PermanentCard p = new PermanentCard(card, null, currentGame);
p.setTapped(tapped);
if (player.equals(playerA)) {
battlefieldCardsA.add(p);

View file

@ -37,6 +37,7 @@ import java.util.UUID;
public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implements CardTestAPI {
static {
// CardScanner.scanned = true;
CardScanner.scan();
}
@ -168,7 +169,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
if (card == null) {
throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
}
PermanentCard p = new PermanentCard(card, null);
PermanentCard p = new PermanentCard(card, null, currentGame);
p.setTapped(tapped);
getBattlefieldCards(player).add(p);
}
@ -511,6 +512,28 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param flag true if creature should have type, false if it should not
*/
public void assertType(String cardName, CardType type, boolean flag) throws AssertionError {
Permanent found = null;
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) {
if (permanent.getName().equals(cardName)) {
found = permanent;
break;
}
}
Assert.assertNotNull("There is no such permanent on the battlefield, cardName=" + cardName, found);
Assert.assertTrue("(Battlefield) card type not found (" + cardName + ":" + type + ")", (found.getCardType().contains(type) == flag));
}
/**
* Assert whether a permanent is a specified type
*
* @param cardName Name of the permanent that should be checked.
* @param type A type to test for
* @param subType a subtype to test for
*/
public void assertType(String cardName, CardType type, String subType) throws AssertionError {