* Starfield of Nyx - Fixed that not only controlled permanents are effected. Fixed some layered effects problems (fixes #6638).

This commit is contained in:
LevelX2 2020-06-14 12:22:30 +02:00
parent 033f80c6ed
commit f7c24e8b7f
4 changed files with 141 additions and 125 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID; import java.util.UUID;
@ -11,11 +10,12 @@ import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.DependencyType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Layer; import mage.constants.Layer;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubLayer; import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -28,7 +28,7 @@ import mage.target.TargetPermanent;
public final class SongOfTheDryads extends CardImpl { public final class SongOfTheDryads extends CardImpl {
public SongOfTheDryads(UUID ownerId, CardSetInfo setInfo) { public SongOfTheDryads(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
this.subtype.add(SubType.AURA); this.subtype.add(SubType.AURA);
// Enchant permanent // Enchant permanent
@ -58,6 +58,7 @@ class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
public BecomesColorlessForestLandEffect() { public BecomesColorlessForestLandEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment); super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Enchanted permanent is a colorless Forest land"; this.staticText = "Enchanted permanent is a colorless Forest land";
dependencyTypes.add(DependencyType.BecomeForest);
} }
public BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) { public BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) {
@ -89,10 +90,10 @@ class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
permanent.getColor(game).setRed(false); permanent.getColor(game).setRed(false);
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game); permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break; break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.LAND); permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).clear(); permanent.getSubtype(game).clear();

View file

@ -12,7 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterEnchantmentPermanent; import mage.filter.common.FilterEnchantmentPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.AnotherPredicate;
@ -47,15 +47,15 @@ public final class StarfieldOfNyx extends CardImpl {
public StarfieldOfNyx(UUID ownerId, CardSetInfo setInfo) { public StarfieldOfNyx(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}");
// At the beginning of your upkeep, you may return target enchantment card // At the beginning of your upkeep, you may return target enchantment card
// from your graveyard to the battlefield. // from your graveyard to the battlefield.
Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, Ability ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD,
new ReturnFromGraveyardToBattlefieldTargetEffect(), TargetController.YOU, true); new ReturnFromGraveyardToBattlefieldTargetEffect(), TargetController.YOU, true);
ability.addTarget(new TargetCardInGraveyard(filterGraveyardEnchantment)); ability.addTarget(new TargetCardInGraveyard(filterGraveyardEnchantment));
this.addAbility(ability); this.addAbility(ability);
// As long as you control five or more enchantments, each other non-Aura enchantment // As long as you control five or more enchantments, each other non-Aura enchantment
// you control is a creature in addition to its other types and has base power and // you control is a creature in addition to its other types and has base power and
// base toughness each equal to its converted mana cost. // base toughness each equal to its converted mana cost.
ConditionalContinuousEffect effect = new ConditionalContinuousEffect( ConditionalContinuousEffect effect = new ConditionalContinuousEffect(
new StarfieldOfNyxEffect(), new PermanentsOnTheBattlefieldCondition( new StarfieldOfNyxEffect(), new PermanentsOnTheBattlefieldCondition(
@ -74,13 +74,13 @@ public final class StarfieldOfNyx extends CardImpl {
static class StarfieldOfNyxEffect extends ContinuousEffectImpl { static class StarfieldOfNyxEffect extends ContinuousEffectImpl {
private static final FilterPermanent filter private static final FilterControlledPermanent filter
= new FilterPermanent("Each other non-Aura enchantment you control"); = new FilterControlledPermanent("Each other non-Aura enchantment you control");
private static final FilterEnchantmentPermanent filter2
= new FilterEnchantmentPermanent();
static { static {
filter2.add(TargetController.YOU.getControllerPredicate()); filter.add(CardType.ENCHANTMENT.getPredicate());
filter.add(Predicates.not(SubType.AURA.getPredicate()));
filter.add(AnotherPredicate.instance);
} }
public StarfieldOfNyxEffect() { public StarfieldOfNyxEffect() {
@ -91,8 +91,14 @@ public final class StarfieldOfNyx extends CardImpl {
this.dependendToTypes.add(DependencyType.EnchantmentAddingRemoving); // Enchanted Evening this.dependendToTypes.add(DependencyType.EnchantmentAddingRemoving); // Enchanted Evening
this.dependendToTypes.add(DependencyType.AuraAddingRemoving); // Cloudform this.dependendToTypes.add(DependencyType.AuraAddingRemoving); // Cloudform
this.dependendToTypes.add(DependencyType.BecomeForest); // Song of the Dryads
this.dependendToTypes.add(DependencyType.BecomeMountain);
this.dependendToTypes.add(DependencyType.BecomePlains);
this.dependendToTypes.add(DependencyType.BecomeSwamp);
this.dependendToTypes.add(DependencyType.BecomeIsland);
this.dependencyTypes.add(DependencyType.BecomeCreature); // Conspiracy this.dependencyTypes.add(DependencyType.BecomeCreature); // Conspiracy
} }
public StarfieldOfNyxEffect(final StarfieldOfNyxEffect effect) { public StarfieldOfNyxEffect(final StarfieldOfNyxEffect effect) {
@ -106,9 +112,6 @@ public final class StarfieldOfNyx extends CardImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
filter.add(CardType.ENCHANTMENT.getPredicate());
filter.add(Predicates.not(SubType.AURA.getPredicate()));
filter.add(AnotherPredicate.instance);
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, for (Permanent permanent : game.getBattlefield().getActivePermanents(filter,
source.getControllerId(), source.getSourceId(), game)) { source.getControllerId(), source.getSourceId(), game)) {
switch (layer) { switch (layer) {

View file

@ -1,13 +1,14 @@
package org.mage.test.cards.enchantments; package org.mage.test.cards.enchantments;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.constants.CardType;
import mage.constants.EmptyNames; import mage.constants.EmptyNames;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.Filter; import mage.filter.Filter;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
@ -25,7 +26,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
*/ */
@Test @Test
public void testCloudform() { public void testCloudform() {
// At the beginning of your upkeep, if you control an artifact, put a 1/1 // At the beginning of your upkeep, if you control an artifact, put a 1/1
// colorless Thopter artifact creature token with flying onto the battlefield. // colorless Thopter artifact creature token with flying onto the battlefield.
// Whenever one or more artifact creatures you control deal combat damage to a player, draw a card. // Whenever one or more artifact creatures you control deal combat damage to a player, draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Thopter Spy Network", 2); // {2}{U}{U} - added to come to 5 enchantments on the battlefield addCard(Zone.BATTLEFIELD, playerA, "Thopter Spy Network", 2); // {2}{U}{U} - added to come to 5 enchantments on the battlefield
@ -35,7 +36,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
// As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in // As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in
// addition to its other types and has base power and base toughness each equal to its converted mana cost. // addition to its other types and has base power and base toughness each equal to its converted mana cost.
addCard(Zone.HAND, playerA, "Starfield of Nyx"); // "{4}{W}" addCard(Zone.HAND, playerA, "Starfield of Nyx"); // "{4}{W}"
// When Cloudform enters the battlefield, it becomes an Aura with enchant creature. // When Cloudform enters the battlefield, it becomes an Aura with enchant creature.
// Manifest the top card of your library and attach Cloudform to it. // Manifest the top card of your library and attach Cloudform to it.
// Enchanted creature has flying and hexproof. // Enchanted creature has flying and hexproof.
addCard(Zone.HAND, playerA, "Cloudform"); // {1}{U}{U} addCard(Zone.HAND, playerA, "Cloudform"); // {1}{U}{U}
@ -51,7 +52,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
assertAllCommandsUsed(); assertAllCommandsUsed();
assertGraveyardCount(playerA, "Thopter Spy Network", 0); assertGraveyardCount(playerA, "Thopter Spy Network", 0);
assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(),
2, 2, Filter.ComparisonScope.All); // the manifested cards 2, 2, Filter.ComparisonScope.All); // the manifested cards
assertPermanentCount(playerA, "Starfield of Nyx", 1); assertPermanentCount(playerA, "Starfield of Nyx", 1);
assertPowerToughness(playerA, "Thopter Spy Network", 4, 4, Filter.ComparisonScope.All); assertPowerToughness(playerA, "Thopter Spy Network", 4, 4, Filter.ComparisonScope.All);
@ -66,7 +67,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
*/ */
@Test @Test
public void testHexproof() { public void testHexproof() {
// At the beginning of your upkeep, if you control an artifact, put a 1/1 colorless // At the beginning of your upkeep, if you control an artifact, put a 1/1 colorless
// Thopter artifact creature token with flying onto the battlefield. // Thopter artifact creature token with flying onto the battlefield.
// Whenever one or more artifact creatures you control deal combat damage to a player, draw a card. // Whenever one or more artifact creatures you control deal combat damage to a player, draw a card.
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5); addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
@ -114,7 +115,7 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN); setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute(); execute();
assertAllCommandsUsed(); assertAllCommandsUsed();
assertPowerToughness(playerA, "Master of the Feast", 3, 3, Filter.ComparisonScope.All); assertPowerToughness(playerA, "Master of the Feast", 3, 3, Filter.ComparisonScope.All);
assertPowerToughness(playerA, "Humility", 4, 4, Filter.ComparisonScope.All); assertPowerToughness(playerA, "Humility", 4, 4, Filter.ComparisonScope.All);
// Humility loses its ability in layer 6. Layer 7 never gets Humility's effect // Humility loses its ability in layer 6. Layer 7 never gets Humility's effect
@ -139,10 +140,9 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
* there. * there.
*/ */
@Test @Test
@Ignore
public void testStarfieldOfNyxAndSongOfTheDryads() { public void testStarfieldOfNyxAndSongOfTheDryads() {
// Nontoken creatures you control get +1/+1 and have vigilance. // Nontoken creatures you control get +1/+1 and have vigilance.
addCard(Zone.BATTLEFIELD, playerA, "Always Watching", 5); addCard(Zone.BATTLEFIELD, playerA, "Always Watching", 5); // Enchantment {1}{W}{W}
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5); addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
// At the beginning of your upkeep, you may return target enchantment card from your graveyard to the battlefield. // At the beginning of your upkeep, you may return target enchantment card from your graveyard to the battlefield.
// As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in // As long as you control five or more enchantments, each other non-Aura enchantment you control is a creature in
@ -157,15 +157,19 @@ public class StarfieldOfNyxTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Song of the Dryads", "Starfield of Nyx"); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Song of the Dryads", "Starfield of Nyx");
setStopAt(2, PhaseStep.BEGIN_COMBAT); setStopAt(2, PhaseStep.BEGIN_COMBAT);
setStrictChooseMode(true);
execute(); execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, "Always Watching", 5); assertPermanentCount(playerA, "Always Watching", 5);
assertPermanentCount(playerB, "Song of the Dryads", 1); assertPermanentCount(playerB, "Song of the Dryads", 1);
assertType("Always Watching", CardType.ENCHANTMENT, true);
assertType("Always Watching", CardType.CREATURE, false);
assertPowerToughness(playerA, "Always Watching", 0, 0, Filter.ComparisonScope.All); assertPowerToughness(playerA, "Always Watching", 0, 0, Filter.ComparisonScope.All);
assertPermanentCount(playerA, "Forest", 1); assertType("Starfield of Nyx", CardType.LAND, SubType.FOREST);
} }
} }

View file

@ -1,5 +1,13 @@
package org.mage.test.serverside.base.impl; package org.mage.test.serverside.base.impl;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import mage.MageObject; import mage.MageObject;
import mage.Mana; import mage.Mana;
import mage.ObjectColor; import mage.ObjectColor;
@ -35,15 +43,6 @@ import org.mage.test.player.TestPlayer;
import org.mage.test.serverside.base.CardTestAPI; import org.mage.test.serverside.base.CardTestAPI;
import org.mage.test.serverside.base.MageTestPlayerBase; import org.mage.test.serverside.base.MageTestPlayerBase;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* API for test initialization and asserting the test results. * API for test initialization and asserting the test results.
* *
@ -274,10 +273,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
} }
Assert.assertFalse("Wrong stop command on " + this.stopOnTurn + " / " + this.stopAtStep + " (" + this.stopAtStep.getIndex() + ")" Assert.assertFalse("Wrong stop command on " + this.stopOnTurn + " / " + this.stopAtStep + " (" + this.stopAtStep.getIndex() + ")"
+ " (found actions after stop on " + maxTurn + " / " + maxPhase + ")", + " (found actions after stop on " + maxTurn + " / " + maxPhase + ")",
(maxTurn > this.stopOnTurn) || (maxTurn == this.stopOnTurn && maxPhase > this.stopAtStep.getIndex())); (maxTurn > this.stopOnTurn) || (maxTurn == this.stopOnTurn && maxPhase > this.stopAtStep.getIndex()));
for (Player player : currentGame.getPlayers().values()) { for (Player player : currentGame.getPlayers().values()) {
TestPlayer testPlayer = (TestPlayer) player; TestPlayer testPlayer = (TestPlayer) player;
currentGame.cheat(player.getId(), getCommands(testPlayer)); currentGame.cheat(player.getId(), getCommands(testPlayer));
@ -326,7 +324,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
// check commands // check commands
private void check(String checkName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) { private void check(String checkName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) {
String res = CHECK_PREFIX + command; String res = CHECK_PREFIX + command;
for (String param : params) { for (String param : params) {
@ -428,7 +425,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
// show commands // show commands
private void show(String showName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) { private void show(String showName, int turnNum, PhaseStep step, TestPlayer player, String command, String... params) {
String res = "show:" + command; String res = "show:" + command;
for (String param : params) { for (String param : params) {
@ -496,8 +492,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
/** /**
* Disable auto-payment from mana pool, you must manually fill pool by activateManaAbility and unlock color by setChoice * Disable auto-payment from mana pool, you must manually fill pool by
* Use it for pay color order testing (e.g. simulate user clicks on mana pool to pay) * activateManaAbility and unlock color by setChoice Use it for pay color
* order testing (e.g. simulate user clicks on mana pool to pay)
* *
* @param player * @param player
*/ */
@ -509,8 +506,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add a card to specified zone of specified player. * Add a card to specified zone of specified player.
* *
* @param gameZone {@link mage.constants.Zone} to add cards to. * @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or * @param player {@link Player} to add cards for. Use either playerA or
* playerB. * playerB.
* @param cardName Card name in string format. * @param cardName Card name in string format.
*/ */
@Override @Override
@ -522,10 +519,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add any amount of cards to specified zone of specified player. * Add any amount of cards to specified zone of specified player.
* *
* @param gameZone {@link mage.constants.Zone} to add cards to. * @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or * @param player {@link Player} to add cards for. Use either playerA or
* playerB. * playerB.
* @param cardName Card name in string format. * @param cardName Card name in string format.
* @param count Amount of cards to be added. * @param count Amount of cards to be added.
*/ */
@Override @Override
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) { public void addCard(Zone gameZone, TestPlayer player, String cardName, int count) {
@ -536,13 +533,13 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Add any amount of cards to specified zone of specified player. * Add any amount of cards to specified zone of specified player.
* *
* @param gameZone {@link mage.constants.Zone} to add cards to. * @param gameZone {@link mage.constants.Zone} to add cards to.
* @param player {@link Player} to add cards for. Use either playerA or * @param player {@link Player} to add cards for. Use either playerA or
* playerB. * playerB.
* @param cardName Card name in string format. * @param cardName Card name in string format.
* @param count Amount of cards to be added. * @param count Amount of cards to be added.
* @param tapped In case gameZone is Battlefield, determines whether * @param tapped In case gameZone is Battlefield, determines whether
* permanent should be tapped. In case gameZone is other than Battlefield, * permanent should be tapped. In case gameZone is other than Battlefield,
* {@link IllegalArgumentException} is thrown * {@link IllegalArgumentException} is thrown
*/ */
@Override @Override
public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) { public void addCard(Zone gameZone, TestPlayer player, String cardName, int count, boolean tapped) {
@ -623,7 +620,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Set player's initial life count. * Set player's initial life count.
* *
* @param player {@link Player} to set life count for. * @param player {@link Player} to set life count for.
* @param life Life count to set. * @param life Life count to set.
*/ */
@Override @Override
public void setLife(TestPlayer player, int life) { public void setLife(TestPlayer player, int life) {
@ -700,7 +697,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert player's life count after test execution. * Assert player's life count after test execution.
* *
* @param player {@link Player} to get life for comparison. * @param player {@link Player} to get life for comparison.
* @param life Expected player's life to compare with. * @param life Expected player's life to compare with.
*/ */
@Override @Override
public void assertLife(Player player, int life) throws AssertionError { public void assertLife(Player player, int life) throws AssertionError {
@ -717,14 +714,14 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* params 3b. all: there is at least one creature with the cardName with the * params 3b. all: there is at least one creature with the cardName with the
* different p\t params * different p\t params
* *
* @param player {@link Player} to get creatures for comparison. * @param player {@link Player} to get creatures for comparison.
* @param cardName Card name to compare with. * @param cardName Card name to compare with.
* @param power Expected power to compare with. * @param power Expected power to compare with.
* @param toughness Expected toughness to compare with. * @param toughness Expected toughness to compare with.
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you * @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you
* want "at least one creature with given name should have specified p\t" * want "at least one creature with given name should have specified p\t"
* Use ALL, if you want "all creature with gived name should have specified * Use ALL, if you want "all creature with gived name should have specified
* p\t" * p\t"
*/ */
@Override @Override
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope) public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
@ -813,9 +810,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param player * @param player
* @param cardName * @param cardName
* @param ability * @param ability
* @param mustHave true if creature should contain ability, false if it should * @param mustHave true if creature should contain ability, false if it
* NOT contain it instead * should NOT contain it instead
* @param count number of permanents with that ability * @param count number of permanents with that ability
* @throws AssertionError * @throws AssertionError
*/ */
public void assertAbility(Player player, String cardName, Ability ability, boolean mustHave, int count) throws AssertionError { public void assertAbility(Player player, String cardName, Ability ability, boolean mustHave, int count) throws AssertionError {
@ -848,7 +845,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert permanent count under player's control. * Assert permanent count under player's control.
* *
* @param player {@link Player} which permanents should be counted. * @param player {@link Player} which permanents should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
@Override @Override
public void assertPermanentCount(Player player, int count) throws AssertionError { public void assertPermanentCount(Player player, int count) throws AssertionError {
@ -864,9 +861,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert permanent count under player's control. * Assert permanent count under player's control.
* *
* @param player {@link Player} which permanents should be counted. * @param player {@link Player} which permanents should be counted.
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
@Override @Override
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError { public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
@ -916,8 +913,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a permanent * Assert counter count on a permanent
* *
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted. * @param type Type of the counter that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertCounterCount(String cardName, CounterType type, int count) throws AssertionError { public void assertCounterCount(String cardName, CounterType type, int count) throws AssertionError {
this.assertCounterCount(null, cardName, type, count); this.assertCounterCount(null, cardName, type, count);
@ -940,8 +937,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a card in exile * Assert counter count on a card in exile
* *
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param type Type of the counter that should be counted. * @param type Type of the counter that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError { public void assertCounterOnExiledCardCount(String cardName, CounterType type, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -964,8 +961,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert counter count on a player * Assert counter count on a player
* *
* @param player The player whos counters should be counted. * @param player The player whos counters should be counted.
* @param type Type of the counter that should be counted. * @param type Type of the counter that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError { public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError {
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ':' + type + ')', count, player.getCounters().getCount(type)); Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ':' + type + ')', count, player.getCounters().getCount(type));
@ -975,7 +972,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type or not * Assert whether a permanent is a specified type or not
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param type A type to test for * @param type A type to test for
* @param mustHave true if creature should have type, false if it should not * @param mustHave true if creature should have type, false if it should not
*/ */
public void assertType(String cardName, CardType type, boolean mustHave) throws AssertionError { public void assertType(String cardName, CardType type, boolean mustHave) throws AssertionError {
@ -991,7 +988,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
Assert.assertNotNull("There is no such permanent on the battlefield, cardName=" + cardName, found); Assert.assertNotNull("There is no such permanent on the battlefield, cardName=" + cardName, found);
Assert.assertTrue("(Battlefield) card type not found (" + cardName + ':' + type + ')', (found.getCardType().contains(type) == mustHave)); Assert.assertTrue("(Battlefield) card type " + (mustHave ? "not " : "")
+ "found (" + cardName + ':' + type + ')', (found.getCardType().contains(type) == mustHave));
} }
@ -999,8 +997,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is a specified type * Assert whether a permanent is a specified type
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param type A type to test for * @param type A type to test for
* @param subType a subtype to test for * @param subType a subtype to test for
*/ */
public void assertType(String cardName, CardType type, SubType subType) throws AssertionError { public void assertType(String cardName, CardType type, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1015,7 +1013,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified type * Assert whether a permanent is not a specified type
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param type A type to test for * @param type A type to test for
*/ */
public void assertNotType(String cardName, CardType type) throws AssertionError { public void assertNotType(String cardName, CardType type) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1027,7 +1025,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is not a specified subtype * Assert whether a permanent is not a specified subtype
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param subType a subtype to test for * @param subType a subtype to test for
*/ */
public void assertNotSubtype(String cardName, SubType subType) throws AssertionError { public void assertNotSubtype(String cardName, SubType subType) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1040,10 +1038,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert permanent color * Assert permanent color
* *
* @param player player to check * @param player player to check
* @param cardName card name on battlefield from player * @param cardName card name on battlefield from player
* @param searchColors colors list with searchable values * @param searchColors colors list with searchable values
* @param mustHave must or not must have that colors * @param mustHave must or not must have that colors
*/ */
public void assertColor(Player player, String cardName, ObjectColor searchColors, boolean mustHave) { public void assertColor(Player player, String cardName, ObjectColor searchColors, boolean mustHave) {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1078,7 +1076,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether a permanent is tapped or not * Assert whether a permanent is tapped or not
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not * @param tapped Whether the permanent is tapped or not
*/ */
public void assertTapped(String cardName, boolean tapped) throws AssertionError { public void assertTapped(String cardName, boolean tapped) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1105,8 +1103,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert whether X permanents of the same name are tapped or not. * Assert whether X permanents of the same name are tapped or not.
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param tapped Whether the permanent is tapped or not * @param tapped Whether the permanent is tapped or not
* @param count The amount of this permanents that should be tapped * @param count The amount of this permanents that should be tapped
*/ */
public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError { public void assertTappedCount(String cardName, boolean tapped, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1128,7 +1126,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert whether a permanent is attacking or not * Assert whether a permanent is attacking or not
* *
* @param cardName Name of the permanent that should be checked. * @param cardName Name of the permanent that should be checked.
* @param attacking Whether the permanent is attacking or not * @param attacking Whether the permanent is attacking or not
*/ */
public void assertAttacking(String cardName, boolean attacking) throws AssertionError { public void assertAttacking(String cardName, boolean attacking) throws AssertionError {
@ -1150,7 +1148,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's hand. * Assert card count in player's hand.
* *
* @param player {@link Player} who's hand should be counted. * @param player {@link Player} who's hand should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertHandCount(Player player, int count) throws AssertionError { public void assertHandCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getHand().size(); int actual = currentGame.getPlayer(player.getId()).getHand().size();
@ -1160,9 +1158,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert card count in player's hand. * Assert card count in player's hand.
* *
* @param player {@link Player} who's hand should be counted. * @param player {@link Player} who's hand should be counted.
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertHandCount(Player player, String cardName, int count) throws AssertionError { public void assertHandCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1182,7 +1180,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
Assert.assertEquals("(Hand) Card counts for card " + cardName + " for " + player.getName() + " are not equal ", count, actual); Assert.assertEquals("(Hand) Card counts for card " + cardName + " for " + player.getName() + " are not equal ", count, actual);
} }
public void assertManaPool(Player player, ManaType color, int amount) { public void assertManaPool(Player player, ManaType color, int amount) {
ManaPool manaPool = currentGame.getPlayer(player.getId()).getManaPool(); ManaPool manaPool = currentGame.getPlayer(player.getId()).getManaPool();
switch (color) { switch (color) {
@ -1211,7 +1208,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in player's graveyard. * Assert card count in player's graveyard.
* *
* @param player {@link Player} who's graveyard should be counted. * @param player {@link Player} who's graveyard should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertGraveyardCount(Player player, int count) throws AssertionError { public void assertGraveyardCount(Player player, int count) throws AssertionError {
int actual = currentGame.getPlayer(player.getId()).getGraveyard().size(); int actual = currentGame.getPlayer(player.getId()).getGraveyard().size();
@ -1222,7 +1219,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert card count in exile. * Assert card count in exile.
* *
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertExileCount(String cardName, int count) throws AssertionError { public void assertExileCount(String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1260,9 +1257,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert card count in player's exile. * Assert card count in player's exile.
* *
* @param owner {@link Player} who's exile should be counted. * @param owner {@link Player} who's exile should be counted.
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertExileCount(Player owner, String cardName, int count) throws AssertionError { public void assertExileCount(Player owner, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1281,9 +1278,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert card count in player's graveyard. * Assert card count in player's graveyard.
* *
* @param player {@link Player} who's graveyard should be counted. * @param player {@link Player} who's graveyard should be counted.
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertGraveyardCount(Player player, String cardName, int count) throws AssertionError { public void assertGraveyardCount(Player player, String cardName, int count) throws AssertionError {
assertAliaseSupportInActivateCommand(cardName, true); assertAliaseSupportInActivateCommand(cardName, true);
@ -1302,7 +1299,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* Assert library card count. * Assert library card count.
* *
* @param player {@link Player} who's library should be counted. * @param player {@link Player} who's library should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertLibraryCount(Player player, int count) throws AssertionError { public void assertLibraryCount(Player player, int count) throws AssertionError {
List<Card> libraryList = player.getLibrary().getCards(currentGame); List<Card> libraryList = player.getLibrary().getCards(currentGame);
@ -1313,9 +1310,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* Assert specific card count in player's library. * Assert specific card count in player's library.
* *
* @param player {@link Player} who's library should be counted. * @param player {@link Player} who's library should be counted.
* @param cardName Name of the cards that should be counted. * @param cardName Name of the cards that should be counted.
* @param count Expected count. * @param count Expected count.
*/ */
public void assertLibraryCount(Player player, String cardName, int count) throws AssertionError { public void assertLibraryCount(Player player, String cardName, int count) throws AssertionError {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1426,8 +1423,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
/** /**
* AI play one PRIORITY with multi game simulations (calcs and play ONE best action, can be called with stack) * AI play one PRIORITY with multi game simulations (calcs and play ONE best
* All choices must be made by AI (e.g. strict mode possible) * action, can be called with stack) All choices must be made by AI (e.g.
* strict mode possible)
*/ */
public void aiPlayPriority(int turnNum, PhaseStep step, TestPlayer player) { public void aiPlayPriority(int turnNum, PhaseStep step, TestPlayer player) {
assertAiPlayAndGameCompatible(player); assertAiPlayAndGameCompatible(player);
@ -1435,8 +1433,9 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
/** /**
* AI play STEP to the end with multi game simulations (calcs and play best actions until step ends, can be called in the middle of the step) * AI play STEP to the end with multi game simulations (calcs and play best
* All choices must be made by AI (e.g. strict mode possible) * actions until step ends, can be called in the middle of the step) All
* choices must be made by AI (e.g. strict mode possible)
*/ */
public void aiPlayStep(int turnNum, PhaseStep step, TestPlayer player) { public void aiPlayStep(int turnNum, PhaseStep step, TestPlayer player) {
assertAiPlayAndGameCompatible(player); assertAiPlayAndGameCompatible(player);
@ -1494,7 +1493,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param player * @param player
* @param cardName * @param cardName
* @param targetName for modes you can add "mode=3" before target name, * @param targetName for modes you can add "mode=3" before target name,
* multiple targets can be seperated by ^, not target marks as TestPlayer.NO_TARGET * 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) { public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
//Assert.assertNotEquals("", cardName); //Assert.assertNotEquals("", cardName);
@ -1517,8 +1517,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step * @param step
* @param player * @param player
* @param cardName * @param cardName
* @param targetName for modal spells add the mode to the name e.g. * @param targetName for modal spells add the mode to the name e.g.
* "mode=2SilvercoatLion^mode3=PillarfieldOx" * "mode=2SilvercoatLion^mode3=PillarfieldOx"
* @param spellOnStack * @param spellOnStack
*/ */
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack) { public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName, String spellOnStack) {
@ -1605,7 +1605,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step * @param step
* @param player * @param player
* @param ability * @param ability
* @param targetName use NO_TARGET if there is no target to set * @param targetName use NO_TARGET if there is no target to set
* @param spellOnStack * @param spellOnStack
*/ */
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) { public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName, String spellOnStack) {
@ -1618,8 +1618,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* @param step * @param step
* @param player * @param player
* @param ability * @param ability
* @param targetName if not target has to be defined use the constant * @param targetName if not target has to be defined use the constant
* NO_TARGET * NO_TARGET
* @param spellOnStack * @param spellOnStack
* @param clause * @param clause
*/ */
@ -1705,10 +1705,10 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* *
* @param player * @param player
* @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to * @param choice starting with "1" for mode 1, "2" for mode 2 and so on (to
* set multiple modes call the command multiple times). If a spell mode can * set multiple modes call the command multiple times). If a spell mode can
* be used only once like Demonic Pact, the value has to be set to the * be used only once like Demonic Pact, the value has to be set to the
* number of the remaining modes (e.g. if only 2 are left the number need to * number of the remaining modes (e.g. if only 2 are left the number need to
* be 1 or 2). * be 1 or 2).
*/ */
public void setModeChoice(TestPlayer player, String choice) { public void setModeChoice(TestPlayer player, String choice) {
player.addModeChoice(choice); player.addModeChoice(choice);
@ -1719,12 +1719,12 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
* *
* @param player * @param player
* @param target you can add multiple targets by separating them by the "^" * @param target you can add multiple targets by separating them by the "^"
* character e.g. "creatureName1^creatureName2" you can qualify the target * character e.g. "creatureName1^creatureName2" you can qualify the target
* additional by setcode e.g. "creatureName-M15" you can add [no copy] to * additional by setcode e.g. "creatureName-M15" you can add [no copy] to
* the end of the target name to prohibit targets that are copied you can * the end of the target name to prohibit targets that are copied you can
* add [only copy] to the end of the target name to allow only targets that * add [only copy] to the end of the target name to allow only targets that
* are copies. For modal spells use a prefix with the mode number: * are copies. For modal spells use a prefix with the mode number:
* mode=1Lightning Bolt^mode=2Silvercoat Lion * mode=1Lightning Bolt^mode=2Silvercoat Lion
*/ */
// TODO: mode options doesn't work here (see BrutalExpulsionTest) // TODO: mode options doesn't work here (see BrutalExpulsionTest)
public void addTarget(TestPlayer player, String target) { public void addTarget(TestPlayer player, String target) {
@ -1743,7 +1743,8 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
/** /**
* @param player * @param player
* @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop "up two xxx" selection * @param target use TestPlayer.TARGET_SKIP to 0 targets selects or to stop
* "up two xxx" selection
* @param amount * @param amount
*/ */
public void addTargetAmount(TestPlayer player, String target, int amount) { public void addTargetAmount(TestPlayer player, String target, int amount) {
@ -1758,7 +1759,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
addTargetAmount(player, "targetPlayer=" + targetPlayer.getName(), amount); addTargetAmount(player, "targetPlayer=" + targetPlayer.getName(), amount);
} }
public void addTargetAmount(TestPlayer player, String target) { public void addTargetAmount(TestPlayer player, String target) {
Assert.assertTrue("Only skip command allows here", target.equals(TestPlayer.TARGET_SKIP)); Assert.assertTrue("Only skip command allows here", target.equals(TestPlayer.TARGET_SKIP));
addTargetAmount(player, target, 0); addTargetAmount(player, target, 0);
@ -1793,10 +1793,18 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
} }
public void waitStackResolved(int turnNum, PhaseStep step) { public void waitStackResolved(int turnNum, PhaseStep step) {
if (playerA != null) waitStackResolved(turnNum, step, playerA); if (playerA != null) {
if (playerB != null) waitStackResolved(turnNum, step, playerB); waitStackResolved(turnNum, step, playerA);
if (playerC != null) waitStackResolved(turnNum, step, playerC); }
if (playerD != null) waitStackResolved(turnNum, step, playerD); if (playerB != null) {
waitStackResolved(turnNum, step, playerB);
}
if (playerC != null) {
waitStackResolved(turnNum, step, playerC);
}
if (playerD != null) {
waitStackResolved(turnNum, step, playerD);
}
} }
private void assertAliaseSupportInActivateCommand(String targetName, boolean methodSupportAliases) { private void assertAliaseSupportInActivateCommand(String targetName, boolean methodSupportAliases) {