* 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;
@ -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;
@ -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;
@ -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.
* *
@ -277,7 +276,6 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
+ " (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
*/ */
@ -813,8 +810,8 @@ 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
*/ */
@ -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));
} }
@ -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) {
@ -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);
@ -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) {