mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 13:32:06 -08:00
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:
parent
b0853fae8b
commit
e1fea330dd
24 changed files with 435 additions and 327 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue