Test framework - multiple improves:

* Added support of spell ability choice in free cast (chooseSpellAbilityForCast);
* Added support of "up to" targets setup in addTargetAmount (use TestPlayer.TARGET_SKIP to stop target choose);
* Restored multiple checks for addTargetAmount;
* Fixed many wrong tests (wrong order or missing commands);
This commit is contained in:
Oleg Agafonov 2020-01-12 01:17:39 +04:00
parent b0853fae8b
commit e1fea330dd
24 changed files with 435 additions and 327 deletions

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.abilities.activated;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class PutToGraveyardTest extends CardTestPlayerBase {
@ -32,7 +31,7 @@ public class PutToGraveyardTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Stasis Snare");
addTarget(playerA, "Silvercoat Lion");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G},", NO_TARGET, "");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{G},", TestPlayer.NO_TARGET, "");
addTarget(playerA, "Silvercoat Lion");
setStopAt(1, PhaseStep.BEGIN_COMBAT);

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.abilities.keywords;
import mage.abilities.keyword.HasteAbility;
@ -8,7 +7,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class MadnessTest extends CardTestPlayerBase {
@ -37,7 +35,6 @@ public class MadnessTest extends CardTestPlayerBase {
* Raven's Crime B Sorcery Target player discards a card. Retrace (You may
* cast this card from your graveyard by discarding a land card in addition
* to paying its other costs.)
*
*/
@Test
public void testMadness() {
@ -47,10 +44,13 @@ public class MadnessTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Raven's Crime");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerA);
setChoice(playerA, "Yes");
setChoice(playerA, "Yes"); // use madness triggered ability
setChoice(playerA, "Yes"); // use madness cast
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Arrogant Wurm", 1);
assertGraveyardCount(playerA, "Raven's Crime", 1);
@ -68,8 +68,10 @@ public class MadnessTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raven's Crime", playerA);
setChoice(playerA, "No");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Arrogant Wurm", 0);
assertGraveyardCount(playerA, "Raven's Crime", 1);
@ -93,10 +95,13 @@ public class MadnessTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Haunting Hymn");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA);
setChoice(playerA, "Yes");
setChoice(playerA, "Yes"); // use madness triggered ability
setChoice(playerA, "Yes"); // use madness cast
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
setStrictChooseMode(true);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerB, "Haunting Hymn", 1);
@ -119,12 +124,15 @@ public class MadnessTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerB, "Haunting Hymn");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Haunting Hymn", playerA);
setChoice(playerA, "Yes");
setChoice(playerA, "Yes"); // use madness triggered ability
setChoice(playerA, "Yes"); // use madness cast
setChoice(playerA, "X=4");
addTarget(playerA, "Pillarfield Ox");
addTargetAmount(playerA, "Pillarfield Ox", 4);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerB, "Haunting Hymn", 1);
assertGraveyardCount(playerA, "Avacyn's Judgment", 1);
@ -137,7 +145,7 @@ public class MadnessTest extends CardTestPlayerBase {
* Madness) + Olivia, Mobilized for War - Haste part of the triggered effect
* may not affect entering Vampire properly, please read further for more
* details.
*
* <p>
* When I cast Falkenrath Gorger and then discarded Asylum Visitor with
* Olivia, Mobilized for War 's triggered ability, two Madness pop-ups
* appeared, I have used the first one, Asylum Visitor entered the
@ -147,7 +155,7 @@ public class MadnessTest extends CardTestPlayerBase {
* from what I have tested, the choice at this point does not matter).
* Asylum Visitor lost Haste and was both visually and functionally affected
* by Summoning Sickness.
*
* <p>
* I was able to avoid this issue by cancelling the first Madness pop-up and
* then using only the second one.
*/
@ -171,13 +179,17 @@ public class MadnessTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Falkenrath Gorger");
setChoice(playerA, "Yes"); // Discard a card and put a +1/+1 counter on that creature, it gains haste until end of turn, and it becomes a Vampire in addition to its other types?
setChoice(playerA, "Asylum Visitor");
setChoice(playerA, "Yes"); // When this card is exiled this way, you may cast it by paying {1}{B} instead of putting it into your graveyard.
setChoice(playerA, "Yes"); // Cast Asylum Visitor by madness?
setChoice(playerA, "Asylum Visitor: Madness {1}{B}"); // choose replacement effect (TODO: 2 same madness effetcs: one from Asylum Visitor, one from Falkenrath -- is that ok?!)
//
setChoice(playerA, "Yes"); // use madness triggered ability
setChoice(playerA, "Yes"); // use madness cast
setChoice(playerA, "Yes"); // Discard a card and put a +1/+1 counter on that creature, it gains haste until end of turn, and it becomes a Vampire in addition to its other types?
setChoice(playerA, "Forest");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Falkenrath Gorger", 1);
assertPermanentCount(playerA, "Asylum Visitor", 1);
@ -189,6 +201,5 @@ public class MadnessTest extends CardTestPlayerBase {
assertAbility(playerA, "Asylum Visitor", HasteAbility.getInstance(), true);
assertGraveyardCount(playerA, "Forest", 1);
}
}

View file

@ -6,6 +6,7 @@ import mage.filter.Filter;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
@ -100,7 +101,7 @@ public class MorphTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Icefeather Aven", NO_TARGET, "Pine Walker", StackClause.WHILE_NOT_ON_STACK);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Icefeather Aven", TestPlayer.NO_TARGET, "Pine Walker", StackClause.WHILE_NOT_ON_STACK);
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
attack(3, playerA, EmptyNames.FACE_DOWN_CREATURE.toString());
@ -359,7 +360,7 @@ public class MorphTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler", NO_TARGET, "Sagu Mauler", StackClause.WHILE_NOT_ON_STACK);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sagu Mauler", TestPlayer.NO_TARGET, "Sagu Mauler", StackClause.WHILE_NOT_ON_STACK);
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
// showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.abilities.other;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class EndTurnEffectTest extends CardTestPlayerBase {
@ -16,9 +15,8 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
* Additional bug: Days Undoing and Sphinx's Tutelage are broken. You
* shouldn't get triggers off of Tutelage, since the turn ends, but it has
* you resolve them in your cleanup step.
*
* <p>
* http://tabakrules.tumblr.com/post/122350751009/days-undoing-has-been-officially-spoiled-on
*
*/
@Test
public void testSpellsAffinity() {
@ -69,7 +67,7 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Ice", "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Time Stop", NO_TARGET, "Ice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Time Stop", TestPlayer.NO_TARGET, "Ice");
setStopAt(2, PhaseStep.UPKEEP);
execute();
@ -105,7 +103,7 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Injury", "Silvercoat Lion");
addTarget(playerA, playerB);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Glorious End", NO_TARGET, "Injury");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Glorious End", TestPlayer.NO_TARGET, "Injury");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
@ -137,7 +135,7 @@ public class EndTurnEffectTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sundial of the Infinite");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Disenchant", "Sundial of the Infinite");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},", NO_TARGET, "Disenchant");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1},", TestPlayer.NO_TARGET, "Disenchant");
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.continuous;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class BoostEnchantedTest extends CardTestPlayerBase {
@ -35,12 +34,11 @@ public class BoostEnchantedTest extends CardTestPlayerBase {
* return Ghitu Firebreathing to your hand, the +1/0 goes away on the
* creature. If you re-cast Ghitu Firebreathing onto the creature, the boost
* returns.
*
* <p>
* Gatherer Rulings: 9/25/2006 If you return Ghitu Firebreathing to its
* owner's hand while the +1/+0 ability is on the stack, that ability will
* still give the creature that was last enchanted by Ghitu Firebreathing
* +1/+0.
*
*/
@Test
public void testFirebreathingReturnToHand() {
@ -54,7 +52,7 @@ public class BoostEnchantedTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Firebreathing", "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Boomerang", "Firebreathing");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: Enchanted creature", NO_TARGET, "Boomerang");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{R}: Enchanted creature", TestPlayer.NO_TARGET, "Boomerang");
setStopAt(1, PhaseStep.END_COMBAT);
execute();

View file

@ -1,4 +1,3 @@
package org.mage.test.cards.continuous;
import mage.cards.Card;
@ -7,10 +6,10 @@ import mage.constants.Zone;
import mage.game.permanent.Permanent;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class PaintersServantTest extends CardTestPlayerBase {
@ -22,9 +21,9 @@ public class PaintersServantTest extends CardTestPlayerBase {
public void testColorSet() {
// As Painter's Servant enters the battlefield, choose a color.
// All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.HAND, playerA, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
@ -35,40 +34,40 @@ public class PaintersServantTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
setChoice(playerA, "Blue");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Painter's Servant", 1);
Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA);
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isBlue());
silvercoatLion = getPermanent("Silvercoat Lion", playerB);
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isBlue());
for(Card card: playerA.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should be blue",true, card.getColor(currentGame).isBlue());
for (Card card : playerA.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should be blue", true, card.getColor(currentGame).isBlue());
}
for(Card card: playerB.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should be blue",true, card.getColor(currentGame).isBlue());
for (Card card : playerB.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should be blue", true, card.getColor(currentGame).isBlue());
}
for(Card card: playerA.getHand().getCards(currentGame)) {
for (Card card : playerA.getHand().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isRed());
Assert.assertEquals(true, card.getColor(currentGame).isBlue());
}
for(Card card: playerB.getHand().getCards(currentGame)) {
for (Card card : playerB.getHand().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isRed());
Assert.assertEquals(true, card.getColor(currentGame).isBlue());
}
for(Card card: playerA.getGraveyard().getCards(currentGame)) {
for (Card card : playerA.getGraveyard().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isWhite());
Assert.assertEquals(true, card.getColor(currentGame).isBlue());
}
for(Card card: playerB.getGraveyard().getCards(currentGame)) {
for (Card card : playerB.getGraveyard().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isWhite());
Assert.assertEquals(true, card.getColor(currentGame).isBlue());
}
@ -82,14 +81,14 @@ public class PaintersServantTest extends CardTestPlayerBase {
public void testColorReset() {
// As Painter's Servant enters the battlefield, choose a color.
// All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.HAND, playerA, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
addCard(Zone.HAND, playerB, "Lightning Bolt",2);
addCard(Zone.HAND, playerB, "Lightning Bolt", 2);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
addCard(Zone.GRAVEYARD, playerB, "Silvercoat Lion");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
@ -98,43 +97,43 @@ public class PaintersServantTest extends CardTestPlayerBase {
setChoice(playerA, "Blue");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Painter's Servant");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertGraveyardCount(playerA, "Painter's Servant", 1);
Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA);
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isBlue());
silvercoatLion = getPermanent("Silvercoat Lion", playerB);
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isBlue());
for(Card card: playerA.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should not be blue",false, card.getColor(currentGame).isBlue());
for (Card card : playerA.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should not be blue", false, card.getColor(currentGame).isBlue());
}
for(Card card: playerB.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should not be blue",false, card.getColor(currentGame).isBlue());
for (Card card : playerB.getLibrary().getCards(currentGame)) {
Assert.assertEquals(card.getName() + " should not be blue", false, card.getColor(currentGame).isBlue());
}
for(Card card: playerA.getHand().getCards(currentGame)) {
for (Card card : playerA.getHand().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isRed());
Assert.assertEquals(false, card.getColor(currentGame).isBlue());
}
for(Card card: playerB.getHand().getCards(currentGame)) {
for (Card card : playerB.getHand().getCards(currentGame)) {
Assert.assertEquals(true, card.getColor(currentGame).isRed());
Assert.assertEquals(false, card.getColor(currentGame).isBlue());
}
for(Card card: playerA.getGraveyard().getCards(currentGame)) {
if(card.getName().equals("Silvercoat Lion")) {
for (Card card : playerA.getGraveyard().getCards(currentGame)) {
if (card.getName().equals("Silvercoat Lion")) {
Assert.assertEquals(true, card.getColor(currentGame).isWhite());
Assert.assertEquals(false, card.getColor(currentGame).isBlue());
}
}
for(Card card: playerB.getGraveyard().getCards(currentGame)) {
if(card.getName().equals("Silvercoat Lion")) {
for (Card card : playerB.getGraveyard().getCards(currentGame)) {
if (card.getName().equals("Silvercoat Lion")) {
Assert.assertEquals(true, card.getColor(currentGame).isWhite());
Assert.assertEquals(false, card.getColor(currentGame).isBlue());
}
@ -152,42 +151,42 @@ public class PaintersServantTest extends CardTestPlayerBase {
public void testColorOverwrite() {
// As Painter's Servant enters the battlefield, choose a color.
// All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
// Target creature becomes blue until end of turn. Untap that creature.
// Draw a card.
addCard(Zone.HAND, playerB, "Cerulean Wisps", 1); // Instant {U}
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
setChoice(playerA, "Red");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cerulean Wisps", "Silvercoat Lion", "Painter's Servant", StackClause.WHILE_NOT_ON_STACK);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Painter's Servant", 1);
Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA);
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isRed());
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isBlue());
}
/**
* Check color of spells
/**
* Check color of spells
*/
@Test
public void testColorSpell() {
// As Painter's Servant enters the battlefield, choose a color.
// All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
addCard(Zone.HAND, playerA, "Painter's Servant", 1);
// Draw two cards.
addCard(Zone.HAND, playerA, "Divination", 1); // {U}{2}
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
// Whenever a player casts a red spell, you may gain 1 life.
addCard(Zone.BATTLEFIELD, playerA, "Dragon's Claw");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
@ -195,30 +194,30 @@ public class PaintersServantTest extends CardTestPlayerBase {
// Target creature becomes blue until end of turn. Untap that creature.
// Draw a card.
addCard(Zone.HAND, playerB, "Cerulean Wisps", 1); // Instant {U}
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
setChoice(playerA, "Red");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cerulean Wisps", "Silvercoat Lion", "Painter's Servant", StackClause.WHILE_NOT_ON_STACK);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Divination", NO_TARGET, "Painter's Servant", StackClause.WHILE_NOT_ON_STACK);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Divination", TestPlayer.NO_TARGET, "Painter's Servant", StackClause.WHILE_NOT_ON_STACK);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Painter's Servant", 1);
assertGraveyardCount(playerA, "Divination", 1);
assertGraveyardCount(playerB, "Cerulean Wisps", 1);
assertLife(playerA, 22); // + 1 from Cerulean Wisps + 1 from Divination
Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA);
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isWhite());
Assert.assertEquals(false, silvercoatLion.getColor(currentGame).isRed());
Assert.assertEquals(true, silvercoatLion.getColor(currentGame).isBlue());
}
}

View file

@ -49,8 +49,8 @@ public class UnboundFlourishingTest extends CardTestPlayerBase {
// cast with X=3, but double it
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Endless One");
setChoice(playerA, "X=3");
setChoice(playerA, "Unbound Flourishing"); // choose replacement effects
setChoice(playerA, "X=3");
checkPermanentCounters("after", 1, PhaseStep.BEGIN_COMBAT, playerA, "Endless One", CounterType.P1P1, 3 * 2 * 2);
setStrictChooseMode(true);

View file

@ -36,11 +36,13 @@ public class CastSplitCardsFromOtherZonesTest extends CardTestPlayerBase {
addTarget(playerA, playerB);
setChoice(playerA, "Wear // Tear"); // select card
setChoice(playerA, "Yes"); // confirm to cast
setChoice(playerA, "Tear"); // select tear side
setChoice(playerA, "Cast Tear"); // select tear side
addTarget(playerA, "Sanguine Bond"); // target for tear
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Mindclaw Shaman", 1);
assertGraveyardCount(playerB, "Wear // Tear", 1);
@ -67,11 +69,13 @@ public class CastSplitCardsFromOtherZonesTest extends CardTestPlayerBase {
addTarget(playerA, playerB);
setChoice(playerA, "Wear // Tear"); // select card
setChoice(playerA, "Yes"); // confirm to cast
setChoice(playerA, "Wear"); // select wear side
setChoice(playerA, "Cast Wear"); // select wear side
addTarget(playerA, "Icy Manipulator"); // target for wear
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Mindclaw Shaman", 1);
assertGraveyardCount(playerB, "Wear // Tear", 1);
@ -98,12 +102,14 @@ public class CastSplitCardsFromOtherZonesTest extends CardTestPlayerBase {
addTarget(playerA, playerB);
setChoice(playerA, "Wear // Tear"); // select card
setChoice(playerA, "Yes"); // confirm to cast
setChoice(playerA, "Wear // Tear"); // select fused
setChoice(playerA, "Cast fused Wear // Tear"); // select fused
addTarget(playerA, "Icy Manipulator"); // target for wear
addTarget(playerA, "Sanguine Bond"); // target for tear
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Mindclaw Shaman", 1);
assertGraveyardCount(playerB, "Wear // Tear", 1);
@ -130,12 +136,15 @@ public class CastSplitCardsFromOtherZonesTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Etali, Primal Storm"); // Creature {4}{R} 6/6
attack(2, playerB, "Etali, Primal Storm");
setChoice(playerB, "Yes");
setChoice(playerB, "Fire");
addTarget(playerB, "Silvercoat Lion");
setChoice(playerB, "Yes"); // free cast
setChoice(playerB, "Fire // Ice"); // card to cast
setChoice(playerB, "Cast Fire"); // ability to cast
addTargetAmount(playerB, "Silvercoat Lion", 2);
setStrictChooseMode(true);
setStopAt(2, PhaseStep.END_COMBAT);
execute();
assertAllCommandsUsed();
assertLife(playerA, 14);
assertGraveyardCount(playerA, "Silvercoat Lion", 1);

View file

@ -1,14 +1,13 @@
package org.mage.test.cards.enchantments;
import mage.constants.PhaseStep;
import mage.constants.SubType;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class SpreadingSeasTest extends CardTestPlayerBase {
@ -17,7 +16,7 @@ public class SpreadingSeasTest extends CardTestPlayerBase {
* Played Spreading Seas on opps manland (e.g. Blinkmoth Nexus) . He
* activated it on response, seas resolves but the manland loses creature
* type what should not happened.
*
* <p>
* 305.7. If an effect changes a land's subtype to one or more of the basic
* land types, the land no longer has its old land type. It loses all
* abilities generated from its rules text and its old land types, and it
@ -28,7 +27,6 @@ public class SpreadingSeasTest extends CardTestPlayerBase {
* snow) the land may have. If a land gains one or more land types in
* addition to its own, it keeps its land types and rules text, and it gains
* the new land types and mana abilities.
*
*/
@Test
public void testCreatureTypeStays() {
@ -46,7 +44,7 @@ public class SpreadingSeasTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Spreading Seas", "Blinkmoth Nexus");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}:", NO_TARGET, "Spreading Seas");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}:", TestPlayer.NO_TARGET, "Spreading Seas");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();

View file

@ -10,14 +10,14 @@ import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.CounterType;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class VivienTest extends CardTestPlayerBase {
public class VivienTest extends CardTestPlayerBase {
@Test
public void testVivienArkbowRangerAbility1NoTargets() {
setStrictChooseMode(true);
@ -28,7 +28,8 @@ public class VivienTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Arkbow Ranger");
addTargetAmount(playerA, TestPlayer.TARGET_SKIP); // stop choosing (not targets)
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Distribute");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
@ -38,9 +39,9 @@ public class VivienTest extends CardTestPlayerBase {
assertCounterCount("Vivien, Arkbow Ranger", CounterType.LOYALTY, 5);
}
@Test
public void testVivienArkbowRangerAbility1OnePossibleTarget() {
public void testVivienArkbowRangerAbilityOnePossibleTargetWithOne() {
setStrictChooseMode(true);
// +1: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.
// 3: Target creature you control deals damage equal to its power to target creature or planeswalker.
@ -49,21 +50,47 @@ public class VivienTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Arkbow Ranger");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Distribute");
addTargetAmount(playerA, "Silvercoat Lion", 1);
addTargetAmount(playerA, TestPlayer.TARGET_SKIP); // stop choosing (one target)
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Vivien, Arkbow Ranger", 1);
assertCounterCount("Vivien, Arkbow Ranger", CounterType.LOYALTY, 5);
assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
assertPowerToughness(playerB, "Silvercoat Lion", 2 + 1, 2 + 1);
}
@Test
public void testVivienArkbowRangerAbilityOnePossibleTargetWithTwo() {
setStrictChooseMode(true);
// +1: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.
// 3: Target creature you control deals damage equal to its power to target creature or planeswalker.
// 5: You may choose a creature card you own from outside the game, reveal it, and put it into your hand.
addCard(Zone.HAND, playerA, "Vivien, Arkbow Ranger"); // Planeswalker {1}{G}{G}{G} - starts with 4 Loyality counters
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Arkbow Ranger");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Distribute");
addTargetAmount(playerA, "Silvercoat Lion", 2);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Vivien, Arkbow Ranger", 1);
assertCounterCount("Vivien, Arkbow Ranger", CounterType.LOYALTY, 5);
assertPowerToughness(playerB, "Silvercoat Lion", 2 + 2, 2 + 2);
}
@Test
public void testVivienArkbowRangerAbility1OneOwnPossibleTarget() {
// +1: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.
@ -73,22 +100,22 @@ public class VivienTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Arkbow Ranger");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Distribute");
addTargetAmount(playerA, "Silvercoat Lion", 2);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Vivien, Arkbow Ranger", 1);
assertCounterCount("Vivien, Arkbow Ranger", CounterType.LOYALTY, 5);
assertPowerToughness(playerA, "Silvercoat Lion", 4, 4);
}
}
@Test
public void testVivienArkbowRangerAbility1TwoOwnPossibleTarget() {
// +1: Distribute two +1/+1 counters among up to two target creatures. They gain trample until end of turn.
@ -99,24 +126,24 @@ public class VivienTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vivien, Arkbow Ranger");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1: Distribute");
addTargetAmount(playerA, "Silvercoat Lion", 1);
addTargetAmount(playerA, "Pillarfield Ox", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Vivien, Arkbow Ranger", 1);
assertCounterCount("Vivien, Arkbow Ranger", CounterType.LOYALTY, 5);
assertPowerToughness(playerA, "Silvercoat Lion", 3, 3);
assertPowerToughness(playerA, "Pillarfield Ox", 3, 5);
assertAbility(playerA, "Silvercoat Lion", TrampleAbility.getInstance(), true);
assertAbility(playerA, "Pillarfield Ox", TrampleAbility.getInstance(), true);
}
}
}

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.replacement;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class HallowedMoonlightTest extends CardTestPlayerBase {
@ -72,7 +71,7 @@ public class HallowedMoonlightTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Rally the Ancestors");
setChoice(playerB, "X=4");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Hallowed Moonlight", NO_TARGET, "Rally the Ancestors");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Hallowed Moonlight", TestPlayer.NO_TARGET, "Rally the Ancestors");
setStopAt(2, PhaseStep.END_TURN);
execute();

View file

@ -48,14 +48,17 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Chalice of the Void", 1);
addCard(Zone.BATTLEFIELD, playerB, "Island", 1);
// Counter target spell with converted mana cost 1.
addCard(Zone.HAND, playerB, "Mental Misstep", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Chalice of the Void");
setChoice(playerA, "X=1");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Mental Misstep", "Chalice of the Void", "Chalice of the Void");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
// assertAllCommandsUsed(); // cast Mental Misstep must be ignored
assertHandCount(playerB, "Mental Misstep", 1); // cannot be cast because no legal target exists
assertPermanentCount(playerA, "Chalice of the Void", 1); // was not countered
@ -81,10 +84,13 @@ public class ChaliceOfTheVoidTest extends CardTestPlayerBase {
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flashback {R}{R}");
setChoice(playerB, "X=1");
addTarget(playerB, playerA);
addTargetAmount(playerB, playerA, 1);
setChoice(playerB, "Mountain"); // discard 1 card
setStrictChooseMode(true);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertExileCount(playerB, "Conflagrate", 1);
//TODO: Apparently there are two mountains in the graveyard at the end of the test now.

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.single.lrw;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author Kranken, LevelX2
*/
@ -23,12 +22,12 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Soldier of the Pantheon");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.", NO_TARGET, "Cast Lightning Bolt");
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.", TestPlayer.NO_TARGET, "Cast Lightning Bolt");
playerA.addChoice("Lightning Bolt");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerB, "Lightning Bolt", 1);
assertGraveyardCount(playerA, "Burrenton Forge-Tender", 1);
@ -46,15 +45,15 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
addTarget(playerB, "Soldier of the Pantheon");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature.");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
TestPlayer.NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature.");
playerA.addChoice("Flametongue Kavu");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerB, "Flametongue Kavu", 1);
assertGraveyardCount(playerA, "Burrenton Forge-Tender", 1);
assertPermanentCount(playerA, "Soldier of the Pantheon", 1);
}
@ -73,24 +72,24 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Flametongue Kavu");
addTarget(playerB, "Soldier of the Pantheon");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature.");
activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.",
TestPlayer.NO_TARGET, "When {this} enters the battlefield, {source} deals 4 damage to target creature.");
playerA.addChoice("Flametongue Kavu");
castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Cloudshift", "Flametongue Kavu");
addTarget(playerB, "Soldier of the Pantheon"); // now the damage may not be prevented because it's a new object
setStopAt(2, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerB, "Flametongue Kavu", 1);
assertGraveyardCount(playerB, "Cloudshift", 1);
assertGraveyardCount(playerA, "Burrenton Forge-Tender", 1);
assertGraveyardCount(playerA, "Soldier of the Pantheon", 1);
}
}
@Test
public void testPreventDamageFromToken() {
addCard(Zone.BATTLEFIELD, playerA, "Burrenton Forge-Tender");
@ -111,26 +110,26 @@ public class BurrentonForgeTenderTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Rite of Replication", "Mogg Fanatic");
setChoice(playerB, "No"); // no kicker
castSpell(2, PhaseStep.BEGIN_COMBAT, playerA, "Orzhov Charm", "Mogg Fanatic");
setModeChoice(playerA, "1");
activateAbility(2, PhaseStep.END_COMBAT, playerA, "Sacrifice {this}: Prevent all damage a red source of your choice would deal this turn.");
playerA.addChoice("Mogg Fanatic");
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}: {source} deals 1 damage to ","Soldier of the Pantheon");
activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}: {source} deals 1 damage to ", "Soldier of the Pantheon");
setStopAt(2, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerB, "Mogg Fanatic", 0);
assertGraveyardCount(playerA, "Orzhov Charm", 1);
assertHandCount(playerA, "Mogg Fanatic", 1);
assertGraveyardCount(playerB, "Rite of Replication", 1);
assertGraveyardCount(playerA, "Burrenton Forge-Tender", 1);
assertPermanentCount(playerA, "Soldier of the Pantheon", 1);
}
}
}

View file

@ -6,7 +6,6 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class CastSplitCardsWithFuseTest extends CardTestPlayerBase {
@ -27,8 +26,10 @@ public class CastSplitCardsWithFuseTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Wear", "Juggernaut");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Wear // Tear", 1);
@ -52,8 +53,10 @@ public class CastSplitCardsWithFuseTest extends CardTestPlayerBase {
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tear", "Absolute Grace");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Wear // Tear", 1);
@ -62,8 +65,9 @@ public class CastSplitCardsWithFuseTest extends CardTestPlayerBase {
@Test
public void testCastingFusedSpell() {
// TODO: AI can't distribute mana for future (e.g. it consume W instead R and can't cast next split half that require W)
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1 + 1);
// INSTANT
// Wear {1}{R}
// Destroy target artifact.
@ -76,12 +80,17 @@ public class CastSplitCardsWithFuseTest extends CardTestPlayerBase {
addCard(Zone.BATTLEFIELD, playerB, "Absolute Grace"); // Enchantment
addCard(Zone.BATTLEFIELD, playerB, "Juggernaut"); // Artifact
showAvaileableAbilities("abils", 1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "fused Wear // Tear");
playerA.addTarget("Juggernaut");
playerA.addTarget("Absolute Grace");
addTarget(playerA, "Juggernaut");
addTarget(playerA, "Absolute Grace");
//playerA.addTarget("Absolute Grace");
showBattlefield("after", 1, PhaseStep.BEGIN_COMBAT, playerB);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
assertGraveyardCount(playerA, "Wear // Tear", 1);

View file

@ -1,13 +1,12 @@
package org.mage.test.cards.triggers;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class ReturnToBattlefieldEffectsTest extends CardTestPlayerBase {
@ -149,7 +148,7 @@ public class ReturnToBattlefieldEffectsTest extends CardTestPlayerBase {
attack(2, playerB, "Reassembling Skeleton");
block(2, playerA, "Necroskitter", "Reassembling Skeleton");
activateAbility(2, PhaseStep.COMBAT_DAMAGE, playerB, "{1}{B}: Return", NO_TARGET, "Whenever a creature");
activateAbility(2, PhaseStep.COMBAT_DAMAGE, playerB, "{1}{B}: Return", TestPlayer.NO_TARGET, "Whenever a creature");
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);

View file

@ -251,13 +251,15 @@ public class SpellskiteTest extends CardTestPlayerBase {
// Cast Fiery Justice
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice");
addTarget(playerA, playerB); // 5 life to B
addTargetAmount(playerA, "Scute Mob" , 1); // target 1
addTargetAmount(playerA, "Scute Mob", 1); // target 1
addTargetAmount(playerA, "Spellskite", 4); // target 2
addTarget(playerA, playerB); // 5 life to B
// B activate Spellskite, but can't change any targets cause it's already targeted
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
setChoice(playerB, "Yes"); // pay 2 life
setStrictChooseMode(true);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertAllCommandsUsed();
@ -319,9 +321,9 @@ public class SpellskiteTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Fiery Justice");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Fiery Justice"); // 5 damage distributed to any number of targets
addTargetAmount(playerA, "Royal Assassin",1);
addTargetAmount(playerA, "Blinking Spirit",2);
addTargetAmount(playerA, "Pearled Unicorn",2);
addTargetAmount(playerA, "Royal Assassin", 1);
addTargetAmount(playerA, "Blinking Spirit", 2);
addTargetAmount(playerA, "Pearled Unicorn", 2);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "{U/P}: Change a target", "Fiery Justice", "Fiery Justice");
setChoice(playerB, "Yes"); // pay 2 life

View file

@ -42,7 +42,7 @@ public class TestComputerPlayer extends ComputerPlayer {
if (!this.testPlayerLink.getChoices().isEmpty()) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = this.getSpellAbilities(object, game.getState().getZone(object.getId()), game);
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getSpellAbilities(playerId, object, game.getState().getZone(object.getId()), game);
// left, right or fused cast
for (String choose : this.testPlayerLink.getChoices()) {

View file

@ -42,7 +42,7 @@ public class TestComputerPlayer7 extends ComputerPlayer7 {
if (!this.testPlayerLink.getChoices().isEmpty()) {
MageObject object = game.getObject(ability.getSourceId());
if (object != null) {
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = this.getSpellAbilities(object, game.getState().getZone(object.getId()), game);
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getSpellAbilities(playerId, object, game.getState().getZone(object.getId()), game);
// left, right or fused cast
for (String choose : this.testPlayerLink.getChoices()) {

View file

@ -1,11 +1,5 @@
package org.mage.test.player;
import java.io.Serializable;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.MageItem;
import mage.MageObject;
import mage.MageObjectReference;
@ -17,7 +11,6 @@ import mage.abilities.costs.Costs;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.abilities.mana.ManaOptions;
import mage.cards.Card;
@ -55,6 +48,7 @@ import mage.player.ai.ComputerPlayer;
import mage.players.Library;
import mage.players.ManaPool;
import mage.players.Player;
import mage.players.PlayerImpl;
import mage.players.net.UserData;
import mage.target.*;
import mage.target.common.*;
@ -62,6 +56,13 @@ import mage.util.CardUtil;
import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Ignore;
import java.io.Serializable;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl.*;
/**
@ -74,9 +75,10 @@ public class TestPlayer implements Player {
private static final Logger LOGGER = Logger.getLogger(TestPlayer.class);
public static final String TARGET_SKIP = "[target_skip]";
public static final String TARGET_SKIP = "[target_skip]"; // stop/skip targeting
public static final String BLOCK_SKIP = "[block_skip]";
public static final String ATTACK_SKIP = "[attack_skip]";
public static final String NO_TARGET = "NO_TARGET"; // cast spell or activate ability without target defines
private int maxCallsWithoutAction = 100;
private int foundNoAction = 0;
@ -84,7 +86,6 @@ public class TestPlayer implements Player {
private final List<PlayerAction> actions = new ArrayList<>();
private final List<String> choices = new ArrayList<>(); // choices stack for choice
private final List<String> targets = new ArrayList<>(); // targets stack for choose (it's uses on empty direct target by cast command)
private final LinkedHashMap<String, Integer> targetsAmount = new LinkedHashMap<>(); // targets and amounts for targets that also need to set an amount
private final Map<String, UUID> aliases = new HashMap<>(); // aliases for game objects/players (use it for cards with same name to save and use)
private final List<String> modesSet = new ArrayList<>();
@ -156,16 +157,6 @@ public class TestPlayer implements Player {
targets.add(target);
}
/**
* Sets the data for TargetAmount classes that include also an amount beside the target like TargetPermanentAmount
*
* @param targetName
* @param amount
*/
public void addTargetAmount(String targetName, Integer amount) {
targetsAmount.put(targetName, amount);
}
public void addAlias(String name, UUID Id) {
aliases.put(name, Id);
}
@ -188,7 +179,7 @@ public class TestPlayer implements Player {
/**
* @param maxCallsWithoutAction max number of priority passes a player may
* have for this test (default = 100)
* have for this test (default = 100)
*/
public void setMaxCallsWithoutAction(int maxCallsWithoutAction) {
this.maxCallsWithoutAction = maxCallsWithoutAction;
@ -518,7 +509,7 @@ public class TestPlayer implements Player {
if (ability.toString().startsWith(groups[0])) {
int bookmark = game.bookmarkState();
Ability newAbility = ability.copy();
if (groups.length > 1 && !groups[1].equals("target=NO_TARGET")) {
if (groups.length > 1 && !groups[1].equals("target=" + NO_TARGET)) {
groupsForTargetHandling = groups;
}
if (computerPlayer.activateAbility((ActivatedAbility) newAbility, game)) {
@ -909,12 +900,12 @@ public class TestPlayer implements Player {
List<String> data = cards.stream()
.map(c -> (((c instanceof PermanentToken) ? "[T] " : "[C] ")
+ c.getIdName()
+ (c.isCopy() ? " [copy of " + c.getCopyFrom().getId().toString().substring(0, 3) + "]" : "")
+ " - " + c.getPower().getValue() + "/" + c.getToughness().getValue()
+ (c.isPlaneswalker() ? " - L" + c.getCounters(game).getCount(CounterType.LOYALTY) : "")
+ ", " + (c.isTapped() ? "Tapped" : "Untapped")
+ (c.getAttachedTo() == null ? "" : ", attached to " + game.getPermanent(c.getAttachedTo()).getIdName())))
+ c.getIdName()
+ (c.isCopy() ? " [copy of " + c.getCopyFrom().getId().toString().substring(0, 3) + "]" : "")
+ " - " + c.getPower().getValue() + "/" + c.getToughness().getValue()
+ (c.isPlaneswalker() ? " - L" + c.getCounters(game).getCount(CounterType.LOYALTY) : "")
+ ", " + (c.isTapped() ? "Tapped" : "Untapped")
+ (c.getAttachedTo() == null ? "" : ", attached to " + game.getPermanent(c.getAttachedTo()).getIdName())))
.sorted()
.collect(Collectors.toList());
@ -938,11 +929,11 @@ public class TestPlayer implements Player {
List<String> data = abilities.stream()
.map(a -> (a.getZone() + " -> "
+ a.getSourceObject(game).getIdName() + " -> "
+ (a.toString().length() > 0
? a.toString().substring(0, Math.min(20, a.toString().length()) - 1)
: a.getClass().getSimpleName())
+ "..."))
+ a.getSourceObject(game).getIdName() + " -> "
+ (a.toString().length() > 0
? a.toString().substring(0, Math.min(20, a.toString().length()) - 1)
: a.getClass().getSimpleName())
+ "..."))
.sorted()
.collect(Collectors.toList());
@ -1296,7 +1287,7 @@ public class TestPlayer implements Player {
UUID defenderId = null;
boolean mustAttackByAction = false;
boolean madeAttackByAction = false;
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext();) {
for (Iterator<org.mage.test.player.PlayerAction> it = actions.iterator(); it.hasNext(); ) {
PlayerAction action = it.next();
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
mustAttackByAction = true;
@ -1357,7 +1348,7 @@ public class TestPlayer implements Player {
}
if (mustAttackByAction && !madeAttackByAction) {
this.chooseStrictModeFailed(game, "select attackers must use attack command but don't");
this.chooseStrictModeFailed("attacker", game, "select attackers must use attack command but don't");
}
// AI play if no actions available
@ -1472,9 +1463,9 @@ public class TestPlayer implements Player {
return o != null ? o.getClass().getSimpleName() + ": " + o.getMessage() : "null";
}
private void chooseStrictModeFailed(Game game, String reason) {
private void chooseStrictModeFailed(String choiceType, Game game, String reason) {
if (strictChooseMode) {
Assert.fail("Missing target/choice def for turn " + game.getTurnNum() + ", " + this.getName() + ", "
Assert.fail("Missing " + choiceType + " def for turn " + game.getTurnNum() + ", " + this.getName() + ", "
+ game.getStep().getType().name() + ": " + reason);
}
}
@ -1501,7 +1492,7 @@ public class TestPlayer implements Player {
return null;
}
this.chooseStrictModeFailed(game, getInfo(source));
this.chooseStrictModeFailed("mode", game, getInfo(source));
return computerPlayer.chooseMode(modes, source, game);
}
@ -1515,7 +1506,7 @@ public class TestPlayer implements Player {
//Assert.fail("Wrong choice");
}
this.chooseStrictModeFailed(game, choice.getMessage());
this.chooseStrictModeFailed("choice", game, choice.getMessage());
return computerPlayer.choose(outcome, choice, game);
}
@ -1525,21 +1516,22 @@ public class TestPlayer implements Player {
return 0;
}
if (!choices.isEmpty()) {
for (String choice : choices) {
int index = 0;
for (Map.Entry<String, String> entry : rEffects.entrySet()) {
if (entry.getValue().startsWith(choice)) {
choices.remove(choice);
return index;
}
index++;
String choice = choices.get(0);
int index = 0;
for (Map.Entry<String, String> entry : rEffects.entrySet()) {
if (entry.getValue().startsWith(choice)) {
choices.remove(choice);
return index;
}
index++;
}
// TODO: enable fail checks and fix tests
//Assert.fail("wrong choice");
}
this.chooseStrictModeFailed(game, String.join("; ", rEffects.values()));
this.chooseStrictModeFailed("choice", game, String.join("; ", rEffects.values()));
return computerPlayer.chooseReplacementEffect(rEffects, game);
}
@ -1737,7 +1729,7 @@ public class TestPlayer implements Player {
// ignore player select
if (!target.getMessage().equals("Select a starting player")) {
this.chooseStrictModeFailed(game, getInfo(game.getObject(sourceId)) + "; " + getInfo(target));
this.chooseStrictModeFailed("choice", game, getInfo(game.getObject(sourceId)) + "; " + getInfo(target));
}
return computerPlayer.choose(outcome, target, sourceId, game, options);
}
@ -1774,9 +1766,11 @@ public class TestPlayer implements Player {
if (!targets.isEmpty()) {
// do not select
// skip targets
if (targets.get(0).equals(TARGET_SKIP)) {
Assert.assertEquals("found empty choice, but target is not support 0 choice", 0, target.getMinNumberOfTargets());
Assert.assertTrue("found skip target, but it require more targets, needs "
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
target.getTargets().size() >= target.getMinNumberOfTargets());
targets.remove(0);
return true;
}
@ -2030,7 +2024,7 @@ public class TestPlayer implements Player {
Assert.fail(message);
}
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
this.chooseStrictModeFailed("target", game, getInfo(source) + "; " + getInfo(target));
return computerPlayer.chooseTarget(outcome, target, source, game);
}
@ -2059,7 +2053,7 @@ public class TestPlayer implements Player {
//Assert.fail("Wrong target");
}
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
this.chooseStrictModeFailed("target", game, getInfo(source) + "; " + getInfo(target));
return computerPlayer.chooseTarget(outcome, cards, target, source, game);
}
@ -2076,7 +2070,7 @@ public class TestPlayer implements Player {
//Assert.fail("Wrong choice");
}
this.chooseStrictModeFailed(game, abilities.stream().map(this::getInfo).collect(Collectors.joining("; ")));
this.chooseStrictModeFailed("choice", game, abilities.stream().map(this::getInfo).collect(Collectors.joining("; ")));
return computerPlayer.chooseTriggeredAbility(abilities, game);
}
@ -2103,7 +2097,8 @@ public class TestPlayer implements Player {
//Assert.fail("Wrong choice");
}
this.chooseStrictModeFailed(game, getInfo(source) + "; " + message + ": " + trueText + " - " + falseText);
this.chooseStrictModeFailed("choice", game, getInfo(source) + "; " + message + ": "
+ (trueText != null ? trueText : "Yes") + " - " + (falseText != null ? falseText : "No"));
return computerPlayer.chooseUse(outcome, message, secondMessage, trueText, falseText, source, game);
}
@ -2119,7 +2114,7 @@ public class TestPlayer implements Player {
}
}
this.chooseStrictModeFailed(game, getInfo(ability) + "; " + message);
this.chooseStrictModeFailed("choice", game, getInfo(ability) + "; " + message);
return computerPlayer.announceXMana(min, max, multiplier, message, game, ability);
}
@ -2133,7 +2128,7 @@ public class TestPlayer implements Player {
}
}
this.chooseStrictModeFailed(game, getInfo(ability) + "; " + message);
this.chooseStrictModeFailed("choice", game, getInfo(ability) + "; " + message);
return computerPlayer.announceXCost(min, max, message, game, ability, null);
}
@ -2147,7 +2142,7 @@ public class TestPlayer implements Player {
}
}
this.chooseStrictModeFailed(game, message);
this.chooseStrictModeFailed("choice", game, message);
return computerPlayer.getAmount(min, max, message, game);
}
@ -3248,7 +3243,7 @@ public class TestPlayer implements Player {
@Override
public boolean choose(Outcome outcome, Target target,
UUID sourceId, Game game
UUID sourceId, Game game
) {
// needed to call here the TestPlayer because it's overwitten
return choose(outcome, target, sourceId, game, null);
@ -3256,7 +3251,7 @@ public class TestPlayer implements Player {
@Override
public boolean choose(Outcome outcome, Cards cards,
TargetCard target, Game game
TargetCard target, Game game
) {
if (!choices.isEmpty()) {
for (String choose2 : choices) {
@ -3286,44 +3281,69 @@ public class TestPlayer implements Player {
//Assert.fail("Wrong choice");
}
this.chooseStrictModeFailed(game, getInfo(target));
this.chooseStrictModeFailed("choice", game, getInfo(target));
return computerPlayer.choose(outcome, cards, target, game);
}
@Override
@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target,
Ability source, Game game
) {
if (!targetsAmount.isEmpty()) {
for (Iterator<Entry<String, Integer>> iterator = targetsAmount.entrySet().iterator(); iterator.hasNext();) {
Entry<String, Integer> targetRecord = iterator.next();
if (target.getAmountRemaining() > 0) {
target.possibleTargets(source.getSourceId(), source.getControllerId(), game).forEach((possibleTarget) -> {
MageObject objectPermanent = game.getObject(possibleTarget);
Player objectPlayer = game.getPlayer(possibleTarget);
String objectName = objectPermanent != null ? objectPermanent.getName() : objectPlayer.getName();
if (objectName.equals(targetRecord.getKey())) {
if (!target.getTargets().contains(possibleTarget) && target.canTarget(possibleTarget, source, game)) {
// can select
target.addTarget(possibleTarget, targetRecord.getValue(), source, game);
iterator.remove();
}
}
});
// chooseTargetAmount calls for EACH target cycle (e.g. one target per click, see TargetAmount)
// if use want to stop choosing then chooseTargetAmount must return false (example: up to xxx)
Assert.assertNotEquals("chooseTargetAmount needs non zero amount remaining", 0, target.getAmountRemaining());
if (!targets.isEmpty()) {
// skip targets
if (targets.get(0).equals(TARGET_SKIP)) {
Assert.assertTrue("found skip target, but it require more targets, needs "
+ (target.getMinNumberOfTargets() - target.getTargets().size()) + " more",
target.getTargets().size() >= target.getMinNumberOfTargets());
targets.remove(0);
return false; // false in chooseTargetAmount = stop to choose
}
// only target amount needs
String[] choiceSettings = targets.get(0).split("\\^");
if (choiceSettings.length != 2
|| !choiceSettings[1].startsWith("X=")) {
Assert.fail("Must be target amount, but found unknown target: " + targets.get(0));
}
String targetName = choiceSettings[0];
int targetAmount = Integer.parseInt(choiceSettings[1].substring("X=".length()));
// player target support
if (targetName.startsWith("targetPlayer=")) {
targetName = targetName.substring(targetName.indexOf("targetPlayer=") + "targetPlayer=".length());
}
String targetInfo = "(" + targetName + " - " + targetAmount + ")";
Assert.assertTrue("target amount must be non zero " + targetInfo, targetAmount > 0);
Assert.assertTrue("target amount must be <= remaining = " + target.getAmountRemaining() + " " + targetInfo, targetAmount <= target.getAmountRemaining());
if (target.getAmountRemaining() > 0) {
for (UUID possibleTarget : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
MageObject objectPermanent = game.getObject(possibleTarget);
Player objectPlayer = game.getPlayer(possibleTarget);
String objectName = objectPermanent != null ? objectPermanent.getName() : objectPlayer.getName();
if (objectName.equals(targetName)) {
if (!target.getTargets().contains(possibleTarget) && target.canTarget(possibleTarget, source, game)) {
// can select
target.addTarget(possibleTarget, targetAmount, source, game);
targets.remove(0);
return true; // one target per choose call
}
}
}
}
}
if (!target.isRequired() && target.getAmountRemaining() > 0) {
if (strictChooseMode) {
target.setAmountDefinition(StaticValue.get(0));
target.setAmount(source, game);
return true;
}
}
this.chooseStrictModeFailed(game, getInfo(source) + "; " + getInfo(target));
this.chooseStrictModeFailed("target", game, getInfo(source) + "; " + getInfo(target));
return computerPlayer.chooseTargetAmount(outcome, target, source, game);
}
@Override
public boolean chooseMulligan(Game game
) {
@ -3332,15 +3352,15 @@ public class TestPlayer implements Player {
@Override
public boolean choosePile(Outcome outcome, String message,
List<? extends Card> pile1, List<? extends Card> pile2,
Game game
List<? extends Card> pile1, List<? extends Card> pile2,
Game game
) {
return computerPlayer.choosePile(outcome, message, pile1, pile2, game);
}
@Override
public boolean playMana(Ability ability, ManaCost unpaid,
String promptText, Game game
String promptText, Game game
) {
groupsForTargetHandling = null;
return computerPlayer.playMana(ability, unpaid, promptText, game);
@ -3354,15 +3374,15 @@ public class TestPlayer implements Player {
@Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup,
List<UUID> blockerOrder, Game game
List<UUID> blockerOrder, Game game
) {
return computerPlayer.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
}
@Override
public void assignDamage(int damage, List<UUID> targets,
String singleTargetName, UUID sourceId,
Game game
String singleTargetName, UUID sourceId,
Game game
) {
computerPlayer.assignDamage(damage, targets, singleTargetName, sourceId, game);
}
@ -3381,14 +3401,14 @@ public class TestPlayer implements Player {
@Override
public void pickCard(List<Card> cards, Deck deck,
Draft draft
Draft draft
) {
computerPlayer.pickCard(cards, deck, draft);
}
@Override
public boolean scry(int value, Ability source,
Game game
Game game
) {
// Don't scry at the start of the game.
if (game.getTurnNum() == 1 && game.getStep() == null) {
@ -3399,44 +3419,44 @@ public class TestPlayer implements Player {
@Override
public boolean surveil(int value, Ability source,
Game game
Game game
) {
return computerPlayer.surveil(value, source, game);
}
@Override
public boolean moveCards(Card card, Zone toZone,
Ability source, Game game
Ability source, Game game
) {
return computerPlayer.moveCards(card, toZone, source, game);
}
@Override
public boolean moveCards(Card card, Zone toZone,
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) {
return computerPlayer.moveCards(card, toZone, source, game, tapped, faceDown, byOwner, appliedEffects);
}
@Override
public boolean moveCards(Cards cards, Zone toZone,
Ability source, Game game
Ability source, Game game
) {
return computerPlayer.moveCards(cards, toZone, source, game);
}
@Override
public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game
Ability source, Game game
) {
return computerPlayer.moveCards(cards, toZone, source, game);
}
@Override
public boolean moveCards(Set<Card> cards, Zone toZone,
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
Ability source, Game game,
boolean tapped, boolean faceDown, boolean byOwner, List<UUID> appliedEffects
) {
return computerPlayer.moveCards(cards, toZone, source, game, tapped, faceDown, byOwner, appliedEffects);
}
@ -3524,6 +3544,23 @@ public class TestPlayer implements Player {
@Override
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
return card.getSpellAbility();
String allInfo = "";
if (!choices.isEmpty()) {
Map<UUID, ActivatedAbility> useable = PlayerImpl.getSpellAbilities(this.getId(), card, game.getState().getZone(card.getId()), game);
for (ActivatedAbility ability : useable.values()) {
if (ability.toString().startsWith(choices.get(0))) {
choices.remove(0);
return (SpellAbility) ability;
}
}
allInfo = useable.values().stream().map(Object::toString).collect(Collectors.joining("\n"));
// TODO: enable fail checks and fix tests
//Assert.fail("Wrong choice");
}
this.chooseStrictModeFailed("choice", game, getInfo(card) + " - can't select ability to cast.\n" + "Card's abilities:\n" + allInfo);
return computerPlayer.chooseAbilityForCast(card, game, noMana);
}
}

View file

@ -46,9 +46,6 @@ import java.util.stream.Collectors;
* @author ayratn
*/
public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implements CardTestAPI {
// Defines the constant if for activate ability is not target but a ability on the stack to define
public static final String NO_TARGET = "NO_TARGET";
// TODO: add target player param to commands
public static final String CHECK_COMMAND_PT = "PT";
@ -1395,7 +1392,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param player
* @param cardName
* @param targetName for modes you can add "mode=3" before target name,
* multiple targets can be seperated by ^
* multiple targets can be seperated by ^, not target marks as TestPlayer.NO_TARGET
*/
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
//Assert.assertNotEquals("", cardName);
@ -1604,11 +1601,29 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
player.addTarget("targetPlayer=" + targetPlayer.getName());
}
/**
* @param player
* @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop "up two xxx" selection
* @param amount
*/
public void addTargetAmount(TestPlayer player, String target, int amount) {
player.addTargetAmount(target, amount);
if (target.equals(TestPlayer.TARGET_SKIP)) {
player.addTarget(target);
} else {
player.addTarget(target + "^X=" + amount);
}
}
public void addTargetAmount(TestPlayer player, Player targetPlayer, int amount) {
addTargetAmount(player, "targetPlayer=" + targetPlayer.getName(), amount);
}
public void addTargetAmount(TestPlayer player, String target) {
Assert.assertTrue("Only skip command allows here", target.equals(TestPlayer.TARGET_SKIP));
addTargetAmount(player, target, 0);
}
public void setDecknamePlayerA(String deckname) {
deckNameA = deckname;
}