diff --git a/Mage.Sets/src/mage/cards/n/NearbyPlanet.java b/Mage.Sets/src/mage/cards/n/NearbyPlanet.java
new file mode 100644
index 00000000000..b50a41cb84c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/n/NearbyPlanet.java
@@ -0,0 +1,75 @@
+package mage.cards.n;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldTappedAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class NearbyPlanet extends CardImpl {
+
+ public NearbyPlanet(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Rangeling
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new NearbyPlanetEffect()));
+
+ // Nearby Planet enters the battlefield tapped.
+ this.addAbility(new EntersBattlefieldTappedAbility());
+
+ // When Nearby Planet enters the battlefield, sacrifice it unless you pay {1}.
+ this.addAbility(new EntersBattlefieldTriggeredAbility(
+ new SacrificeSourceUnlessPaysEffect(new GenericManaCost(1)).setText("sacrifice it unless you pay {1}")
+ ));
+ }
+
+ private NearbyPlanet(final NearbyPlanet card) {
+ super(card);
+ }
+
+ @Override
+ public NearbyPlanet copy() {
+ return new NearbyPlanet(this);
+ }
+}
+
+class NearbyPlanetEffect extends ContinuousEffectImpl {
+
+ NearbyPlanetEffect() {
+ super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
+ staticText = "Rangeling (This card is every land type, including Plains, Island, Swamp, " +
+ "Mountain, Forest, Desert, Gate, Lair, Locus, and all those Urza's ones.).";
+ }
+
+ private NearbyPlanetEffect(final NearbyPlanetEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public NearbyPlanetEffect copy() {
+ return new NearbyPlanetEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ MageObject sourceObject = game.getObject(source);
+ if (sourceObject == null) {
+ return false;
+ }
+ sourceObject.addSubType(game, SubType.PLAINS, SubType.ISLAND, SubType.SWAMP, SubType.MOUNTAIN, SubType.FOREST);
+ sourceObject.setIsAllNonbasicLandTypes(game, true);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/o/OmoQueenOfVesuva.java b/Mage.Sets/src/mage/cards/o/OmoQueenOfVesuva.java
new file mode 100644
index 00000000000..5aa0161315d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/o/OmoQueenOfVesuva.java
@@ -0,0 +1,161 @@
+package mage.cards.o;
+
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.mana.*;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.counters.CounterType;
+import mage.filter.FilterPermanent;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.common.FilterNonlandPermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.common.TargetLandPermanent;
+import mage.target.targetpointer.EachTargetPointer;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class OmoQueenOfVesuva extends CardImpl {
+
+ public OmoQueenOfVesuva(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G/U}");
+
+ this.supertype.add(SuperType.LEGENDARY);
+ this.subtype.add(SubType.SHAPESHIFTER);
+ this.subtype.add(SubType.NOBLE);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(5);
+
+ // Whenever Omo, Queen of Vesuva enters the battlefield or attacks, put an everything counter on each of up to one target land and up to one target creature.
+ Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(
+ new AddCountersTargetEffect(CounterType.EVERYTHING.createInstance())
+ .setTargetPointer(new EachTargetPointer())
+ .setText("put an everything counter on each of up to one target land and up to one target creature")
+ );
+ ability.addTarget(new TargetLandPermanent(0, 1));
+ ability.addTarget(new TargetCreaturePermanent(0, 1));
+ this.addAbility(ability);
+
+ // Each land with an everything counter on it is every land type in addition to its other types.
+ this.addAbility(new SimpleStaticAbility(new OmoQueenOfVesuvaLandEffect()));
+
+ // Each nonland creature with an everything counter on it is every creature type.
+ this.addAbility(new SimpleStaticAbility(new OmoQueenOfVesuvaCreatureEffect()));
+ }
+
+ private OmoQueenOfVesuva(final OmoQueenOfVesuva card) {
+ super(card);
+ }
+
+ @Override
+ public OmoQueenOfVesuva copy() {
+ return new OmoQueenOfVesuva(this);
+ }
+}
+
+class OmoQueenOfVesuvaLandEffect extends ContinuousEffectImpl {
+
+ private static final Ability[] basicManaAbilities = {
+ new WhiteManaAbility(),
+ new BlueManaAbility(),
+ new BlackManaAbility(),
+ new RedManaAbility(),
+ new GreenManaAbility()
+ };
+ private static final FilterPermanent filter = new FilterLandPermanent();
+
+ static {
+ filter.add(CounterType.EVERYTHING.getPredicate());
+ }
+
+ public OmoQueenOfVesuvaLandEffect() {
+ super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
+ this.staticText = "each land with an everything counter on it is every land type in addition to its other types";
+ dependencyTypes.add(DependencyType.BecomeMountain);
+ dependencyTypes.add(DependencyType.BecomeForest);
+ dependencyTypes.add(DependencyType.BecomeSwamp);
+ dependencyTypes.add(DependencyType.BecomeIsland);
+ dependencyTypes.add(DependencyType.BecomePlains);
+ }
+
+ private OmoQueenOfVesuvaLandEffect(final OmoQueenOfVesuvaLandEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OmoQueenOfVesuvaLandEffect copy() {
+ return new OmoQueenOfVesuvaLandEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
+ permanent.addSubType(
+ game,
+ SubType.PLAINS,
+ SubType.ISLAND,
+ SubType.SWAMP,
+ SubType.MOUNTAIN,
+ SubType.FOREST
+ );
+ permanent.setIsAllNonbasicLandTypes(game, true);
+ // Optimization: Remove basic mana abilities since they are redundant with AnyColorManaAbility
+ // and keeping them will only produce too many combinations inside ManaOptions
+ for (Ability basicManaAbility : basicManaAbilities) {
+ if (permanent.getAbilities(game).containsRule(basicManaAbility)) {
+ permanent.removeAbility(basicManaAbility, source.getSourceId(), game);
+ }
+ }
+ // Add the {T}: Add one mana of any color ability
+ // This is functionally equivalent to having five "{T}: Add {COLOR}" for each COLOR in {W}{U}{B}{R}{G}
+ AnyColorManaAbility ability = new AnyColorManaAbility();
+ if (!permanent.getAbilities(game).containsRule(ability)) {
+ permanent.addAbility(ability, source.getSourceId(), game);
+ }
+ }
+ return true;
+ }
+}
+
+class OmoQueenOfVesuvaCreatureEffect extends ContinuousEffectImpl {
+
+ private static final FilterPermanent filter = new FilterNonlandPermanent();
+
+ static {
+ filter.add(CardType.CREATURE.getPredicate());
+ filter.add(CounterType.EVERYTHING.getPredicate());
+ }
+
+ public OmoQueenOfVesuvaCreatureEffect() {
+ super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
+ this.staticText = "each nonland creature with an everything counter on it is every creature type";
+ dependencyTypes.add(DependencyType.AddingCreatureType);
+ }
+
+ private OmoQueenOfVesuvaCreatureEffect(final OmoQueenOfVesuvaCreatureEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public OmoQueenOfVesuvaCreatureEffect copy() {
+ return new OmoQueenOfVesuvaCreatureEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) {
+ permanent.setIsAllCreatureTypes(game, true);
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/PlanarNexus.java b/Mage.Sets/src/mage/cards/p/PlanarNexus.java
new file mode 100644
index 00000000000..c4dcff83f6c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PlanarNexus.java
@@ -0,0 +1,75 @@
+package mage.cards.p;
+
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.abilities.mana.AnyColorManaAbility;
+import mage.abilities.mana.ColorlessManaAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ */
+public final class PlanarNexus extends CardImpl {
+
+ public PlanarNexus(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
+
+ // Planar Nexus is every nonbasic land type.
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new PlanarNexusEffect()));
+
+ // {T}: Add {C}.
+ this.addAbility(new ColorlessManaAbility());
+
+ // {1}, {T}: Add one mana of any color.
+ Ability ability = new AnyColorManaAbility(new GenericManaCost(1));
+ ability.addCost(new TapSourceCost());
+ this.addAbility(ability);
+ }
+
+ private PlanarNexus(final PlanarNexus card) {
+ super(card);
+ }
+
+ @Override
+ public PlanarNexus copy() {
+ return new PlanarNexus(this);
+ }
+}
+
+class PlanarNexusEffect extends ContinuousEffectImpl {
+
+ PlanarNexusEffect() {
+ super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
+ staticText = "{this} is every nonbasic land type. " +
+ "(Nonbasic land types include Cave, Desert, Gate, Lair, " +
+ "Locus, Mine, Power-Plant, Sphere, Tower, and Urza's.).";
+ }
+
+ private PlanarNexusEffect(final PlanarNexusEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PlanarNexusEffect copy() {
+ return new PlanarNexusEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ MageObject sourceObject = game.getObject(source);
+ if (sourceObject == null) {
+ return false;
+ }
+ sourceObject.setIsAllNonbasicLandTypes(game, true);
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java b/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java
index 92ccb83455a..22b40700460 100644
--- a/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java
+++ b/Mage.Sets/src/mage/sets/ModernHorizons3Commander.java
@@ -196,9 +196,11 @@ public final class ModernHorizons3Commander extends ExpansionSet {
cards.add(new SetCardInfo("Nissa, Steward of Elements", 270, Rarity.MYTHIC, mage.cards.n.NissaStewardOfElements.class));
cards.add(new SetCardInfo("Oblivion Sower", 158, Rarity.MYTHIC, mage.cards.o.OblivionSower.class));
cards.add(new SetCardInfo("Oblivion Stone", 303, Rarity.RARE, mage.cards.o.OblivionStone.class));
+ cards.add(new SetCardInfo("Omo, Queen of Vesuva", 2, Rarity.MYTHIC, mage.cards.o.OmoQueenOfVesuva.class));
cards.add(new SetCardInfo("Opal Palace", 361, Rarity.COMMON, mage.cards.o.OpalPalace.class));
cards.add(new SetCardInfo("Overflowing Basin", 362, Rarity.RARE, mage.cards.o.OverflowingBasin.class));
cards.add(new SetCardInfo("Path of Ancestry", 363, Rarity.COMMON, mage.cards.p.PathOfAncestry.class));
+ cards.add(new SetCardInfo("Planar Nexus", 80, Rarity.RARE, mage.cards.p.PlanarNexus.class));
cards.add(new SetCardInfo("Poison Dart Frog", 238, Rarity.COMMON, mage.cards.p.PoisonDartFrog.class));
cards.add(new SetCardInfo("Polygoyf", 65, Rarity.RARE, mage.cards.p.Polygoyf.class));
cards.add(new SetCardInfo("Pongify", 190, Rarity.UNCOMMON, mage.cards.p.Pongify.class));
diff --git a/Mage.Sets/src/mage/sets/Unfinity.java b/Mage.Sets/src/mage/sets/Unfinity.java
index 292d30d4bda..86bf7616201 100644
--- a/Mage.Sets/src/mage/sets/Unfinity.java
+++ b/Mage.Sets/src/mage/sets/Unfinity.java
@@ -42,6 +42,7 @@ public final class Unfinity extends ExpansionSet {
cards.add(new SetCardInfo("Monoxa, Midway Manager", 173, Rarity.UNCOMMON, mage.cards.m.MonoxaMidwayManager.class));
cards.add(new SetCardInfo("Mountain", 238, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_UST_VARIOUS));
cards.add(new SetCardInfo("Mountain", 243, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_UST_VARIOUS));
+ cards.add(new SetCardInfo("Nearby Planet", 198, Rarity.COMMON, mage.cards.n.NearbyPlanet.class));
cards.add(new SetCardInfo("Non-Human Cannonball", 115, Rarity.COMMON, mage.cards.n.NonHumanCannonball.class));
cards.add(new SetCardInfo("One-Clown Band", 117, Rarity.COMMON, mage.cards.o.OneClownBand.class));
cards.add(new SetCardInfo("Overgrown Tomb", 284, Rarity.RARE, mage.cards.o.OvergrownTomb.class));
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/OmoQueenOfVesuvaTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/OmoQueenOfVesuvaTest.java
new file mode 100644
index 00000000000..f75c523bb81
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/OmoQueenOfVesuvaTest.java
@@ -0,0 +1,89 @@
+package org.mage.test.cards.single.m3c;
+
+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 Susucr
+ */
+public class OmoQueenOfVesuvaTest extends CardTestPlayerBase {
+
+ /**
+ * {@link mage.cards.o.OmoQueenOfVesuva Omo, Queen of Vesuva} {2}{G/U}
+ * Legendary Creature — Shapeshifter Noble
+ * Whenever Omo, Queen of Vesuva enters the battlefield or attacks, put an everything counter on each of up to one target land and up to one target creature.
+ * Each land with an everything counter on it is every land type in addition to its other types.
+ * Each nonland creature with an everything counter on it is every creature type.
+ * 1/5
+ */
+ private static final String omo = "Omo, Queen of Vesuva";
+
+ @Test
+ public void test_TronLand() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Urza's Tower");
+ addCard(Zone.HAND, playerA, omo);
+ addCard(Zone.HAND, playerA, "Abzan Banner");
+
+ activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 3);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, omo, true);
+ addTarget(playerA, "Forest");
+ addTarget(playerA, TestPlayer.TARGET_SKIP);
+
+ // Urza's Tower makes {3} mana
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Abzan Banner");
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, "Abzan Banner", 1);
+ }
+
+ @Test
+ public void test_IsForest() {
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Coiling Woodworm", 1); // Coiling Woodworm’s power is equal to the number of Forests on the battlefield.
+ addCard(Zone.HAND, playerA, omo);
+ addCard(Zone.HAND, playerA, "Llanowar Elves");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, omo);
+ addTarget(playerA, "Island");
+ addTarget(playerA, TestPlayer.TARGET_SKIP);
+
+ setChoice(playerA, "Green"); // mana color to cast Llanowar Elves
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Llanowar Elves");
+
+ setStrictChooseMode(true);
+ setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPowerToughness(playerA, "Coiling Woodworm", 1, 1);
+ assertPermanentCount(playerA, "Llanowar Elves", 1);
+ }
+
+ @Test
+ public void test_EveryCreatureSubType() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Coiling Woodworm", 1); // Coiling Woodworm’s power is equal to the number of Forests on the battlefield.
+ addCard(Zone.BATTLEFIELD, playerA, "Imperious Perfect", 1); // Other Elves you control get +1/+1.
+ addCard(Zone.HAND, playerA, omo);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, omo, true);
+ addTarget(playerA, "Island");
+ addTarget(playerA, "Coiling Woodworm");
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertCounterCount(playerA, "Coiling Woodworm", CounterType.EVERYTHING, 1);
+ assertPowerToughness(playerA, "Coiling Woodworm", 2, 2); // 1 Forest, and is an Elf
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PlanarNexusTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PlanarNexusTest.java
new file mode 100644
index 00000000000..10987c86e34
--- /dev/null
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/m3c/PlanarNexusTest.java
@@ -0,0 +1,112 @@
+package org.mage.test.cards.single.m3c;
+
+import mage.abilities.keyword.TrampleAbility;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author TheElk801
+ */
+public class PlanarNexusTest extends CardTestPlayerBase {
+
+ private static final String nexus = "Planar Nexus";
+ private static final String cloudpost = "Cloudpost";
+ private static final String glimmerpost = "Glimmerpost";
+ private static final String golem = "Stone Golem";
+
+ @Test
+ public void testLocus() {
+ addCard(Zone.BATTLEFIELD, playerA, nexus);
+ addCard(Zone.BATTLEFIELD, playerA, cloudpost);
+ addCard(Zone.HAND, playerA, glimmerpost);
+ addCard(Zone.HAND, playerA, golem);
+
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, glimmerpost);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertLife(playerA, 20 + 3);
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, golem);
+ setStopAt(3, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, golem, 1);
+ }
+
+ private static final String tower = "Urza's Tower";
+ private static final String sentinel = "Gilded Sentinel";
+
+ @Test
+ public void testTronLand() {
+ addCard(Zone.BATTLEFIELD, playerA, nexus);
+ addCard(Zone.BATTLEFIELD, playerA, tower);
+ addCard(Zone.HAND, playerA, sentinel);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sentinel);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertPermanentCount(playerA, sentinel, 1);
+ }
+
+ private static final String seas = "Spreading Seas";
+
+ @Test
+ public void testSpreadingSeas() {
+ addCard(Zone.BATTLEFIELD, playerA, "Island");
+ addCard(Zone.BATTLEFIELD, playerA, nexus);
+ addCard(Zone.HAND, playerA, seas);
+ addCard(Zone.HAND, playerA, glimmerpost);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, seas, nexus);
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, glimmerpost);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertLife(playerA, 20 + 1);
+ }
+
+ private static final String vine = "Gatecreeper Vine";
+
+ @Test
+ public void testGateSearch() {
+ addCard(Zone.LIBRARY, playerA, nexus);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.HAND, playerA, vine);
+
+ setChoice(playerA, true);
+ addTarget(playerA, nexus);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, vine);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertHandCount(playerA, nexus, 1);
+ }
+
+ private static final String naga = "Sidewinder Naga";
+
+ @Test
+ public void testDesertGraveyard() {
+ addCard(Zone.GRAVEYARD, playerA, nexus);
+ addCard(Zone.BATTLEFIELD, playerA, naga);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertPowerToughness(playerA, naga, 3 + 1, 2);
+ assertAbility(playerA, naga, TrampleAbility.getInstance(), true);
+ }
+}
diff --git a/Mage/src/main/java/mage/MageObject.java b/Mage/src/main/java/mage/MageObject.java
index ce337272aaa..c5b498ae270 100644
--- a/Mage/src/main/java/mage/MageObject.java
+++ b/Mage/src/main/java/mage/MageObject.java
@@ -471,6 +471,9 @@ public interface MageObject extends MageItem, Serializable, Copyable
if (subTypeSet == SubTypeSet.CreatureType || subTypeSet == null) {
this.setIsAllCreatureTypes(game, mageObject.isAllCreatureTypes(game));
}
+ if (subTypeSet == SubTypeSet.NonBasicLandType || subTypeSet == null) {
+ this.setIsAllNonbasicLandTypes(game, mageObject.isAllNonbasicLandTypes(game));
+ }
for (SubType subType : mageObject.getSubtype(game)) {
if (subType.getSubTypeSet() == subTypeSet || subTypeSet == null) {
this.addSubType(game, subType);
@@ -485,10 +488,12 @@ public interface MageObject extends MageItem, Serializable, Copyable
default void removeAllSubTypes(Game game, SubTypeSet subTypeSet) {
if (subTypeSet == null) {
setIsAllCreatureTypes(game, false);
+ setIsAllNonbasicLandTypes(game, false);
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().clear();
} else if (subTypeSet == SubTypeSet.CreatureType) {
removeAllCreatureTypes(game);
} else if (subTypeSet == SubTypeSet.NonBasicLandType) {
+ setIsAllNonbasicLandTypes(game, false);
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().removeAll(SubType.getLandTypes());
} else {
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().removeAll(SubType.getBySubTypeSet(subTypeSet));
@@ -497,11 +502,13 @@ public interface MageObject extends MageItem, Serializable, Copyable
default void retainAllArtifactSubTypes(Game game) {
setIsAllCreatureTypes(game, false);
+ setIsAllNonbasicLandTypes(game, false);
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().retainAll(SubType.getArtifactTypes());
}
default void retainAllEnchantmentSubTypes(Game game) {
setIsAllCreatureTypes(game, false);
+ setIsAllNonbasicLandTypes(game, false);
game.getState().getCreateMageObjectAttribute(this, game).getSubtype().retainAll(SubType.getEnchantmentTypes());
}
@@ -603,5 +610,17 @@ public interface MageObject extends MageItem, Serializable, Copyable
*/
void setIsAllCreatureTypes(Game game, boolean value);
+ boolean isAllNonbasicLandTypes(Game game);
+
+ void setIsAllNonbasicLandTypes(boolean value);
+
+ /**
+ * Change all nonbasic land type mark temporary, for continuous effects only
+ *
+ * @param game
+ * @param value
+ */
+ void setIsAllNonbasicLandTypes(Game game, boolean value);
+
void removePTCDA();
}
diff --git a/Mage/src/main/java/mage/MageObjectImpl.java b/Mage/src/main/java/mage/MageObjectImpl.java
index 0a2606d220b..02d88de6f35 100644
--- a/Mage/src/main/java/mage/MageObjectImpl.java
+++ b/Mage/src/main/java/mage/MageObjectImpl.java
@@ -323,10 +323,9 @@ public abstract class MageObjectImpl implements MageObject {
if (value == null) {
return false;
}
- if (value.getSubTypeSet() == SubTypeSet.CreatureType && isAllCreatureTypes(game)) {
- return true;
- }
- return getSubtype(game).contains(value);
+ return value.getSubTypeSet() == SubTypeSet.CreatureType && isAllCreatureTypes(game)
+ || value.getSubTypeSet() == SubTypeSet.NonBasicLandType && isAllNonbasicLandTypes(game)
+ || getSubtype(game).contains(value);
}
@Override
@@ -375,6 +374,21 @@ public abstract class MageObjectImpl implements MageObject {
this.getSubtype(game).setIsAllCreatureTypes(value && (this.isTribal(game) || this.isCreature(game)));
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return this.getSubtype(game).isAllNonbasicLandTypes();
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ this.getSubtype().setIsAllNonbasicLandTypes(value && this.isLand());
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ this.getSubtype(game).setIsAllNonbasicLandTypes(value && this.isLand(game));
+ }
+
/**
* Remove power/toughness character defining abilities
*/
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java
index dd57998ef35..755024a0555 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BecomesEnchantmentSourceEffect.java
@@ -43,7 +43,6 @@ public class BecomesEnchantmentSourceEffect extends ContinuousEffectImpl {
permanent.removeAllCardTypes(game);
permanent.addCardType(game, CardType.ENCHANTMENT);
permanent.retainAllEnchantmentSubTypes(game);
- permanent.setIsAllCreatureTypes(game, false);
return true;
}
}
diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java
index dca4c78e6bd..429ffd8e82e 100644
--- a/Mage/src/main/java/mage/counters/CounterType.java
+++ b/Mage/src/main/java/mage/counters/CounterType.java
@@ -71,6 +71,7 @@ public enum CounterType {
ENERGY("energy"),
ENLIGHTENED("enlightened"),
EON("eon"),
+ EVERYTHING("everything"),
EXALTED("exalted"),
EXPERIENCE("experience"),
EYEBALL("eyeball"),
diff --git a/Mage/src/main/java/mage/designations/Designation.java b/Mage/src/main/java/mage/designations/Designation.java
index edab643575c..cb76e274bc0 100644
--- a/Mage/src/main/java/mage/designations/Designation.java
+++ b/Mage/src/main/java/mage/designations/Designation.java
@@ -181,6 +181,19 @@ public abstract class Designation extends MageObjectImpl {
public void setIsAllCreatureTypes(boolean value) {
}
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ }
+
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return false;
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ }
+
@Override
public void setIsAllCreatureTypes(Game game, boolean value) {
}
diff --git a/Mage/src/main/java/mage/game/command/Commander.java b/Mage/src/main/java/mage/game/command/Commander.java
index a124394f927..7ff69e6101d 100644
--- a/Mage/src/main/java/mage/game/command/Commander.java
+++ b/Mage/src/main/java/mage/game/command/Commander.java
@@ -316,6 +316,21 @@ public class Commander extends CommandObjectImpl {
sourceObject.setIsAllCreatureTypes(game, value);
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return sourceObject.isAllNonbasicLandTypes(game);
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ sourceObject.setIsAllNonbasicLandTypes(value);
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ sourceObject.setIsAllNonbasicLandTypes(game, value);
+ }
+
@Override
public void removePTCDA() {
}
diff --git a/Mage/src/main/java/mage/game/command/Dungeon.java b/Mage/src/main/java/mage/game/command/Dungeon.java
index 2b1e65b422c..adf15b5b8f4 100644
--- a/Mage/src/main/java/mage/game/command/Dungeon.java
+++ b/Mage/src/main/java/mage/game/command/Dungeon.java
@@ -331,6 +331,19 @@ public class Dungeon extends CommandObjectImpl {
public void setIsAllCreatureTypes(Game game, boolean value) {
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return false;
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ }
+
public void discardEffects() {
for (Ability ability : abilites) {
for (Effect effect : ability.getEffects()) {
diff --git a/Mage/src/main/java/mage/game/command/Emblem.java b/Mage/src/main/java/mage/game/command/Emblem.java
index 7cb934200a9..570d030d1be 100644
--- a/Mage/src/main/java/mage/game/command/Emblem.java
+++ b/Mage/src/main/java/mage/game/command/Emblem.java
@@ -246,6 +246,19 @@ public abstract class Emblem extends CommandObjectImpl {
public void setIsAllCreatureTypes(Game game, boolean value) {
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return false;
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ }
+
public void discardEffects() {
for (Ability ability : abilites) {
for (Effect effect : ability.getEffects()) {
diff --git a/Mage/src/main/java/mage/game/command/Plane.java b/Mage/src/main/java/mage/game/command/Plane.java
index 9ee4394ebd8..4e48daaf7cd 100644
--- a/Mage/src/main/java/mage/game/command/Plane.java
+++ b/Mage/src/main/java/mage/game/command/Plane.java
@@ -268,6 +268,19 @@ public abstract class Plane extends CommandObjectImpl {
public void setIsAllCreatureTypes(Game game, boolean value) {
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return false;
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ }
+
public void discardEffects() {
for (Ability ability : abilites) {
for (Effect effect : ability.getEffects()) {
diff --git a/Mage/src/main/java/mage/game/stack/Spell.java b/Mage/src/main/java/mage/game/stack/Spell.java
index d3cb54c8c4a..56f7c5cc3fc 100644
--- a/Mage/src/main/java/mage/game/stack/Spell.java
+++ b/Mage/src/main/java/mage/game/stack/Spell.java
@@ -1181,6 +1181,21 @@ public class Spell extends StackObjectImpl implements Card {
card.setIsAllCreatureTypes(game, value);
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return card.isAllNonbasicLandTypes(game);
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ card.setIsAllNonbasicLandTypes(value);
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ card.setIsAllNonbasicLandTypes(game, value);
+ }
+
@Override
public List getAttachments() {
throw new UnsupportedOperationException("Not supported.");
diff --git a/Mage/src/main/java/mage/game/stack/StackAbility.java b/Mage/src/main/java/mage/game/stack/StackAbility.java
index 67a357a529d..dedc8115a29 100644
--- a/Mage/src/main/java/mage/game/stack/StackAbility.java
+++ b/Mage/src/main/java/mage/game/stack/StackAbility.java
@@ -740,6 +740,19 @@ public class StackAbility extends StackObjectImpl implements Ability {
public void setIsAllCreatureTypes(Game game, boolean value) {
}
+ @Override
+ public boolean isAllNonbasicLandTypes(Game game) {
+ return false;
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(boolean value) {
+ }
+
+ @Override
+ public void setIsAllNonbasicLandTypes(Game game, boolean value) {
+ }
+
@Override
public StackAbility setTargetAdjuster(TargetAdjuster targetAdjuster) {
this.targetAdjuster = targetAdjuster;
diff --git a/Mage/src/main/java/mage/util/SubTypes.java b/Mage/src/main/java/mage/util/SubTypes.java
index 501595b7481..79caea31158 100644
--- a/Mage/src/main/java/mage/util/SubTypes.java
+++ b/Mage/src/main/java/mage/util/SubTypes.java
@@ -9,6 +9,7 @@ import java.util.Collections;
public class SubTypes extends ArrayList {
private boolean isAllCreatureTypes = false;
+ private boolean isAllNonbasicLandTypes = false;
public SubTypes(SubType... subTypes) {
super();
@@ -18,6 +19,7 @@ public class SubTypes extends ArrayList {
protected SubTypes(final SubTypes list) {
this.addAll(list);
this.isAllCreatureTypes = list.isAllCreatureTypes;
+ this.isAllNonbasicLandTypes = list.isAllNonbasicLandTypes;
}
public SubTypes copy() {
@@ -32,6 +34,7 @@ public class SubTypes extends ArrayList {
this.clear();
this.addAll(subtypes);
this.isAllCreatureTypes = subtypes.isAllCreatureTypes;
+ this.isAllNonbasicLandTypes = subtypes.isAllNonbasicLandTypes;
}
public boolean removeAll(SubType... subTypes) {
@@ -45,4 +48,12 @@ public class SubTypes extends ArrayList {
public boolean isAllCreatureTypes() {
return isAllCreatureTypes;
}
+
+ public void setIsAllNonbasicLandTypes(boolean allNonbasicLandTypes) {
+ isAllNonbasicLandTypes = allNonbasicLandTypes;
+ }
+
+ public boolean isAllNonbasicLandTypes() {
+ return isAllNonbasicLandTypes;
+ }
}