forked from External/mage
implement [M3C] Planar Nexus [MH3] Omo, Queen of Vesuva and [UNF] Nearby Planet ; introduce AllNonbasicLandTypes status (#12203)
This commit is contained in:
parent
3e18b58cac
commit
08c7d2ab8f
19 changed files with 659 additions and 5 deletions
75
Mage.Sets/src/mage/cards/n/NearbyPlanet.java
Normal file
75
Mage.Sets/src/mage/cards/n/NearbyPlanet.java
Normal file
|
|
@ -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 <i>(This card is every land type, including Plains, Island, Swamp, " +
|
||||
"Mountain, Forest, Desert, Gate, Lair, Locus, and all those Urza's ones.)</i>.";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
161
Mage.Sets/src/mage/cards/o/OmoQueenOfVesuva.java
Normal file
161
Mage.Sets/src/mage/cards/o/OmoQueenOfVesuva.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
75
Mage.Sets/src/mage/cards/p/PlanarNexus.java
Normal file
75
Mage.Sets/src/mage/cards/p/PlanarNexus.java
Normal file
|
|
@ -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. " +
|
||||
"<i>(Nonbasic land types include Cave, Desert, Gate, Lair, " +
|
||||
"Locus, Mine, Power-Plant, Sphere, Tower, and Urza's.)</i>.";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -471,6 +471,9 @@ public interface MageObject extends MageItem, Serializable, Copyable<MageObject>
|
|||
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<MageObject>
|
|||
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<MageObject>
|
|||
|
||||
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<MageObject>
|
|||
*/
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public enum CounterType {
|
|||
ENERGY("energy"),
|
||||
ENLIGHTENED("enlightened"),
|
||||
EON("eon"),
|
||||
EVERYTHING("everything"),
|
||||
EXALTED("exalted"),
|
||||
EXPERIENCE("experience"),
|
||||
EYEBALL("eyeball"),
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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<UUID> getAttachments() {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import java.util.Collections;
|
|||
public class SubTypes extends ArrayList<SubType> {
|
||||
|
||||
private boolean isAllCreatureTypes = false;
|
||||
private boolean isAllNonbasicLandTypes = false;
|
||||
|
||||
public SubTypes(SubType... subTypes) {
|
||||
super();
|
||||
|
|
@ -18,6 +19,7 @@ public class SubTypes extends ArrayList<SubType> {
|
|||
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<SubType> {
|
|||
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<SubType> {
|
|||
public boolean isAllCreatureTypes() {
|
||||
return isAllCreatureTypes;
|
||||
}
|
||||
|
||||
public void setIsAllNonbasicLandTypes(boolean allNonbasicLandTypes) {
|
||||
isAllNonbasicLandTypes = allNonbasicLandTypes;
|
||||
}
|
||||
|
||||
public boolean isAllNonbasicLandTypes() {
|
||||
return isAllNonbasicLandTypes;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue