diff --git a/Mage.Sets/src/mage/cards/g/GlimpseTheCosmos.java b/Mage.Sets/src/mage/cards/g/GlimpseTheCosmos.java
index 79f2b118f0..e293a529f2 100644
--- a/Mage.Sets/src/mage/cards/g/GlimpseTheCosmos.java
+++ b/Mage.Sets/src/mage/cards/g/GlimpseTheCosmos.java
@@ -1,161 +1,161 @@
-package mage.cards.g;
-
-import mage.abilities.Ability;
-import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
-import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.ReplacementEffectImpl;
-import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.constants.*;
-import mage.filter.StaticFilters;
-import mage.filter.common.FilterControlledPermanent;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.events.ZoneChangeEvent;
-import mage.players.Player;
-import java.util.UUID;
-import mage.Mana;
-import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.decorator.ConditionalAsThoughEffect;
-import mage.abilities.effects.AsThoughEffectImpl;
-import mage.watchers.common.ManaSpentToCastWatcher;
-
-/**
- *
- * @author jeffwadsworth
- */
-
-public class GlimpseTheCosmos extends CardImpl {
-
- public GlimpseTheCosmos(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
-
- // Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
- StaticValue.get(3), false, StaticValue.get(1),
- StaticFilters.FILTER_CARD, Zone.LIBRARY, false,
- false, false, Zone.HAND, false
- ).setText("look at the top three cards of your library. "
- + "Put one of them into your hand and the rest on the bottom of your library in any order"));
-
- //As long as you control a Giant, you may cast Glimpse the Cosmos from your graveyard by paying {U} rather than paying its mana cost. If you cast Glimpse the Cosmos this way and it would be put into your graveyard, exile it instead.
- this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD,
- new ConditionalAsThoughEffect(
- new GlimpseTheCosmosPlayEffect(),
- new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.GIANT)))));
-
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new GlimpseTheCosmosReplacementEffect()));
-
- }
-
- private GlimpseTheCosmos(final GlimpseTheCosmos card) {
- super(card);
- }
-
- @Override
- public GlimpseTheCosmos copy() {
- return new GlimpseTheCosmos(this);
- }
-
-}
-
-class GlimpseTheCosmosPlayEffect extends AsThoughEffectImpl {
-
- public GlimpseTheCosmosPlayEffect() {
- super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
- staticText = "As long as you control a Giant, you may cast {this} from your graveyard by paying {U} rather than paying its mana cost";
- }
-
- public GlimpseTheCosmosPlayEffect(final GlimpseTheCosmosPlayEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- return true;
- }
-
- @Override
- public GlimpseTheCosmosPlayEffect copy() {
- return new GlimpseTheCosmosPlayEffect(this);
- }
-
- @Override
- public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
- if (sourceId.equals(source.getSourceId())
- && source.isControlledBy(affectedControllerId)) {
- if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
- Player controller = game.getPlayer(affectedControllerId);
- if (controller != null) {
- controller.setCastSourceIdWithAlternateMana(sourceId, new ManaCostsImpl<>("{U}"), null);
- return true;
- }
- }
- }
- return false;
- }
-
-}
-
-class GlimpseTheCosmosReplacementEffect extends ReplacementEffectImpl {
-
- public GlimpseTheCosmosReplacementEffect() {
- super(Duration.OneUse, Outcome.Exile);
- staticText = "As long as you control a Giant, you may cast {this} from your graveyard by paying {U} rather than paying its mana cost. If you cast {this} this way and it would be put into your graveyard, exile it instead";
- }
-
- public GlimpseTheCosmosReplacementEffect(final GlimpseTheCosmosReplacementEffect effect) {
- super(effect);
- }
-
- @Override
- public GlimpseTheCosmosReplacementEffect copy() {
- return new GlimpseTheCosmosReplacementEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- return true;
- }
-
- @Override
- public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- Card card = game.getCard(event.getTargetId());
- if (card != null) {
- discard();
- return controller.moveCards(
- card, Zone.EXILED, source, game, false, false, false, event.getAppliedEffects());
- }
- }
- return false;
- }
-
- @Override
- public boolean checksEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.ZONE_CHANGE;
- }
-
- @Override
- public boolean applies(GameEvent event, Ability source, Game game) {
- ManaSpentToCastWatcher watcher = game.getState().getWatcher(ManaSpentToCastWatcher.class);
- if (watcher == null) {
- return false;
- }
- Mana payment = watcher.getLastManaPayment(source.getSourceId());
- if (payment != null
- && payment.getBlue() == 1 // must be blue mana
- && payment.count() == 1) { // must be just one
- if (event.getTargetId().equals(source.getSourceId())
- && ((ZoneChangeEvent) event).getFromZone() == Zone.STACK
- && ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
- return true;
- }
- }
- return false;
- }
-}
+package mage.cards.g;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.ReplacementEffectImpl;
+import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledPermanent;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.players.Player;
+import java.util.UUID;
+import mage.Mana;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalAsThoughEffect;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.watchers.common.ManaSpentToCastWatcher;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+
+public class GlimpseTheCosmos extends CardImpl {
+
+ public GlimpseTheCosmos(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
+
+ // Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
+ this.getSpellAbility().addEffect(new LookLibraryAndPickControllerEffect(
+ StaticValue.get(3), false, StaticValue.get(1),
+ StaticFilters.FILTER_CARD, Zone.LIBRARY, false,
+ false, false, Zone.HAND, false
+ ).setText("look at the top three cards of your library. "
+ + "Put one of them into your hand and the rest on the bottom of your library in any order"));
+
+ //As long as you control a Giant, you may cast Glimpse the Cosmos from your graveyard by paying {U} rather than paying its mana cost. If you cast Glimpse the Cosmos this way and it would be put into your graveyard, exile it instead.
+ this.addAbility(new SimpleStaticAbility(Zone.GRAVEYARD,
+ new ConditionalAsThoughEffect(
+ new GlimpseTheCosmosPlayEffect(),
+ new PermanentsOnTheBattlefieldCondition(new FilterControlledPermanent(SubType.GIANT)))));
+
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new GlimpseTheCosmosReplacementEffect()));
+
+ }
+
+ private GlimpseTheCosmos(final GlimpseTheCosmos card) {
+ super(card);
+ }
+
+ @Override
+ public GlimpseTheCosmos copy() {
+ return new GlimpseTheCosmos(this);
+ }
+
+}
+
+class GlimpseTheCosmosPlayEffect extends AsThoughEffectImpl {
+
+ public GlimpseTheCosmosPlayEffect() {
+ super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
+ staticText = "As long as you control a Giant, you may cast {this} from your graveyard by paying {U} rather than paying its mana cost";
+ }
+
+ public GlimpseTheCosmosPlayEffect(final GlimpseTheCosmosPlayEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public GlimpseTheCosmosPlayEffect copy() {
+ return new GlimpseTheCosmosPlayEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
+ if (sourceId.equals(source.getSourceId())
+ && source.isControlledBy(affectedControllerId)) {
+ if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
+ Player controller = game.getPlayer(affectedControllerId);
+ if (controller != null) {
+ controller.setCastSourceIdWithAlternateMana(sourceId, new ManaCostsImpl<>("{U}"), null);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
+
+class GlimpseTheCosmosReplacementEffect extends ReplacementEffectImpl {
+
+ public GlimpseTheCosmosReplacementEffect() {
+ super(Duration.OneUse, Outcome.Exile);
+ staticText = "As long as you control a Giant, you may cast {this} from your graveyard by paying {U} rather than paying its mana cost. If you cast {this} this way and it would be put into your graveyard, exile it instead";
+ }
+
+ public GlimpseTheCosmosReplacementEffect(final GlimpseTheCosmosReplacementEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GlimpseTheCosmosReplacementEffect copy() {
+ return new GlimpseTheCosmosReplacementEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public boolean replaceEvent(GameEvent event, Ability source, Game game) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ Card card = game.getCard(event.getTargetId());
+ if (card != null) {
+ discard();
+ return controller.moveCards(
+ card, Zone.EXILED, source, game, false, false, false, event.getAppliedEffects());
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ ManaSpentToCastWatcher watcher = game.getState().getWatcher(ManaSpentToCastWatcher.class);
+ if (watcher == null) {
+ return false;
+ }
+ Mana payment = watcher.getLastManaPayment(source.getSourceId());
+ if (payment != null
+ && payment.getBlue() == 1 // must be blue mana
+ && payment.count() == 1) { // must be just one
+ if (event.getTargetId().equals(source.getSourceId())
+ && ((ZoneChangeEvent) event).getFromZone() == Zone.STACK
+ && ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/MercadianMasques.java b/Mage.Sets/src/mage/sets/MercadianMasques.java
index 866c8cb036..a7398bf630 100644
--- a/Mage.Sets/src/mage/sets/MercadianMasques.java
+++ b/Mage.Sets/src/mage/sets/MercadianMasques.java
@@ -1,375 +1,375 @@
-package mage.sets;
-
-import mage.cards.ExpansionSet;
-import mage.constants.Rarity;
-import mage.constants.SetType;
-
-/**
- * @author North
- */
-public final class MercadianMasques extends ExpansionSet {
-
- private static final MercadianMasques instance = new MercadianMasques();
-
- public static MercadianMasques getInstance() {
- return instance;
- }
-
- private MercadianMasques() {
- super("Mercadian Masques", "MMQ", ExpansionSet.buildDate(1999, 8, 25), SetType.EXPANSION);
- this.blockName = "Masques";
- this.hasBoosters = true;
- this.numBoosterLands = 0;
- this.numBoosterCommon = 11;
- this.numBoosterUncommon = 3;
- this.numBoosterRare = 1;
- this.ratioBoosterMythic = 0;
- cards.add(new SetCardInfo("Aerial Caravan", 58, Rarity.RARE, mage.cards.a.AerialCaravan.class));
- cards.add(new SetCardInfo("Afterlife", 1, Rarity.UNCOMMON, mage.cards.a.Afterlife.class));
- cards.add(new SetCardInfo("Alabaster Wall", 2, Rarity.COMMON, mage.cards.a.AlabasterWall.class));
- cards.add(new SetCardInfo("Alley Grifters", 115, Rarity.COMMON, mage.cards.a.AlleyGrifters.class));
- cards.add(new SetCardInfo("Ancestral Mask", 229, Rarity.COMMON, mage.cards.a.AncestralMask.class));
- cards.add(new SetCardInfo("Armistice", 3, Rarity.RARE, mage.cards.a.Armistice.class));
- cards.add(new SetCardInfo("Arms Dealer", 172, Rarity.UNCOMMON, mage.cards.a.ArmsDealer.class));
- cards.add(new SetCardInfo("Arrest", 4, Rarity.UNCOMMON, mage.cards.a.Arrest.class));
- cards.add(new SetCardInfo("Assembly Hall", 286, Rarity.RARE, mage.cards.a.AssemblyHall.class));
- cards.add(new SetCardInfo("Ballista Squad", 5, Rarity.UNCOMMON, mage.cards.b.BallistaSquad.class));
- cards.add(new SetCardInfo("Balloon Peddler", 59, Rarity.COMMON, mage.cards.b.BalloonPeddler.class));
- cards.add(new SetCardInfo("Barbed Wire", 287, Rarity.UNCOMMON, mage.cards.b.BarbedWire.class));
- cards.add(new SetCardInfo("Battle Rampart", 173, Rarity.COMMON, mage.cards.b.BattleRampart.class));
- cards.add(new SetCardInfo("Battle Squadron", 174, Rarity.RARE, mage.cards.b.BattleSquadron.class));
- cards.add(new SetCardInfo("Bifurcate", 230, Rarity.RARE, mage.cards.b.Bifurcate.class));
- cards.add(new SetCardInfo("Black Market", 116, Rarity.RARE, mage.cards.b.BlackMarket.class));
- cards.add(new SetCardInfo("Blaster Mage", 175, Rarity.COMMON, mage.cards.b.BlasterMage.class));
- cards.add(new SetCardInfo("Blockade Runner", 60, Rarity.COMMON, mage.cards.b.BlockadeRunner.class));
- cards.add(new SetCardInfo("Blood Hound", 176, Rarity.RARE, mage.cards.b.BloodHound.class));
- cards.add(new SetCardInfo("Blood Oath", 177, Rarity.RARE, mage.cards.b.BloodOath.class));
- cards.add(new SetCardInfo("Boa Constrictor", 231, Rarity.UNCOMMON, mage.cards.b.BoaConstrictor.class));
- cards.add(new SetCardInfo("Bog Smugglers", 117, Rarity.COMMON, mage.cards.b.BogSmugglers.class));
- cards.add(new SetCardInfo("Bog Witch", 118, Rarity.COMMON, mage.cards.b.BogWitch.class));
- cards.add(new SetCardInfo("Brainstorm", 61, Rarity.COMMON, mage.cards.b.Brainstorm.class));
- cards.add(new SetCardInfo("Brawl", 178, Rarity.RARE, mage.cards.b.Brawl.class));
- cards.add(new SetCardInfo("Briar Patch", 232, Rarity.UNCOMMON, mage.cards.b.BriarPatch.class));
- cards.add(new SetCardInfo("Bribery", 62, Rarity.RARE, mage.cards.b.Bribery.class));
- cards.add(new SetCardInfo("Buoyancy", 63, Rarity.COMMON, mage.cards.b.Buoyancy.class));
- cards.add(new SetCardInfo("Cackling Witch", 119, Rarity.UNCOMMON, mage.cards.c.CacklingWitch.class));
- cards.add(new SetCardInfo("Caller of the Hunt", 233, Rarity.RARE, mage.cards.c.CallerOfTheHunt.class));
- cards.add(new SetCardInfo("Cateran Brute", 120, Rarity.COMMON, mage.cards.c.CateranBrute.class));
- cards.add(new SetCardInfo("Cateran Enforcer", 121, Rarity.UNCOMMON, mage.cards.c.CateranEnforcer.class));
- cards.add(new SetCardInfo("Cateran Kidnappers", 122, Rarity.UNCOMMON, mage.cards.c.CateranKidnappers.class));
- cards.add(new SetCardInfo("Cateran Overlord", 123, Rarity.RARE, mage.cards.c.CateranOverlord.class));
- cards.add(new SetCardInfo("Cateran Persuader", 124, Rarity.COMMON, mage.cards.c.CateranPersuader.class));
- cards.add(new SetCardInfo("Cateran Slaver", 125, Rarity.RARE, mage.cards.c.CateranSlaver.class));
- cards.add(new SetCardInfo("Cateran Summons", 126, Rarity.UNCOMMON, mage.cards.c.CateranSummons.class));
- cards.add(new SetCardInfo("Caustic Wasps", 234, Rarity.UNCOMMON, mage.cards.c.CausticWasps.class));
- cards.add(new SetCardInfo("Cave-In", 180, Rarity.RARE, mage.cards.c.CaveIn.class));
- cards.add(new SetCardInfo("Cavern Crawler", 181, Rarity.COMMON, mage.cards.c.CavernCrawler.class));
- cards.add(new SetCardInfo("Cave Sense", 179, Rarity.COMMON, mage.cards.c.CaveSense.class));
- cards.add(new SetCardInfo("Ceremonial Guard", 182, Rarity.COMMON, mage.cards.c.CeremonialGuard.class));
- cards.add(new SetCardInfo("Chambered Nautilus", 64, Rarity.UNCOMMON, mage.cards.c.ChamberedNautilus.class));
- cards.add(new SetCardInfo("Chameleon Spirit", 65, Rarity.UNCOMMON, mage.cards.c.ChameleonSpirit.class));
- cards.add(new SetCardInfo("Charisma", 66, Rarity.RARE, mage.cards.c.Charisma.class));
- cards.add(new SetCardInfo("Charm Peddler", 6, Rarity.COMMON, mage.cards.c.CharmPeddler.class));
- cards.add(new SetCardInfo("Charmed Griffin", 7, Rarity.UNCOMMON, mage.cards.c.CharmedGriffin.class));
- cards.add(new SetCardInfo("Cho-Arrim Alchemist", 8, Rarity.RARE, mage.cards.c.ChoArrimAlchemist.class));
- cards.add(new SetCardInfo("Cho-Arrim Bruiser", 9, Rarity.RARE, mage.cards.c.ChoArrimBruiser.class));
- cards.add(new SetCardInfo("Cho-Arrim Legate", 10, Rarity.UNCOMMON, mage.cards.c.ChoArrimLegate.class));
- cards.add(new SetCardInfo("Cho-Manno, Revolutionary", 11, Rarity.RARE, mage.cards.c.ChoMannoRevolutionary.class));
- cards.add(new SetCardInfo("Cho-Manno's Blessing", 12, Rarity.COMMON, mage.cards.c.ChoMannosBlessing.class));
- cards.add(new SetCardInfo("Cinder Elemental", 183, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class));
- cards.add(new SetCardInfo("Clear the Land", 235, Rarity.RARE, mage.cards.c.ClearTheLand.class));
- cards.add(new SetCardInfo("Close Quarters", 184, Rarity.UNCOMMON, mage.cards.c.CloseQuarters.class));
- cards.add(new SetCardInfo("Cloud Sprite", 67, Rarity.COMMON, mage.cards.c.CloudSprite.class));
- cards.add(new SetCardInfo("Coastal Piracy", 68, Rarity.UNCOMMON, mage.cards.c.CoastalPiracy.class));
- cards.add(new SetCardInfo("Collective Unconscious", 236, Rarity.RARE, mage.cards.c.CollectiveUnconscious.class));
- cards.add(new SetCardInfo("Common Cause", 13, Rarity.RARE, mage.cards.c.CommonCause.class));
- cards.add(new SetCardInfo("Conspiracy", 127, Rarity.RARE, mage.cards.c.Conspiracy.class));
- cards.add(new SetCardInfo("Cornered Market", 14, Rarity.RARE, mage.cards.c.CorneredMarket.class));
- cards.add(new SetCardInfo("Corrupt Official", 128, Rarity.RARE, mage.cards.c.CorruptOfficial.class));
- cards.add(new SetCardInfo("Counterspell", 69, Rarity.COMMON, mage.cards.c.Counterspell.class));
- cards.add(new SetCardInfo("Cowardice", 70, Rarity.RARE, mage.cards.c.Cowardice.class));
- cards.add(new SetCardInfo("Crackdown", 15, Rarity.RARE, mage.cards.c.Crackdown.class));
- cards.add(new SetCardInfo("Crag Saurian", 185, Rarity.RARE, mage.cards.c.CragSaurian.class));
- cards.add(new SetCardInfo("Crash", 186, Rarity.COMMON, mage.cards.c.Crash.class));
- cards.add(new SetCardInfo("Credit Voucher", 289, Rarity.UNCOMMON, mage.cards.c.CreditVoucher.class));
- cards.add(new SetCardInfo("Crenellated Wall", 290, Rarity.UNCOMMON, mage.cards.c.CrenellatedWall.class));
- cards.add(new SetCardInfo("Crooked Scales", 291, Rarity.RARE, mage.cards.c.CrookedScales.class));
- cards.add(new SetCardInfo("Crossbow Infantry", 16, Rarity.COMMON, mage.cards.c.CrossbowInfantry.class));
- cards.add(new SetCardInfo("Crumbling Sanctuary", 292, Rarity.RARE, mage.cards.c.CrumblingSanctuary.class));
- cards.add(new SetCardInfo("Customs Depot", 71, Rarity.UNCOMMON, mage.cards.c.CustomsDepot.class));
- cards.add(new SetCardInfo("Dark Ritual", 129, Rarity.COMMON, mage.cards.d.DarkRitual.class));
- cards.add(new SetCardInfo("Darting Merfolk", 72, Rarity.COMMON, mage.cards.d.DartingMerfolk.class));
- cards.add(new SetCardInfo("Dawnstrider", 237, Rarity.RARE, mage.cards.d.Dawnstrider.class));
- cards.add(new SetCardInfo("Deadly Insect", 238, Rarity.COMMON, mage.cards.d.DeadlyInsect.class));
- cards.add(new SetCardInfo("Deathgazer", 130, Rarity.UNCOMMON, mage.cards.d.Deathgazer.class));
- cards.add(new SetCardInfo("Deepwood Drummer", 239, Rarity.COMMON, mage.cards.d.DeepwoodDrummer.class));
- cards.add(new SetCardInfo("Deepwood Elder", 240, Rarity.RARE, mage.cards.d.DeepwoodElder.class));
- cards.add(new SetCardInfo("Deepwood Ghoul", 131, Rarity.COMMON, mage.cards.d.DeepwoodGhoul.class));
- cards.add(new SetCardInfo("Deepwood Legate", 132, Rarity.UNCOMMON, mage.cards.d.DeepwoodLegate.class));
- cards.add(new SetCardInfo("Deepwood Tantiv", 241, Rarity.UNCOMMON, mage.cards.d.DeepwoodTantiv.class));
- cards.add(new SetCardInfo("Deepwood Wolverine", 242, Rarity.COMMON, mage.cards.d.DeepwoodWolverine.class));
- cards.add(new SetCardInfo("Dehydration", 73, Rarity.COMMON, mage.cards.d.Dehydration.class));
- cards.add(new SetCardInfo("Delraich", 133, Rarity.RARE, mage.cards.d.Delraich.class));
- cards.add(new SetCardInfo("Desert Twister", 243, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class));
- cards.add(new SetCardInfo("Devout Witness", 17, Rarity.COMMON, mage.cards.d.DevoutWitness.class));
- cards.add(new SetCardInfo("Diplomatic Escort", 74, Rarity.UNCOMMON, mage.cards.d.DiplomaticEscort.class));
- cards.add(new SetCardInfo("Diplomatic Immunity", 75, Rarity.COMMON, mage.cards.d.DiplomaticImmunity.class));
- cards.add(new SetCardInfo("Disenchant", 18, Rarity.COMMON, mage.cards.d.Disenchant.class));
- cards.add(new SetCardInfo("Distorting Lens", 293, Rarity.RARE, mage.cards.d.DistortingLens.class));
- cards.add(new SetCardInfo("Drake Hatchling", 76, Rarity.COMMON, mage.cards.d.DrakeHatchling.class));
- cards.add(new SetCardInfo("Dust Bowl", 316, Rarity.RARE, mage.cards.d.DustBowl.class));
- cards.add(new SetCardInfo("Embargo", 77, Rarity.RARE, mage.cards.e.Embargo.class));
- cards.add(new SetCardInfo("Energy Flux", 78, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class));
- cards.add(new SetCardInfo("Enslaved Horror", 134, Rarity.UNCOMMON, mage.cards.e.EnslavedHorror.class));
- cards.add(new SetCardInfo("Extortion", 135, Rarity.RARE, mage.cards.e.Extortion.class));
- cards.add(new SetCardInfo("Extravagant Spirit", 79, Rarity.RARE, mage.cards.e.ExtravagantSpirit.class));
- cards.add(new SetCardInfo("Eye of Ramos", 294, Rarity.RARE, mage.cards.e.EyeOfRamos.class));
- cards.add(new SetCardInfo("False Demise", 80, Rarity.UNCOMMON, mage.cards.f.FalseDemise.class));
- cards.add(new SetCardInfo("Ferocity", 245, Rarity.COMMON, mage.cards.f.Ferocity.class));
- cards.add(new SetCardInfo("Flailing Manticore", 187, Rarity.RARE, mage.cards.f.FlailingManticore.class));
- cards.add(new SetCardInfo("Flailing Ogre", 188, Rarity.UNCOMMON, mage.cards.f.FlailingOgre.class));
- cards.add(new SetCardInfo("Flailing Soldier", 189, Rarity.COMMON, mage.cards.f.FlailingSoldier.class));
- cards.add(new SetCardInfo("Flaming Sword", 190, Rarity.COMMON, mage.cards.f.FlamingSword.class));
- cards.add(new SetCardInfo("Food Chain", 246, Rarity.RARE, mage.cards.f.FoodChain.class));
- cards.add(new SetCardInfo("Forced March", 136, Rarity.RARE, mage.cards.f.ForcedMarch.class));
- cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Foster", 247, Rarity.RARE, mage.cards.f.Foster.class));
- cards.add(new SetCardInfo("Fountain of Cho", 317, Rarity.UNCOMMON, mage.cards.f.FountainOfCho.class));
- cards.add(new SetCardInfo("Fountain Watch", 19, Rarity.RARE, mage.cards.f.FountainWatch.class));
- cards.add(new SetCardInfo("Fresh Volunteers", 20, Rarity.COMMON, mage.cards.f.FreshVolunteers.class));
- cards.add(new SetCardInfo("Furious Assault", 191, Rarity.COMMON, mage.cards.f.FuriousAssault.class));
- cards.add(new SetCardInfo("Game Preserve", 248, Rarity.RARE, mage.cards.g.GamePreserve.class));
- cards.add(new SetCardInfo("General's Regalia", 295, Rarity.RARE, mage.cards.g.GeneralsRegalia.class));
- cards.add(new SetCardInfo("Gerrard's Irregulars", 192, Rarity.COMMON, mage.cards.g.GerrardsIrregulars.class));
- cards.add(new SetCardInfo("Ghoul's Feast", 137, Rarity.UNCOMMON, mage.cards.g.GhoulsFeast.class));
- cards.add(new SetCardInfo("Giant Caterpillar", 249, Rarity.COMMON, mage.cards.g.GiantCaterpillar.class));
- cards.add(new SetCardInfo("Glowing Anemone", 81, Rarity.UNCOMMON, mage.cards.g.GlowingAnemone.class));
- cards.add(new SetCardInfo("Groundskeeper", 250, Rarity.UNCOMMON, mage.cards.g.Groundskeeper.class));
- cards.add(new SetCardInfo("Gush", 82, Rarity.COMMON, mage.cards.g.Gush.class));
- cards.add(new SetCardInfo("Hammer Mage", 193, Rarity.UNCOMMON, mage.cards.h.HammerMage.class));
- cards.add(new SetCardInfo("Haunted Crossroads", 138, Rarity.UNCOMMON, mage.cards.h.HauntedCrossroads.class));
- cards.add(new SetCardInfo("Heart of Ramos", 296, Rarity.RARE, mage.cards.h.HeartOfRamos.class));
- cards.add(new SetCardInfo("Henge Guardian", 297, Rarity.UNCOMMON, mage.cards.h.HengeGuardian.class));
- cards.add(new SetCardInfo("Henge of Ramos", 318, Rarity.UNCOMMON, mage.cards.h.HengeOfRamos.class));
- cards.add(new SetCardInfo("Hickory Woodlot", 319, Rarity.COMMON, mage.cards.h.HickoryWoodlot.class));
- cards.add(new SetCardInfo("High Market", 320, Rarity.RARE, mage.cards.h.HighMarket.class));
- cards.add(new SetCardInfo("High Seas", 83, Rarity.UNCOMMON, mage.cards.h.HighSeas.class));
- cards.add(new SetCardInfo("Highway Robber", 139, Rarity.COMMON, mage.cards.h.HighwayRobber.class));
- cards.add(new SetCardInfo("Hired Giant", 194, Rarity.UNCOMMON, mage.cards.h.HiredGiant.class));
- cards.add(new SetCardInfo("Honor the Fallen", 21, Rarity.RARE, mage.cards.h.HonorTheFallen.class));
- cards.add(new SetCardInfo("Hoodwink", 84, Rarity.COMMON, mage.cards.h.Hoodwink.class));
- cards.add(new SetCardInfo("Horned Troll", 251, Rarity.COMMON, mage.cards.h.HornedTroll.class));
- cards.add(new SetCardInfo("Horn of Plenty", 298, Rarity.RARE, mage.cards.h.HornOfPlenty.class));
- cards.add(new SetCardInfo("Horn of Ramos", 299, Rarity.RARE, mage.cards.h.HornOfRamos.class));
- cards.add(new SetCardInfo("Howling Wolf", 252, Rarity.COMMON, mage.cards.h.HowlingWolf.class));
- cards.add(new SetCardInfo("Hunted Wumpus", 253, Rarity.UNCOMMON, mage.cards.h.HuntedWumpus.class));
- cards.add(new SetCardInfo("Ignoble Soldier", 22, Rarity.UNCOMMON, mage.cards.i.IgnobleSoldier.class));
- cards.add(new SetCardInfo("Indentured Djinn", 85, Rarity.UNCOMMON, mage.cards.i.IndenturedDjinn.class));
- cards.add(new SetCardInfo("Instigator", 140, Rarity.RARE, mage.cards.i.Instigator.class));
- cards.add(new SetCardInfo("Insubordination", 141, Rarity.COMMON, mage.cards.i.Insubordination.class));
- cards.add(new SetCardInfo("Intimidation", 142, Rarity.UNCOMMON, mage.cards.i.Intimidation.class));
- cards.add(new SetCardInfo("Invigorate", 254, Rarity.COMMON, mage.cards.i.Invigorate.class));
- cards.add(new SetCardInfo("Inviolability", 23, Rarity.COMMON, mage.cards.i.Inviolability.class));
- cards.add(new SetCardInfo("Iron Lance", 300, Rarity.UNCOMMON, mage.cards.i.IronLance.class));
- cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Ivory Mask", 24, Rarity.RARE, mage.cards.i.IvoryMask.class));
- cards.add(new SetCardInfo("Jeweled Torque", 301, Rarity.UNCOMMON, mage.cards.j.JeweledTorque.class));
- cards.add(new SetCardInfo("Jhovall Queen", 25, Rarity.RARE, mage.cards.j.JhovallQueen.class));
- cards.add(new SetCardInfo("Jhovall Rider", 26, Rarity.UNCOMMON, mage.cards.j.JhovallRider.class));
- cards.add(new SetCardInfo("Karn's Touch", 86, Rarity.RARE, mage.cards.k.KarnsTouch.class));
- cards.add(new SetCardInfo("Kris Mage", 195, Rarity.COMMON, mage.cards.k.KrisMage.class));
- cards.add(new SetCardInfo("Kyren Archive", 302, Rarity.RARE, mage.cards.k.KyrenArchive.class));
- cards.add(new SetCardInfo("Kyren Glider", 196, Rarity.COMMON, mage.cards.k.KyrenGlider.class));
- cards.add(new SetCardInfo("Kyren Legate", 197, Rarity.UNCOMMON, mage.cards.k.KyrenLegate.class));
- cards.add(new SetCardInfo("Kyren Negotiations", 198, Rarity.UNCOMMON, mage.cards.k.KyrenNegotiations.class));
- cards.add(new SetCardInfo("Kyren Sniper", 199, Rarity.COMMON, mage.cards.k.KyrenSniper.class));
- cards.add(new SetCardInfo("Kyren Toy", 303, Rarity.RARE, mage.cards.k.KyrenToy.class));
- cards.add(new SetCardInfo("Land Grant", 255, Rarity.COMMON, mage.cards.l.LandGrant.class));
- cards.add(new SetCardInfo("Larceny", 143, Rarity.UNCOMMON, mage.cards.l.Larceny.class));
- cards.add(new SetCardInfo("Last Breath", 27, Rarity.UNCOMMON, mage.cards.l.LastBreath.class));
- cards.add(new SetCardInfo("Lava Runner", 200, Rarity.RARE, mage.cards.l.LavaRunner.class));
- cards.add(new SetCardInfo("Liability", 144, Rarity.RARE, mage.cards.l.Liability.class));
- cards.add(new SetCardInfo("Lightning Hounds", 201, Rarity.COMMON, mage.cards.l.LightningHounds.class));
- cards.add(new SetCardInfo("Lithophage", 202, Rarity.RARE, mage.cards.l.Lithophage.class));
- cards.add(new SetCardInfo("Lumbering Satyr", 257, Rarity.UNCOMMON, mage.cards.l.LumberingSatyr.class));
- cards.add(new SetCardInfo("Lunge", 203, Rarity.COMMON, mage.cards.l.Lunge.class));
- cards.add(new SetCardInfo("Lure", 258, Rarity.UNCOMMON, mage.cards.l.Lure.class));
- cards.add(new SetCardInfo("Maggot Therapy", 145, Rarity.COMMON, mage.cards.m.MaggotTherapy.class));
- cards.add(new SetCardInfo("Magistrate's Scepter", 304, Rarity.RARE, mage.cards.m.MagistratesScepter.class));
- cards.add(new SetCardInfo("Magistrate's Veto", 204, Rarity.UNCOMMON, mage.cards.m.MagistratesVeto.class));
- cards.add(new SetCardInfo("Megatherium", 259, Rarity.RARE, mage.cards.m.Megatherium.class));
- cards.add(new SetCardInfo("Mercadia's Downfall", 205, Rarity.UNCOMMON, mage.cards.m.MercadiasDownfall.class));
- cards.add(new SetCardInfo("Mercadian Atlas", 305, Rarity.RARE, mage.cards.m.MercadianAtlas.class));
- cards.add(new SetCardInfo("Mercadian Bazaar", 321, Rarity.UNCOMMON, mage.cards.m.MercadianBazaar.class));
- cards.add(new SetCardInfo("Mercadian Lift", 306, Rarity.RARE, mage.cards.m.MercadianLift.class));
- cards.add(new SetCardInfo("Midnight Ritual", 146, Rarity.RARE, mage.cards.m.MidnightRitual.class));
- cards.add(new SetCardInfo("Misdirection", 87, Rarity.RARE, mage.cards.m.Misdirection.class));
- cards.add(new SetCardInfo("Misshapen Fiend", 147, Rarity.COMMON, mage.cards.m.MisshapenFiend.class));
- cards.add(new SetCardInfo("Misstep", 88, Rarity.COMMON, mage.cards.m.Misstep.class));
- cards.add(new SetCardInfo("Molting Harpy", 148, Rarity.UNCOMMON, mage.cards.m.MoltingHarpy.class));
- cards.add(new SetCardInfo("Moment of Silence", 28, Rarity.COMMON, mage.cards.m.MomentOfSilence.class));
- cards.add(new SetCardInfo("Monkey Cage", 307, Rarity.RARE, mage.cards.m.MonkeyCage.class));
- cards.add(new SetCardInfo("Moonlit Wake", 29, Rarity.UNCOMMON, mage.cards.m.MoonlitWake.class));
- cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Muzzle", 30, Rarity.COMMON, mage.cards.m.Muzzle.class));
- cards.add(new SetCardInfo("Natural Affinity", 260, Rarity.RARE, mage.cards.n.NaturalAffinity.class));
- cards.add(new SetCardInfo("Nether Spirit", 149, Rarity.RARE, mage.cards.n.NetherSpirit.class));
- cards.add(new SetCardInfo("Nightwind Glider", 31, Rarity.COMMON, mage.cards.n.NightwindGlider.class));
- cards.add(new SetCardInfo("Noble Purpose", 32, Rarity.UNCOMMON, mage.cards.n.NoblePurpose.class));
- cards.add(new SetCardInfo("Notorious Assassin", 150, Rarity.RARE, mage.cards.n.NotoriousAssassin.class));
- cards.add(new SetCardInfo("Ogre Taskmaster", 206, Rarity.UNCOMMON, mage.cards.o.OgreTaskmaster.class));
- cards.add(new SetCardInfo("Orim's Cure", 33, Rarity.COMMON, mage.cards.o.OrimsCure.class));
- cards.add(new SetCardInfo("Overtaker", 89, Rarity.RARE, mage.cards.o.Overtaker.class));
- cards.add(new SetCardInfo("Panacea", 308, Rarity.UNCOMMON, mage.cards.p.Panacea.class));
- cards.add(new SetCardInfo("Pangosaur", 261, Rarity.RARE, mage.cards.p.Pangosaur.class));
- cards.add(new SetCardInfo("Peat Bog", 322, Rarity.COMMON, mage.cards.p.PeatBog.class));
- cards.add(new SetCardInfo("Pious Warrior", 34, Rarity.COMMON, mage.cards.p.PiousWarrior.class));
- cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Port Inspector", 90, Rarity.COMMON, mage.cards.p.PortInspector.class));
- cards.add(new SetCardInfo("Power Matrix", 309, Rarity.RARE, mage.cards.p.PowerMatrix.class));
- cards.add(new SetCardInfo("Pretender's Claim", 151, Rarity.UNCOMMON, mage.cards.p.PretendersClaim.class));
- cards.add(new SetCardInfo("Primeval Shambler", 152, Rarity.UNCOMMON, mage.cards.p.PrimevalShambler.class));
- cards.add(new SetCardInfo("Puffer Extract", 310, Rarity.UNCOMMON, mage.cards.p.PufferExtract.class));
- cards.add(new SetCardInfo("Pulverize", 207, Rarity.RARE, mage.cards.p.Pulverize.class));
- cards.add(new SetCardInfo("Putrefaction", 153, Rarity.UNCOMMON, mage.cards.p.Putrefaction.class));
- cards.add(new SetCardInfo("Puppet's Verdict", 208, Rarity.RARE, mage.cards.p.PuppetsVerdict.class));
- cards.add(new SetCardInfo("Quagmire Lamprey", 154, Rarity.UNCOMMON, mage.cards.q.QuagmireLamprey.class));
- cards.add(new SetCardInfo("Rain of Tears", 155, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class));
- cards.add(new SetCardInfo("Ramosian Captain", 35, Rarity.UNCOMMON, mage.cards.r.RamosianCaptain.class));
- cards.add(new SetCardInfo("Ramosian Commander", 36, Rarity.UNCOMMON, mage.cards.r.RamosianCommander.class));
- cards.add(new SetCardInfo("Ramosian Lieutenant", 37, Rarity.COMMON, mage.cards.r.RamosianLieutenant.class));
- cards.add(new SetCardInfo("Ramosian Rally", 38, Rarity.COMMON, mage.cards.r.RamosianRally.class));
- cards.add(new SetCardInfo("Ramosian Sergeant", 39, Rarity.COMMON, mage.cards.r.RamosianSergeant.class));
- cards.add(new SetCardInfo("Ramosian Sky Marshal", 40, Rarity.RARE, mage.cards.r.RamosianSkyMarshal.class));
- cards.add(new SetCardInfo("Rampart Crawler", 156, Rarity.COMMON, mage.cards.r.RampartCrawler.class));
- cards.add(new SetCardInfo("Rappelling Scouts", 41, Rarity.RARE, mage.cards.r.RappellingScouts.class));
- cards.add(new SetCardInfo("Remote Farm", 323, Rarity.COMMON, mage.cards.r.RemoteFarm.class));
- cards.add(new SetCardInfo("Renounce", 42, Rarity.UNCOMMON, mage.cards.r.Renounce.class));
- cards.add(new SetCardInfo("Revered Elder", 43, Rarity.COMMON, mage.cards.r.ReveredElder.class));
- cards.add(new SetCardInfo("Reverent Mantra", 44, Rarity.RARE, mage.cards.r.ReverentMantra.class));
- cards.add(new SetCardInfo("Revive", 262, Rarity.UNCOMMON, mage.cards.r.Revive.class));
- cards.add(new SetCardInfo("Righteous Aura", 45, Rarity.UNCOMMON, mage.cards.r.RighteousAura.class));
- cards.add(new SetCardInfo("Righteous Indignation", 46, Rarity.UNCOMMON, mage.cards.r.RighteousIndignation.class));
- cards.add(new SetCardInfo("Rishadan Airship", 91, Rarity.COMMON, mage.cards.r.RishadanAirship.class));
- cards.add(new SetCardInfo("Rishadan Brigand", 92, Rarity.RARE, mage.cards.r.RishadanBrigand.class));
- cards.add(new SetCardInfo("Rishadan Cutpurse", 93, Rarity.COMMON, mage.cards.r.RishadanCutpurse.class));
- cards.add(new SetCardInfo("Rishadan Footpad", 94, Rarity.UNCOMMON, mage.cards.r.RishadanFootpad.class));
- cards.add(new SetCardInfo("Rishadan Pawnshop", 311, Rarity.RARE, mage.cards.r.RishadanPawnshop.class));
- cards.add(new SetCardInfo("Rishadan Port", 324, Rarity.RARE, mage.cards.r.RishadanPort.class));
- cards.add(new SetCardInfo("Robber Fly", 209, Rarity.UNCOMMON, mage.cards.r.RobberFly.class));
- cards.add(new SetCardInfo("Rock Badger", 210, Rarity.UNCOMMON, mage.cards.r.RockBadger.class));
- cards.add(new SetCardInfo("Rouse", 157, Rarity.COMMON, mage.cards.r.Rouse.class));
- cards.add(new SetCardInfo("Rushwood Dryad", 263, Rarity.COMMON, mage.cards.r.RushwoodDryad.class));
- cards.add(new SetCardInfo("Rushwood Elemental", 264, Rarity.RARE, mage.cards.r.RushwoodElemental.class));
- cards.add(new SetCardInfo("Rushwood Grove", 325, Rarity.UNCOMMON, mage.cards.r.RushwoodGrove.class));
- cards.add(new SetCardInfo("Rushwood Herbalist", 265, Rarity.COMMON, mage.cards.r.RushwoodHerbalist.class));
- cards.add(new SetCardInfo("Rushwood Legate", 266, Rarity.UNCOMMON, mage.cards.r.RushwoodLegate.class));
- cards.add(new SetCardInfo("Saber Ants", 267, Rarity.UNCOMMON, mage.cards.s.SaberAnts.class));
- cards.add(new SetCardInfo("Sacred Prey", 268, Rarity.COMMON, mage.cards.s.SacredPrey.class));
- cards.add(new SetCardInfo("Sailmonger", 95, Rarity.UNCOMMON, mage.cards.s.Sailmonger.class));
- cards.add(new SetCardInfo("Sand Squid", 96, Rarity.RARE, mage.cards.s.SandSquid.class));
- cards.add(new SetCardInfo("Sandstone Needle", 326, Rarity.COMMON, mage.cards.s.SandstoneNeedle.class));
- cards.add(new SetCardInfo("Saprazzan Bailiff", 97, Rarity.RARE, mage.cards.s.SaprazzanBailiff.class));
- cards.add(new SetCardInfo("Saprazzan Breaker", 98, Rarity.UNCOMMON, mage.cards.s.SaprazzanBreaker.class));
- cards.add(new SetCardInfo("Saprazzan Cove", 327, Rarity.UNCOMMON, mage.cards.s.SaprazzanCove.class));
- cards.add(new SetCardInfo("Saprazzan Heir", 99, Rarity.RARE, mage.cards.s.SaprazzanHeir.class));
- cards.add(new SetCardInfo("Saprazzan Legate", 100, Rarity.UNCOMMON, mage.cards.s.SaprazzanLegate.class));
- cards.add(new SetCardInfo("Saprazzan Outrigger", 101, Rarity.COMMON, mage.cards.s.SaprazzanOutrigger.class));
- cards.add(new SetCardInfo("Saprazzan Raider", 102, Rarity.COMMON, mage.cards.s.SaprazzanRaider.class));
- cards.add(new SetCardInfo("Saprazzan Skerry", 328, Rarity.COMMON, mage.cards.s.SaprazzanSkerry.class));
- cards.add(new SetCardInfo("Scandalmonger", 158, Rarity.UNCOMMON, mage.cards.s.Scandalmonger.class));
- cards.add(new SetCardInfo("Security Detail", 47, Rarity.RARE, mage.cards.s.SecurityDetail.class));
- cards.add(new SetCardInfo("Seismic Mage", 211, Rarity.RARE, mage.cards.s.SeismicMage.class));
- cards.add(new SetCardInfo("Sever Soul", 159, Rarity.COMMON, mage.cards.s.SeverSoul.class));
- cards.add(new SetCardInfo("Shock Troops", 212, Rarity.COMMON, mage.cards.s.ShockTroops.class));
- cards.add(new SetCardInfo("Shoving Match", 103, Rarity.UNCOMMON, mage.cards.s.ShovingMatch.class));
- cards.add(new SetCardInfo("Silent Assassin", 160, Rarity.RARE, mage.cards.s.SilentAssassin.class));
- cards.add(new SetCardInfo("Silverglade Elemental", 269, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class));
- cards.add(new SetCardInfo("Silverglade Pathfinder", 270, Rarity.UNCOMMON, mage.cards.s.SilvergladePathfinder.class));
- cards.add(new SetCardInfo("Sizzle", 213, Rarity.COMMON, mage.cards.s.Sizzle.class));
- cards.add(new SetCardInfo("Skulking Fugitive", 161, Rarity.COMMON, mage.cards.s.SkulkingFugitive.class));
- cards.add(new SetCardInfo("Skull of Ramos", 312, Rarity.RARE, mage.cards.s.SkullOfRamos.class));
- cards.add(new SetCardInfo("Snake Pit", 271, Rarity.UNCOMMON, mage.cards.s.SnakePit.class));
- cards.add(new SetCardInfo("Snorting Gahr", 272, Rarity.COMMON, mage.cards.s.SnortingGahr.class));
- cards.add(new SetCardInfo("Snuff Out", 162, Rarity.COMMON, mage.cards.s.SnuffOut.class));
- cards.add(new SetCardInfo("Soothing Balm", 48, Rarity.COMMON, mage.cards.s.SoothingBalm.class));
- cards.add(new SetCardInfo("Soothsaying", 104, Rarity.UNCOMMON, mage.cards.s.Soothsaying.class));
- cards.add(new SetCardInfo("Soul Channeling", 163, Rarity.COMMON, mage.cards.s.SoulChanneling.class));
- cards.add(new SetCardInfo("Specter's Wail", 164, Rarity.COMMON, mage.cards.s.SpectersWail.class));
- cards.add(new SetCardInfo("Spidersilk Armor", 273, Rarity.COMMON, mage.cards.s.SpidersilkArmor.class));
- cards.add(new SetCardInfo("Spiritual Focus", 49, Rarity.RARE, mage.cards.s.SpiritualFocus.class));
- cards.add(new SetCardInfo("Spontaneous Generation", 274, Rarity.RARE, mage.cards.s.SpontaneousGeneration.class));
- cards.add(new SetCardInfo("Squall", 275, Rarity.COMMON, mage.cards.s.Squall.class));
- cards.add(new SetCardInfo("Squallmonger", 276, Rarity.UNCOMMON, mage.cards.s.Squallmonger.class));
- cards.add(new SetCardInfo("Squee, Goblin Nabob", 214, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class));
- cards.add(new SetCardInfo("Squeeze", 105, Rarity.RARE, mage.cards.s.Squeeze.class));
- cards.add(new SetCardInfo("Stamina", 277, Rarity.UNCOMMON, mage.cards.s.Stamina.class));
- cards.add(new SetCardInfo("Statecraft", 106, Rarity.RARE, mage.cards.s.Statecraft.class));
- cards.add(new SetCardInfo("Steadfast Guard", 50, Rarity.COMMON, mage.cards.s.SteadfastGuard.class));
- cards.add(new SetCardInfo("Stinging Barrier", 107, Rarity.COMMON, mage.cards.s.StingingBarrier.class));
- cards.add(new SetCardInfo("Stone Rain", 215, Rarity.COMMON, mage.cards.s.StoneRain.class));
- cards.add(new SetCardInfo("Story Circle", 51, Rarity.UNCOMMON, mage.cards.s.StoryCircle.class));
- cards.add(new SetCardInfo("Strongarm Thug", 165, Rarity.UNCOMMON, mage.cards.s.StrongarmThug.class));
- cards.add(new SetCardInfo("Subterranean Hangar", 329, Rarity.UNCOMMON, mage.cards.s.SubterraneanHangar.class));
- cards.add(new SetCardInfo("Sustenance", 278, Rarity.UNCOMMON, mage.cards.s.Sustenance.class));
- cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Task Force", 52, Rarity.COMMON, mage.cards.t.TaskForce.class));
- cards.add(new SetCardInfo("Tectonic Break", 216, Rarity.RARE, mage.cards.t.TectonicBreak.class));
- cards.add(new SetCardInfo("Territorial Dispute", 217, Rarity.RARE, mage.cards.t.TerritorialDispute.class));
- cards.add(new SetCardInfo("Thermal Glider", 53, Rarity.COMMON, mage.cards.t.ThermalGlider.class));
- cards.add(new SetCardInfo("Thieves' Auction", 218, Rarity.RARE, mage.cards.t.ThievesAuction.class));
- cards.add(new SetCardInfo("Thrashing Wumpus", 166, Rarity.RARE, mage.cards.t.ThrashingWumpus.class));
- cards.add(new SetCardInfo("Thunderclap", 219, Rarity.COMMON, mage.cards.t.Thunderclap.class));
- cards.add(new SetCardInfo("Thwart", 108, Rarity.UNCOMMON, mage.cards.t.Thwart.class));
- cards.add(new SetCardInfo("Tidal Bore", 109, Rarity.COMMON, mage.cards.t.TidalBore.class));
- cards.add(new SetCardInfo("Tidal Kraken", 110, Rarity.RARE, mage.cards.t.TidalKraken.class));
- cards.add(new SetCardInfo("Tiger Claws", 279, Rarity.COMMON, mage.cards.t.TigerClaws.class));
- cards.add(new SetCardInfo("Timid Drake", 111, Rarity.UNCOMMON, mage.cards.t.TimidDrake.class));
- cards.add(new SetCardInfo("Tonic Peddler", 54, Rarity.UNCOMMON, mage.cards.t.TonicPeddler.class));
- cards.add(new SetCardInfo("Tooth of Ramos", 313, Rarity.RARE, mage.cards.t.ToothOfRamos.class));
- cards.add(new SetCardInfo("Tower of the Magistrate", 330, Rarity.RARE, mage.cards.t.TowerOfTheMagistrate.class));
- cards.add(new SetCardInfo("Toymaker", 314, Rarity.UNCOMMON, mage.cards.t.Toymaker.class));
- cards.add(new SetCardInfo("Trade Routes", 112, Rarity.RARE, mage.cards.t.TradeRoutes.class));
- cards.add(new SetCardInfo("Tranquility", 280, Rarity.COMMON, mage.cards.t.Tranquility.class));
- cards.add(new SetCardInfo("Trap Runner", 55, Rarity.UNCOMMON, mage.cards.t.TrapRunner.class));
- cards.add(new SetCardInfo("Tremor", 220, Rarity.COMMON, mage.cards.t.Tremor.class));
- cards.add(new SetCardInfo("Two-Headed Dragon", 221, Rarity.RARE, mage.cards.t.TwoHeadedDragon.class));
- cards.add(new SetCardInfo("Undertaker", 167, Rarity.COMMON, mage.cards.u.Undertaker.class));
- cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class));
- cards.add(new SetCardInfo("Unnatural Hunger", 169, Rarity.RARE, mage.cards.u.UnnaturalHunger.class));
- cards.add(new SetCardInfo("Uphill Battle", 222, Rarity.UNCOMMON, mage.cards.u.UphillBattle.class));
- cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class));
- cards.add(new SetCardInfo("Venomous Breath", 281, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class));
- cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class));
- cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class));
- cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class));
- cards.add(new SetCardInfo("Vine Trellis", 285, Rarity.COMMON, mage.cards.v.VineTrellis.class));
- cards.add(new SetCardInfo("Volcanic Wind", 223, Rarity.UNCOMMON, mage.cards.v.VolcanicWind.class));
- cards.add(new SetCardInfo("Wall of Distortion", 171, Rarity.COMMON, mage.cards.w.WallOfDistortion.class));
- cards.add(new SetCardInfo("War Cadence", 224, Rarity.UNCOMMON, mage.cards.w.WarCadence.class));
- cards.add(new SetCardInfo("War Tax", 113, Rarity.UNCOMMON, mage.cards.w.WarTax.class));
- cards.add(new SetCardInfo("Warmonger", 225, Rarity.UNCOMMON, mage.cards.w.Warmonger.class));
- cards.add(new SetCardInfo("Warpath", 226, Rarity.UNCOMMON, mage.cards.w.Warpath.class));
- cards.add(new SetCardInfo("Waterfront Bouncer", 114, Rarity.COMMON, mage.cards.w.WaterfrontBouncer.class));
- cards.add(new SetCardInfo("Wave of Reckoning", 56, Rarity.RARE, mage.cards.w.WaveOfReckoning.class));
- cards.add(new SetCardInfo("Wild Jhovall", 227, Rarity.COMMON, mage.cards.w.WildJhovall.class));
- cards.add(new SetCardInfo("Wishmonger", 57, Rarity.UNCOMMON, mage.cards.w.Wishmonger.class));
- cards.add(new SetCardInfo("Word of Blasting", 228, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.class));
- cards.add(new SetCardInfo("Worry Beads", 315, Rarity.RARE, mage.cards.w.WorryBeads.class));
- }
-}
+package mage.sets;
+
+import mage.cards.ExpansionSet;
+import mage.constants.Rarity;
+import mage.constants.SetType;
+
+/**
+ * @author North
+ */
+public final class MercadianMasques extends ExpansionSet {
+
+ private static final MercadianMasques instance = new MercadianMasques();
+
+ public static MercadianMasques getInstance() {
+ return instance;
+ }
+
+ private MercadianMasques() {
+ super("Mercadian Masques", "MMQ", ExpansionSet.buildDate(1999, 8, 25), SetType.EXPANSION);
+ this.blockName = "Masques";
+ this.hasBoosters = true;
+ this.numBoosterLands = 0;
+ this.numBoosterCommon = 11;
+ this.numBoosterUncommon = 3;
+ this.numBoosterRare = 1;
+ this.ratioBoosterMythic = 0;
+ cards.add(new SetCardInfo("Aerial Caravan", 58, Rarity.RARE, mage.cards.a.AerialCaravan.class));
+ cards.add(new SetCardInfo("Afterlife", 1, Rarity.UNCOMMON, mage.cards.a.Afterlife.class));
+ cards.add(new SetCardInfo("Alabaster Wall", 2, Rarity.COMMON, mage.cards.a.AlabasterWall.class));
+ cards.add(new SetCardInfo("Alley Grifters", 115, Rarity.COMMON, mage.cards.a.AlleyGrifters.class));
+ cards.add(new SetCardInfo("Ancestral Mask", 229, Rarity.COMMON, mage.cards.a.AncestralMask.class));
+ cards.add(new SetCardInfo("Armistice", 3, Rarity.RARE, mage.cards.a.Armistice.class));
+ cards.add(new SetCardInfo("Arms Dealer", 172, Rarity.UNCOMMON, mage.cards.a.ArmsDealer.class));
+ cards.add(new SetCardInfo("Arrest", 4, Rarity.UNCOMMON, mage.cards.a.Arrest.class));
+ cards.add(new SetCardInfo("Assembly Hall", 286, Rarity.RARE, mage.cards.a.AssemblyHall.class));
+ cards.add(new SetCardInfo("Ballista Squad", 5, Rarity.UNCOMMON, mage.cards.b.BallistaSquad.class));
+ cards.add(new SetCardInfo("Balloon Peddler", 59, Rarity.COMMON, mage.cards.b.BalloonPeddler.class));
+ cards.add(new SetCardInfo("Barbed Wire", 287, Rarity.UNCOMMON, mage.cards.b.BarbedWire.class));
+ cards.add(new SetCardInfo("Battle Rampart", 173, Rarity.COMMON, mage.cards.b.BattleRampart.class));
+ cards.add(new SetCardInfo("Battle Squadron", 174, Rarity.RARE, mage.cards.b.BattleSquadron.class));
+ cards.add(new SetCardInfo("Bifurcate", 230, Rarity.RARE, mage.cards.b.Bifurcate.class));
+ cards.add(new SetCardInfo("Black Market", 116, Rarity.RARE, mage.cards.b.BlackMarket.class));
+ cards.add(new SetCardInfo("Blaster Mage", 175, Rarity.COMMON, mage.cards.b.BlasterMage.class));
+ cards.add(new SetCardInfo("Blockade Runner", 60, Rarity.COMMON, mage.cards.b.BlockadeRunner.class));
+ cards.add(new SetCardInfo("Blood Hound", 176, Rarity.RARE, mage.cards.b.BloodHound.class));
+ cards.add(new SetCardInfo("Blood Oath", 177, Rarity.RARE, mage.cards.b.BloodOath.class));
+ cards.add(new SetCardInfo("Boa Constrictor", 231, Rarity.UNCOMMON, mage.cards.b.BoaConstrictor.class));
+ cards.add(new SetCardInfo("Bog Smugglers", 117, Rarity.COMMON, mage.cards.b.BogSmugglers.class));
+ cards.add(new SetCardInfo("Bog Witch", 118, Rarity.COMMON, mage.cards.b.BogWitch.class));
+ cards.add(new SetCardInfo("Brainstorm", 61, Rarity.COMMON, mage.cards.b.Brainstorm.class));
+ cards.add(new SetCardInfo("Brawl", 178, Rarity.RARE, mage.cards.b.Brawl.class));
+ cards.add(new SetCardInfo("Briar Patch", 232, Rarity.UNCOMMON, mage.cards.b.BriarPatch.class));
+ cards.add(new SetCardInfo("Bribery", 62, Rarity.RARE, mage.cards.b.Bribery.class));
+ cards.add(new SetCardInfo("Buoyancy", 63, Rarity.COMMON, mage.cards.b.Buoyancy.class));
+ cards.add(new SetCardInfo("Cackling Witch", 119, Rarity.UNCOMMON, mage.cards.c.CacklingWitch.class));
+ cards.add(new SetCardInfo("Caller of the Hunt", 233, Rarity.RARE, mage.cards.c.CallerOfTheHunt.class));
+ cards.add(new SetCardInfo("Cateran Brute", 120, Rarity.COMMON, mage.cards.c.CateranBrute.class));
+ cards.add(new SetCardInfo("Cateran Enforcer", 121, Rarity.UNCOMMON, mage.cards.c.CateranEnforcer.class));
+ cards.add(new SetCardInfo("Cateran Kidnappers", 122, Rarity.UNCOMMON, mage.cards.c.CateranKidnappers.class));
+ cards.add(new SetCardInfo("Cateran Overlord", 123, Rarity.RARE, mage.cards.c.CateranOverlord.class));
+ cards.add(new SetCardInfo("Cateran Persuader", 124, Rarity.COMMON, mage.cards.c.CateranPersuader.class));
+ cards.add(new SetCardInfo("Cateran Slaver", 125, Rarity.RARE, mage.cards.c.CateranSlaver.class));
+ cards.add(new SetCardInfo("Cateran Summons", 126, Rarity.UNCOMMON, mage.cards.c.CateranSummons.class));
+ cards.add(new SetCardInfo("Caustic Wasps", 234, Rarity.UNCOMMON, mage.cards.c.CausticWasps.class));
+ cards.add(new SetCardInfo("Cave-In", 180, Rarity.RARE, mage.cards.c.CaveIn.class));
+ cards.add(new SetCardInfo("Cavern Crawler", 181, Rarity.COMMON, mage.cards.c.CavernCrawler.class));
+ cards.add(new SetCardInfo("Cave Sense", 179, Rarity.COMMON, mage.cards.c.CaveSense.class));
+ cards.add(new SetCardInfo("Ceremonial Guard", 182, Rarity.COMMON, mage.cards.c.CeremonialGuard.class));
+ cards.add(new SetCardInfo("Chambered Nautilus", 64, Rarity.UNCOMMON, mage.cards.c.ChamberedNautilus.class));
+ cards.add(new SetCardInfo("Chameleon Spirit", 65, Rarity.UNCOMMON, mage.cards.c.ChameleonSpirit.class));
+ cards.add(new SetCardInfo("Charisma", 66, Rarity.RARE, mage.cards.c.Charisma.class));
+ cards.add(new SetCardInfo("Charm Peddler", 6, Rarity.COMMON, mage.cards.c.CharmPeddler.class));
+ cards.add(new SetCardInfo("Charmed Griffin", 7, Rarity.UNCOMMON, mage.cards.c.CharmedGriffin.class));
+ cards.add(new SetCardInfo("Cho-Arrim Alchemist", 8, Rarity.RARE, mage.cards.c.ChoArrimAlchemist.class));
+ cards.add(new SetCardInfo("Cho-Arrim Bruiser", 9, Rarity.RARE, mage.cards.c.ChoArrimBruiser.class));
+ cards.add(new SetCardInfo("Cho-Arrim Legate", 10, Rarity.UNCOMMON, mage.cards.c.ChoArrimLegate.class));
+ cards.add(new SetCardInfo("Cho-Manno, Revolutionary", 11, Rarity.RARE, mage.cards.c.ChoMannoRevolutionary.class));
+ cards.add(new SetCardInfo("Cho-Manno's Blessing", 12, Rarity.COMMON, mage.cards.c.ChoMannosBlessing.class));
+ cards.add(new SetCardInfo("Cinder Elemental", 183, Rarity.UNCOMMON, mage.cards.c.CinderElemental.class));
+ cards.add(new SetCardInfo("Clear the Land", 235, Rarity.RARE, mage.cards.c.ClearTheLand.class));
+ cards.add(new SetCardInfo("Close Quarters", 184, Rarity.UNCOMMON, mage.cards.c.CloseQuarters.class));
+ cards.add(new SetCardInfo("Cloud Sprite", 67, Rarity.COMMON, mage.cards.c.CloudSprite.class));
+ cards.add(new SetCardInfo("Coastal Piracy", 68, Rarity.UNCOMMON, mage.cards.c.CoastalPiracy.class));
+ cards.add(new SetCardInfo("Collective Unconscious", 236, Rarity.RARE, mage.cards.c.CollectiveUnconscious.class));
+ cards.add(new SetCardInfo("Common Cause", 13, Rarity.RARE, mage.cards.c.CommonCause.class));
+ cards.add(new SetCardInfo("Conspiracy", 127, Rarity.RARE, mage.cards.c.Conspiracy.class));
+ cards.add(new SetCardInfo("Cornered Market", 14, Rarity.RARE, mage.cards.c.CorneredMarket.class));
+ cards.add(new SetCardInfo("Corrupt Official", 128, Rarity.RARE, mage.cards.c.CorruptOfficial.class));
+ cards.add(new SetCardInfo("Counterspell", 69, Rarity.COMMON, mage.cards.c.Counterspell.class));
+ cards.add(new SetCardInfo("Cowardice", 70, Rarity.RARE, mage.cards.c.Cowardice.class));
+ cards.add(new SetCardInfo("Crackdown", 15, Rarity.RARE, mage.cards.c.Crackdown.class));
+ cards.add(new SetCardInfo("Crag Saurian", 185, Rarity.RARE, mage.cards.c.CragSaurian.class));
+ cards.add(new SetCardInfo("Crash", 186, Rarity.COMMON, mage.cards.c.Crash.class));
+ cards.add(new SetCardInfo("Credit Voucher", 289, Rarity.UNCOMMON, mage.cards.c.CreditVoucher.class));
+ cards.add(new SetCardInfo("Crenellated Wall", 290, Rarity.UNCOMMON, mage.cards.c.CrenellatedWall.class));
+ cards.add(new SetCardInfo("Crooked Scales", 291, Rarity.RARE, mage.cards.c.CrookedScales.class));
+ cards.add(new SetCardInfo("Crossbow Infantry", 16, Rarity.COMMON, mage.cards.c.CrossbowInfantry.class));
+ cards.add(new SetCardInfo("Crumbling Sanctuary", 292, Rarity.RARE, mage.cards.c.CrumblingSanctuary.class));
+ cards.add(new SetCardInfo("Customs Depot", 71, Rarity.UNCOMMON, mage.cards.c.CustomsDepot.class));
+ cards.add(new SetCardInfo("Dark Ritual", 129, Rarity.COMMON, mage.cards.d.DarkRitual.class));
+ cards.add(new SetCardInfo("Darting Merfolk", 72, Rarity.COMMON, mage.cards.d.DartingMerfolk.class));
+ cards.add(new SetCardInfo("Dawnstrider", 237, Rarity.RARE, mage.cards.d.Dawnstrider.class));
+ cards.add(new SetCardInfo("Deadly Insect", 238, Rarity.COMMON, mage.cards.d.DeadlyInsect.class));
+ cards.add(new SetCardInfo("Deathgazer", 130, Rarity.UNCOMMON, mage.cards.d.Deathgazer.class));
+ cards.add(new SetCardInfo("Deepwood Drummer", 239, Rarity.COMMON, mage.cards.d.DeepwoodDrummer.class));
+ cards.add(new SetCardInfo("Deepwood Elder", 240, Rarity.RARE, mage.cards.d.DeepwoodElder.class));
+ cards.add(new SetCardInfo("Deepwood Ghoul", 131, Rarity.COMMON, mage.cards.d.DeepwoodGhoul.class));
+ cards.add(new SetCardInfo("Deepwood Legate", 132, Rarity.UNCOMMON, mage.cards.d.DeepwoodLegate.class));
+ cards.add(new SetCardInfo("Deepwood Tantiv", 241, Rarity.UNCOMMON, mage.cards.d.DeepwoodTantiv.class));
+ cards.add(new SetCardInfo("Deepwood Wolverine", 242, Rarity.COMMON, mage.cards.d.DeepwoodWolverine.class));
+ cards.add(new SetCardInfo("Dehydration", 73, Rarity.COMMON, mage.cards.d.Dehydration.class));
+ cards.add(new SetCardInfo("Delraich", 133, Rarity.RARE, mage.cards.d.Delraich.class));
+ cards.add(new SetCardInfo("Desert Twister", 243, Rarity.UNCOMMON, mage.cards.d.DesertTwister.class));
+ cards.add(new SetCardInfo("Devout Witness", 17, Rarity.COMMON, mage.cards.d.DevoutWitness.class));
+ cards.add(new SetCardInfo("Diplomatic Escort", 74, Rarity.UNCOMMON, mage.cards.d.DiplomaticEscort.class));
+ cards.add(new SetCardInfo("Diplomatic Immunity", 75, Rarity.COMMON, mage.cards.d.DiplomaticImmunity.class));
+ cards.add(new SetCardInfo("Disenchant", 18, Rarity.COMMON, mage.cards.d.Disenchant.class));
+ cards.add(new SetCardInfo("Distorting Lens", 293, Rarity.RARE, mage.cards.d.DistortingLens.class));
+ cards.add(new SetCardInfo("Drake Hatchling", 76, Rarity.COMMON, mage.cards.d.DrakeHatchling.class));
+ cards.add(new SetCardInfo("Dust Bowl", 316, Rarity.RARE, mage.cards.d.DustBowl.class));
+ cards.add(new SetCardInfo("Embargo", 77, Rarity.RARE, mage.cards.e.Embargo.class));
+ cards.add(new SetCardInfo("Energy Flux", 78, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class));
+ cards.add(new SetCardInfo("Enslaved Horror", 134, Rarity.UNCOMMON, mage.cards.e.EnslavedHorror.class));
+ cards.add(new SetCardInfo("Extortion", 135, Rarity.RARE, mage.cards.e.Extortion.class));
+ cards.add(new SetCardInfo("Extravagant Spirit", 79, Rarity.RARE, mage.cards.e.ExtravagantSpirit.class));
+ cards.add(new SetCardInfo("Eye of Ramos", 294, Rarity.RARE, mage.cards.e.EyeOfRamos.class));
+ cards.add(new SetCardInfo("False Demise", 80, Rarity.UNCOMMON, mage.cards.f.FalseDemise.class));
+ cards.add(new SetCardInfo("Ferocity", 245, Rarity.COMMON, mage.cards.f.Ferocity.class));
+ cards.add(new SetCardInfo("Flailing Manticore", 187, Rarity.RARE, mage.cards.f.FlailingManticore.class));
+ cards.add(new SetCardInfo("Flailing Ogre", 188, Rarity.UNCOMMON, mage.cards.f.FlailingOgre.class));
+ cards.add(new SetCardInfo("Flailing Soldier", 189, Rarity.COMMON, mage.cards.f.FlailingSoldier.class));
+ cards.add(new SetCardInfo("Flaming Sword", 190, Rarity.COMMON, mage.cards.f.FlamingSword.class));
+ cards.add(new SetCardInfo("Food Chain", 246, Rarity.RARE, mage.cards.f.FoodChain.class));
+ cards.add(new SetCardInfo("Forced March", 136, Rarity.RARE, mage.cards.f.ForcedMarch.class));
+ cards.add(new SetCardInfo("Forest", 347, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forest", 348, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forest", 349, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forest", 350, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Foster", 247, Rarity.RARE, mage.cards.f.Foster.class));
+ cards.add(new SetCardInfo("Fountain of Cho", 317, Rarity.UNCOMMON, mage.cards.f.FountainOfCho.class));
+ cards.add(new SetCardInfo("Fountain Watch", 19, Rarity.RARE, mage.cards.f.FountainWatch.class));
+ cards.add(new SetCardInfo("Fresh Volunteers", 20, Rarity.COMMON, mage.cards.f.FreshVolunteers.class));
+ cards.add(new SetCardInfo("Furious Assault", 191, Rarity.COMMON, mage.cards.f.FuriousAssault.class));
+ cards.add(new SetCardInfo("Game Preserve", 248, Rarity.RARE, mage.cards.g.GamePreserve.class));
+ cards.add(new SetCardInfo("General's Regalia", 295, Rarity.RARE, mage.cards.g.GeneralsRegalia.class));
+ cards.add(new SetCardInfo("Gerrard's Irregulars", 192, Rarity.COMMON, mage.cards.g.GerrardsIrregulars.class));
+ cards.add(new SetCardInfo("Ghoul's Feast", 137, Rarity.UNCOMMON, mage.cards.g.GhoulsFeast.class));
+ cards.add(new SetCardInfo("Giant Caterpillar", 249, Rarity.COMMON, mage.cards.g.GiantCaterpillar.class));
+ cards.add(new SetCardInfo("Glowing Anemone", 81, Rarity.UNCOMMON, mage.cards.g.GlowingAnemone.class));
+ cards.add(new SetCardInfo("Groundskeeper", 250, Rarity.UNCOMMON, mage.cards.g.Groundskeeper.class));
+ cards.add(new SetCardInfo("Gush", 82, Rarity.COMMON, mage.cards.g.Gush.class));
+ cards.add(new SetCardInfo("Hammer Mage", 193, Rarity.UNCOMMON, mage.cards.h.HammerMage.class));
+ cards.add(new SetCardInfo("Haunted Crossroads", 138, Rarity.UNCOMMON, mage.cards.h.HauntedCrossroads.class));
+ cards.add(new SetCardInfo("Heart of Ramos", 296, Rarity.RARE, mage.cards.h.HeartOfRamos.class));
+ cards.add(new SetCardInfo("Henge Guardian", 297, Rarity.UNCOMMON, mage.cards.h.HengeGuardian.class));
+ cards.add(new SetCardInfo("Henge of Ramos", 318, Rarity.UNCOMMON, mage.cards.h.HengeOfRamos.class));
+ cards.add(new SetCardInfo("Hickory Woodlot", 319, Rarity.COMMON, mage.cards.h.HickoryWoodlot.class));
+ cards.add(new SetCardInfo("High Market", 320, Rarity.RARE, mage.cards.h.HighMarket.class));
+ cards.add(new SetCardInfo("High Seas", 83, Rarity.UNCOMMON, mage.cards.h.HighSeas.class));
+ cards.add(new SetCardInfo("Highway Robber", 139, Rarity.COMMON, mage.cards.h.HighwayRobber.class));
+ cards.add(new SetCardInfo("Hired Giant", 194, Rarity.UNCOMMON, mage.cards.h.HiredGiant.class));
+ cards.add(new SetCardInfo("Honor the Fallen", 21, Rarity.RARE, mage.cards.h.HonorTheFallen.class));
+ cards.add(new SetCardInfo("Hoodwink", 84, Rarity.COMMON, mage.cards.h.Hoodwink.class));
+ cards.add(new SetCardInfo("Horned Troll", 251, Rarity.COMMON, mage.cards.h.HornedTroll.class));
+ cards.add(new SetCardInfo("Horn of Plenty", 298, Rarity.RARE, mage.cards.h.HornOfPlenty.class));
+ cards.add(new SetCardInfo("Horn of Ramos", 299, Rarity.RARE, mage.cards.h.HornOfRamos.class));
+ cards.add(new SetCardInfo("Howling Wolf", 252, Rarity.COMMON, mage.cards.h.HowlingWolf.class));
+ cards.add(new SetCardInfo("Hunted Wumpus", 253, Rarity.UNCOMMON, mage.cards.h.HuntedWumpus.class));
+ cards.add(new SetCardInfo("Ignoble Soldier", 22, Rarity.UNCOMMON, mage.cards.i.IgnobleSoldier.class));
+ cards.add(new SetCardInfo("Indentured Djinn", 85, Rarity.UNCOMMON, mage.cards.i.IndenturedDjinn.class));
+ cards.add(new SetCardInfo("Instigator", 140, Rarity.RARE, mage.cards.i.Instigator.class));
+ cards.add(new SetCardInfo("Insubordination", 141, Rarity.COMMON, mage.cards.i.Insubordination.class));
+ cards.add(new SetCardInfo("Intimidation", 142, Rarity.UNCOMMON, mage.cards.i.Intimidation.class));
+ cards.add(new SetCardInfo("Invigorate", 254, Rarity.COMMON, mage.cards.i.Invigorate.class));
+ cards.add(new SetCardInfo("Inviolability", 23, Rarity.COMMON, mage.cards.i.Inviolability.class));
+ cards.add(new SetCardInfo("Iron Lance", 300, Rarity.UNCOMMON, mage.cards.i.IronLance.class));
+ cards.add(new SetCardInfo("Island", 335, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island", 336, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Ivory Mask", 24, Rarity.RARE, mage.cards.i.IvoryMask.class));
+ cards.add(new SetCardInfo("Jeweled Torque", 301, Rarity.UNCOMMON, mage.cards.j.JeweledTorque.class));
+ cards.add(new SetCardInfo("Jhovall Queen", 25, Rarity.RARE, mage.cards.j.JhovallQueen.class));
+ cards.add(new SetCardInfo("Jhovall Rider", 26, Rarity.UNCOMMON, mage.cards.j.JhovallRider.class));
+ cards.add(new SetCardInfo("Karn's Touch", 86, Rarity.RARE, mage.cards.k.KarnsTouch.class));
+ cards.add(new SetCardInfo("Kris Mage", 195, Rarity.COMMON, mage.cards.k.KrisMage.class));
+ cards.add(new SetCardInfo("Kyren Archive", 302, Rarity.RARE, mage.cards.k.KyrenArchive.class));
+ cards.add(new SetCardInfo("Kyren Glider", 196, Rarity.COMMON, mage.cards.k.KyrenGlider.class));
+ cards.add(new SetCardInfo("Kyren Legate", 197, Rarity.UNCOMMON, mage.cards.k.KyrenLegate.class));
+ cards.add(new SetCardInfo("Kyren Negotiations", 198, Rarity.UNCOMMON, mage.cards.k.KyrenNegotiations.class));
+ cards.add(new SetCardInfo("Kyren Sniper", 199, Rarity.COMMON, mage.cards.k.KyrenSniper.class));
+ cards.add(new SetCardInfo("Kyren Toy", 303, Rarity.RARE, mage.cards.k.KyrenToy.class));
+ cards.add(new SetCardInfo("Land Grant", 255, Rarity.COMMON, mage.cards.l.LandGrant.class));
+ cards.add(new SetCardInfo("Larceny", 143, Rarity.UNCOMMON, mage.cards.l.Larceny.class));
+ cards.add(new SetCardInfo("Last Breath", 27, Rarity.UNCOMMON, mage.cards.l.LastBreath.class));
+ cards.add(new SetCardInfo("Lava Runner", 200, Rarity.RARE, mage.cards.l.LavaRunner.class));
+ cards.add(new SetCardInfo("Liability", 144, Rarity.RARE, mage.cards.l.Liability.class));
+ cards.add(new SetCardInfo("Lightning Hounds", 201, Rarity.COMMON, mage.cards.l.LightningHounds.class));
+ cards.add(new SetCardInfo("Lithophage", 202, Rarity.RARE, mage.cards.l.Lithophage.class));
+ cards.add(new SetCardInfo("Lumbering Satyr", 257, Rarity.UNCOMMON, mage.cards.l.LumberingSatyr.class));
+ cards.add(new SetCardInfo("Lunge", 203, Rarity.COMMON, mage.cards.l.Lunge.class));
+ cards.add(new SetCardInfo("Lure", 258, Rarity.UNCOMMON, mage.cards.l.Lure.class));
+ cards.add(new SetCardInfo("Maggot Therapy", 145, Rarity.COMMON, mage.cards.m.MaggotTherapy.class));
+ cards.add(new SetCardInfo("Magistrate's Scepter", 304, Rarity.RARE, mage.cards.m.MagistratesScepter.class));
+ cards.add(new SetCardInfo("Magistrate's Veto", 204, Rarity.UNCOMMON, mage.cards.m.MagistratesVeto.class));
+ cards.add(new SetCardInfo("Megatherium", 259, Rarity.RARE, mage.cards.m.Megatherium.class));
+ cards.add(new SetCardInfo("Mercadia's Downfall", 205, Rarity.UNCOMMON, mage.cards.m.MercadiasDownfall.class));
+ cards.add(new SetCardInfo("Mercadian Atlas", 305, Rarity.RARE, mage.cards.m.MercadianAtlas.class));
+ cards.add(new SetCardInfo("Mercadian Bazaar", 321, Rarity.UNCOMMON, mage.cards.m.MercadianBazaar.class));
+ cards.add(new SetCardInfo("Mercadian Lift", 306, Rarity.RARE, mage.cards.m.MercadianLift.class));
+ cards.add(new SetCardInfo("Midnight Ritual", 146, Rarity.RARE, mage.cards.m.MidnightRitual.class));
+ cards.add(new SetCardInfo("Misdirection", 87, Rarity.RARE, mage.cards.m.Misdirection.class));
+ cards.add(new SetCardInfo("Misshapen Fiend", 147, Rarity.COMMON, mage.cards.m.MisshapenFiend.class));
+ cards.add(new SetCardInfo("Misstep", 88, Rarity.COMMON, mage.cards.m.Misstep.class));
+ cards.add(new SetCardInfo("Molting Harpy", 148, Rarity.UNCOMMON, mage.cards.m.MoltingHarpy.class));
+ cards.add(new SetCardInfo("Moment of Silence", 28, Rarity.COMMON, mage.cards.m.MomentOfSilence.class));
+ cards.add(new SetCardInfo("Monkey Cage", 307, Rarity.RARE, mage.cards.m.MonkeyCage.class));
+ cards.add(new SetCardInfo("Moonlit Wake", 29, Rarity.UNCOMMON, mage.cards.m.MoonlitWake.class));
+ cards.add(new SetCardInfo("Mountain", 343, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain", 344, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain", 345, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain", 346, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Muzzle", 30, Rarity.COMMON, mage.cards.m.Muzzle.class));
+ cards.add(new SetCardInfo("Natural Affinity", 260, Rarity.RARE, mage.cards.n.NaturalAffinity.class));
+ cards.add(new SetCardInfo("Nether Spirit", 149, Rarity.RARE, mage.cards.n.NetherSpirit.class));
+ cards.add(new SetCardInfo("Nightwind Glider", 31, Rarity.COMMON, mage.cards.n.NightwindGlider.class));
+ cards.add(new SetCardInfo("Noble Purpose", 32, Rarity.UNCOMMON, mage.cards.n.NoblePurpose.class));
+ cards.add(new SetCardInfo("Notorious Assassin", 150, Rarity.RARE, mage.cards.n.NotoriousAssassin.class));
+ cards.add(new SetCardInfo("Ogre Taskmaster", 206, Rarity.UNCOMMON, mage.cards.o.OgreTaskmaster.class));
+ cards.add(new SetCardInfo("Orim's Cure", 33, Rarity.COMMON, mage.cards.o.OrimsCure.class));
+ cards.add(new SetCardInfo("Overtaker", 89, Rarity.RARE, mage.cards.o.Overtaker.class));
+ cards.add(new SetCardInfo("Panacea", 308, Rarity.UNCOMMON, mage.cards.p.Panacea.class));
+ cards.add(new SetCardInfo("Pangosaur", 261, Rarity.RARE, mage.cards.p.Pangosaur.class));
+ cards.add(new SetCardInfo("Peat Bog", 322, Rarity.COMMON, mage.cards.p.PeatBog.class));
+ cards.add(new SetCardInfo("Pious Warrior", 34, Rarity.COMMON, mage.cards.p.PiousWarrior.class));
+ cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Port Inspector", 90, Rarity.COMMON, mage.cards.p.PortInspector.class));
+ cards.add(new SetCardInfo("Power Matrix", 309, Rarity.RARE, mage.cards.p.PowerMatrix.class));
+ cards.add(new SetCardInfo("Pretender's Claim", 151, Rarity.UNCOMMON, mage.cards.p.PretendersClaim.class));
+ cards.add(new SetCardInfo("Primeval Shambler", 152, Rarity.UNCOMMON, mage.cards.p.PrimevalShambler.class));
+ cards.add(new SetCardInfo("Puffer Extract", 310, Rarity.UNCOMMON, mage.cards.p.PufferExtract.class));
+ cards.add(new SetCardInfo("Pulverize", 207, Rarity.RARE, mage.cards.p.Pulverize.class));
+ cards.add(new SetCardInfo("Putrefaction", 153, Rarity.UNCOMMON, mage.cards.p.Putrefaction.class));
+ cards.add(new SetCardInfo("Puppet's Verdict", 208, Rarity.RARE, mage.cards.p.PuppetsVerdict.class));
+ cards.add(new SetCardInfo("Quagmire Lamprey", 154, Rarity.UNCOMMON, mage.cards.q.QuagmireLamprey.class));
+ cards.add(new SetCardInfo("Rain of Tears", 155, Rarity.UNCOMMON, mage.cards.r.RainOfTears.class));
+ cards.add(new SetCardInfo("Ramosian Captain", 35, Rarity.UNCOMMON, mage.cards.r.RamosianCaptain.class));
+ cards.add(new SetCardInfo("Ramosian Commander", 36, Rarity.UNCOMMON, mage.cards.r.RamosianCommander.class));
+ cards.add(new SetCardInfo("Ramosian Lieutenant", 37, Rarity.COMMON, mage.cards.r.RamosianLieutenant.class));
+ cards.add(new SetCardInfo("Ramosian Rally", 38, Rarity.COMMON, mage.cards.r.RamosianRally.class));
+ cards.add(new SetCardInfo("Ramosian Sergeant", 39, Rarity.COMMON, mage.cards.r.RamosianSergeant.class));
+ cards.add(new SetCardInfo("Ramosian Sky Marshal", 40, Rarity.RARE, mage.cards.r.RamosianSkyMarshal.class));
+ cards.add(new SetCardInfo("Rampart Crawler", 156, Rarity.COMMON, mage.cards.r.RampartCrawler.class));
+ cards.add(new SetCardInfo("Rappelling Scouts", 41, Rarity.RARE, mage.cards.r.RappellingScouts.class));
+ cards.add(new SetCardInfo("Remote Farm", 323, Rarity.COMMON, mage.cards.r.RemoteFarm.class));
+ cards.add(new SetCardInfo("Renounce", 42, Rarity.UNCOMMON, mage.cards.r.Renounce.class));
+ cards.add(new SetCardInfo("Revered Elder", 43, Rarity.COMMON, mage.cards.r.ReveredElder.class));
+ cards.add(new SetCardInfo("Reverent Mantra", 44, Rarity.RARE, mage.cards.r.ReverentMantra.class));
+ cards.add(new SetCardInfo("Revive", 262, Rarity.UNCOMMON, mage.cards.r.Revive.class));
+ cards.add(new SetCardInfo("Righteous Aura", 45, Rarity.UNCOMMON, mage.cards.r.RighteousAura.class));
+ cards.add(new SetCardInfo("Righteous Indignation", 46, Rarity.UNCOMMON, mage.cards.r.RighteousIndignation.class));
+ cards.add(new SetCardInfo("Rishadan Airship", 91, Rarity.COMMON, mage.cards.r.RishadanAirship.class));
+ cards.add(new SetCardInfo("Rishadan Brigand", 92, Rarity.RARE, mage.cards.r.RishadanBrigand.class));
+ cards.add(new SetCardInfo("Rishadan Cutpurse", 93, Rarity.COMMON, mage.cards.r.RishadanCutpurse.class));
+ cards.add(new SetCardInfo("Rishadan Footpad", 94, Rarity.UNCOMMON, mage.cards.r.RishadanFootpad.class));
+ cards.add(new SetCardInfo("Rishadan Pawnshop", 311, Rarity.RARE, mage.cards.r.RishadanPawnshop.class));
+ cards.add(new SetCardInfo("Rishadan Port", 324, Rarity.RARE, mage.cards.r.RishadanPort.class));
+ cards.add(new SetCardInfo("Robber Fly", 209, Rarity.UNCOMMON, mage.cards.r.RobberFly.class));
+ cards.add(new SetCardInfo("Rock Badger", 210, Rarity.UNCOMMON, mage.cards.r.RockBadger.class));
+ cards.add(new SetCardInfo("Rouse", 157, Rarity.COMMON, mage.cards.r.Rouse.class));
+ cards.add(new SetCardInfo("Rushwood Dryad", 263, Rarity.COMMON, mage.cards.r.RushwoodDryad.class));
+ cards.add(new SetCardInfo("Rushwood Elemental", 264, Rarity.RARE, mage.cards.r.RushwoodElemental.class));
+ cards.add(new SetCardInfo("Rushwood Grove", 325, Rarity.UNCOMMON, mage.cards.r.RushwoodGrove.class));
+ cards.add(new SetCardInfo("Rushwood Herbalist", 265, Rarity.COMMON, mage.cards.r.RushwoodHerbalist.class));
+ cards.add(new SetCardInfo("Rushwood Legate", 266, Rarity.UNCOMMON, mage.cards.r.RushwoodLegate.class));
+ cards.add(new SetCardInfo("Saber Ants", 267, Rarity.UNCOMMON, mage.cards.s.SaberAnts.class));
+ cards.add(new SetCardInfo("Sacred Prey", 268, Rarity.COMMON, mage.cards.s.SacredPrey.class));
+ cards.add(new SetCardInfo("Sailmonger", 95, Rarity.UNCOMMON, mage.cards.s.Sailmonger.class));
+ cards.add(new SetCardInfo("Sand Squid", 96, Rarity.RARE, mage.cards.s.SandSquid.class));
+ cards.add(new SetCardInfo("Sandstone Needle", 326, Rarity.COMMON, mage.cards.s.SandstoneNeedle.class));
+ cards.add(new SetCardInfo("Saprazzan Bailiff", 97, Rarity.RARE, mage.cards.s.SaprazzanBailiff.class));
+ cards.add(new SetCardInfo("Saprazzan Breaker", 98, Rarity.UNCOMMON, mage.cards.s.SaprazzanBreaker.class));
+ cards.add(new SetCardInfo("Saprazzan Cove", 327, Rarity.UNCOMMON, mage.cards.s.SaprazzanCove.class));
+ cards.add(new SetCardInfo("Saprazzan Heir", 99, Rarity.RARE, mage.cards.s.SaprazzanHeir.class));
+ cards.add(new SetCardInfo("Saprazzan Legate", 100, Rarity.UNCOMMON, mage.cards.s.SaprazzanLegate.class));
+ cards.add(new SetCardInfo("Saprazzan Outrigger", 101, Rarity.COMMON, mage.cards.s.SaprazzanOutrigger.class));
+ cards.add(new SetCardInfo("Saprazzan Raider", 102, Rarity.COMMON, mage.cards.s.SaprazzanRaider.class));
+ cards.add(new SetCardInfo("Saprazzan Skerry", 328, Rarity.COMMON, mage.cards.s.SaprazzanSkerry.class));
+ cards.add(new SetCardInfo("Scandalmonger", 158, Rarity.UNCOMMON, mage.cards.s.Scandalmonger.class));
+ cards.add(new SetCardInfo("Security Detail", 47, Rarity.RARE, mage.cards.s.SecurityDetail.class));
+ cards.add(new SetCardInfo("Seismic Mage", 211, Rarity.RARE, mage.cards.s.SeismicMage.class));
+ cards.add(new SetCardInfo("Sever Soul", 159, Rarity.COMMON, mage.cards.s.SeverSoul.class));
+ cards.add(new SetCardInfo("Shock Troops", 212, Rarity.COMMON, mage.cards.s.ShockTroops.class));
+ cards.add(new SetCardInfo("Shoving Match", 103, Rarity.UNCOMMON, mage.cards.s.ShovingMatch.class));
+ cards.add(new SetCardInfo("Silent Assassin", 160, Rarity.RARE, mage.cards.s.SilentAssassin.class));
+ cards.add(new SetCardInfo("Silverglade Elemental", 269, Rarity.COMMON, mage.cards.s.SilvergladeElemental.class));
+ cards.add(new SetCardInfo("Silverglade Pathfinder", 270, Rarity.UNCOMMON, mage.cards.s.SilvergladePathfinder.class));
+ cards.add(new SetCardInfo("Sizzle", 213, Rarity.COMMON, mage.cards.s.Sizzle.class));
+ cards.add(new SetCardInfo("Skulking Fugitive", 161, Rarity.COMMON, mage.cards.s.SkulkingFugitive.class));
+ cards.add(new SetCardInfo("Skull of Ramos", 312, Rarity.RARE, mage.cards.s.SkullOfRamos.class));
+ cards.add(new SetCardInfo("Snake Pit", 271, Rarity.UNCOMMON, mage.cards.s.SnakePit.class));
+ cards.add(new SetCardInfo("Snorting Gahr", 272, Rarity.COMMON, mage.cards.s.SnortingGahr.class));
+ cards.add(new SetCardInfo("Snuff Out", 162, Rarity.COMMON, mage.cards.s.SnuffOut.class));
+ cards.add(new SetCardInfo("Soothing Balm", 48, Rarity.COMMON, mage.cards.s.SoothingBalm.class));
+ cards.add(new SetCardInfo("Soothsaying", 104, Rarity.UNCOMMON, mage.cards.s.Soothsaying.class));
+ cards.add(new SetCardInfo("Soul Channeling", 163, Rarity.COMMON, mage.cards.s.SoulChanneling.class));
+ cards.add(new SetCardInfo("Specter's Wail", 164, Rarity.COMMON, mage.cards.s.SpectersWail.class));
+ cards.add(new SetCardInfo("Spidersilk Armor", 273, Rarity.COMMON, mage.cards.s.SpidersilkArmor.class));
+ cards.add(new SetCardInfo("Spiritual Focus", 49, Rarity.RARE, mage.cards.s.SpiritualFocus.class));
+ cards.add(new SetCardInfo("Spontaneous Generation", 274, Rarity.RARE, mage.cards.s.SpontaneousGeneration.class));
+ cards.add(new SetCardInfo("Squall", 275, Rarity.COMMON, mage.cards.s.Squall.class));
+ cards.add(new SetCardInfo("Squallmonger", 276, Rarity.UNCOMMON, mage.cards.s.Squallmonger.class));
+ cards.add(new SetCardInfo("Squee, Goblin Nabob", 214, Rarity.RARE, mage.cards.s.SqueeGoblinNabob.class));
+ cards.add(new SetCardInfo("Squeeze", 105, Rarity.RARE, mage.cards.s.Squeeze.class));
+ cards.add(new SetCardInfo("Stamina", 277, Rarity.UNCOMMON, mage.cards.s.Stamina.class));
+ cards.add(new SetCardInfo("Statecraft", 106, Rarity.RARE, mage.cards.s.Statecraft.class));
+ cards.add(new SetCardInfo("Steadfast Guard", 50, Rarity.COMMON, mage.cards.s.SteadfastGuard.class));
+ cards.add(new SetCardInfo("Stinging Barrier", 107, Rarity.COMMON, mage.cards.s.StingingBarrier.class));
+ cards.add(new SetCardInfo("Stone Rain", 215, Rarity.COMMON, mage.cards.s.StoneRain.class));
+ cards.add(new SetCardInfo("Story Circle", 51, Rarity.UNCOMMON, mage.cards.s.StoryCircle.class));
+ cards.add(new SetCardInfo("Strongarm Thug", 165, Rarity.UNCOMMON, mage.cards.s.StrongarmThug.class));
+ cards.add(new SetCardInfo("Subterranean Hangar", 329, Rarity.UNCOMMON, mage.cards.s.SubterraneanHangar.class));
+ cards.add(new SetCardInfo("Sustenance", 278, Rarity.UNCOMMON, mage.cards.s.Sustenance.class));
+ cards.add(new SetCardInfo("Swamp", 339, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Swamp", 340, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Swamp", 341, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Swamp", 342, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Task Force", 52, Rarity.COMMON, mage.cards.t.TaskForce.class));
+ cards.add(new SetCardInfo("Tectonic Break", 216, Rarity.RARE, mage.cards.t.TectonicBreak.class));
+ cards.add(new SetCardInfo("Territorial Dispute", 217, Rarity.RARE, mage.cards.t.TerritorialDispute.class));
+ cards.add(new SetCardInfo("Thermal Glider", 53, Rarity.COMMON, mage.cards.t.ThermalGlider.class));
+ cards.add(new SetCardInfo("Thieves' Auction", 218, Rarity.RARE, mage.cards.t.ThievesAuction.class));
+ cards.add(new SetCardInfo("Thrashing Wumpus", 166, Rarity.RARE, mage.cards.t.ThrashingWumpus.class));
+ cards.add(new SetCardInfo("Thunderclap", 219, Rarity.COMMON, mage.cards.t.Thunderclap.class));
+ cards.add(new SetCardInfo("Thwart", 108, Rarity.UNCOMMON, mage.cards.t.Thwart.class));
+ cards.add(new SetCardInfo("Tidal Bore", 109, Rarity.COMMON, mage.cards.t.TidalBore.class));
+ cards.add(new SetCardInfo("Tidal Kraken", 110, Rarity.RARE, mage.cards.t.TidalKraken.class));
+ cards.add(new SetCardInfo("Tiger Claws", 279, Rarity.COMMON, mage.cards.t.TigerClaws.class));
+ cards.add(new SetCardInfo("Timid Drake", 111, Rarity.UNCOMMON, mage.cards.t.TimidDrake.class));
+ cards.add(new SetCardInfo("Tonic Peddler", 54, Rarity.UNCOMMON, mage.cards.t.TonicPeddler.class));
+ cards.add(new SetCardInfo("Tooth of Ramos", 313, Rarity.RARE, mage.cards.t.ToothOfRamos.class));
+ cards.add(new SetCardInfo("Tower of the Magistrate", 330, Rarity.RARE, mage.cards.t.TowerOfTheMagistrate.class));
+ cards.add(new SetCardInfo("Toymaker", 314, Rarity.UNCOMMON, mage.cards.t.Toymaker.class));
+ cards.add(new SetCardInfo("Trade Routes", 112, Rarity.RARE, mage.cards.t.TradeRoutes.class));
+ cards.add(new SetCardInfo("Tranquility", 280, Rarity.COMMON, mage.cards.t.Tranquility.class));
+ cards.add(new SetCardInfo("Trap Runner", 55, Rarity.UNCOMMON, mage.cards.t.TrapRunner.class));
+ cards.add(new SetCardInfo("Tremor", 220, Rarity.COMMON, mage.cards.t.Tremor.class));
+ cards.add(new SetCardInfo("Two-Headed Dragon", 221, Rarity.RARE, mage.cards.t.TwoHeadedDragon.class));
+ cards.add(new SetCardInfo("Undertaker", 167, Rarity.COMMON, mage.cards.u.Undertaker.class));
+ cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class));
+ cards.add(new SetCardInfo("Unnatural Hunger", 169, Rarity.RARE, mage.cards.u.UnnaturalHunger.class));
+ cards.add(new SetCardInfo("Uphill Battle", 222, Rarity.UNCOMMON, mage.cards.u.UphillBattle.class));
+ cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class));
+ cards.add(new SetCardInfo("Venomous Breath", 281, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class));
+ cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class));
+ cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class));
+ cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class));
+ cards.add(new SetCardInfo("Vine Trellis", 285, Rarity.COMMON, mage.cards.v.VineTrellis.class));
+ cards.add(new SetCardInfo("Volcanic Wind", 223, Rarity.UNCOMMON, mage.cards.v.VolcanicWind.class));
+ cards.add(new SetCardInfo("Wall of Distortion", 171, Rarity.COMMON, mage.cards.w.WallOfDistortion.class));
+ cards.add(new SetCardInfo("War Cadence", 224, Rarity.UNCOMMON, mage.cards.w.WarCadence.class));
+ cards.add(new SetCardInfo("War Tax", 113, Rarity.UNCOMMON, mage.cards.w.WarTax.class));
+ cards.add(new SetCardInfo("Warmonger", 225, Rarity.UNCOMMON, mage.cards.w.Warmonger.class));
+ cards.add(new SetCardInfo("Warpath", 226, Rarity.UNCOMMON, mage.cards.w.Warpath.class));
+ cards.add(new SetCardInfo("Waterfront Bouncer", 114, Rarity.COMMON, mage.cards.w.WaterfrontBouncer.class));
+ cards.add(new SetCardInfo("Wave of Reckoning", 56, Rarity.RARE, mage.cards.w.WaveOfReckoning.class));
+ cards.add(new SetCardInfo("Wild Jhovall", 227, Rarity.COMMON, mage.cards.w.WildJhovall.class));
+ cards.add(new SetCardInfo("Wishmonger", 57, Rarity.UNCOMMON, mage.cards.w.Wishmonger.class));
+ cards.add(new SetCardInfo("Word of Blasting", 228, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.class));
+ cards.add(new SetCardInfo("Worry Beads", 315, Rarity.RARE, mage.cards.w.WorryBeads.class));
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CumulativeUpkeepTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CumulativeUpkeepTest.java
index 8c00b671fd..a5fc11b7f3 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CumulativeUpkeepTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/CumulativeUpkeepTest.java
@@ -1,110 +1,110 @@
-
-package org.mage.test.cards.abilities.keywords;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.counters.CounterType;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class CumulativeUpkeepTest extends CardTestPlayerBase {
-
- @Test
- public void basicTest() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
- // Flying; fear
- // Cumulative upkeep {B}
- addCard(Zone.HAND, playerA, "Phobian Phantasm"); // Creature {1}{B}{B} 3/3
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm");
-
- // Phobian Phantasm - CumulativeUpkeepAbility: Cumulative upkeep {B}
- setChoice(playerA, true); // Pay {B}?
- attack(3, playerA, "Phobian Phantasm");
- checkPermanentCounters("Age counters", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm", CounterType.AGE, 1);
-
- setChoice(playerA, true); // Pay {B}{B}?
- attack(5, playerA, "Phobian Phantasm");
- checkPermanentCounters("Age counters", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm", CounterType.AGE, 2);
-
- setChoice(playerA, false); // Pay {B}{B}{B}?
-
- setStopAt(7, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Phobian Phantasm", 1);
-
- assertLife(playerA, 20);
- assertLife(playerB, 14);
- }
-
-
- /**
- I changed control of a Illusions of Grandeur to an AI after cumulative upkeep had triggered but before it resolved.
- I chose not to pay the upkeep cost and then either the AI sacrificed it or I sacrificed it, neither of which should happen.
- I can't sacrifice it because it's not under my control. The AI can't sacrifice it because they are not instructed to do so.
-
- Here is the reminder text for cumulative upkeep:
- At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.
- */
- @Test
- public void controlChangeTest() {
- setStrictChooseMode(true);
-
- // Whenever Kor Celebrant or another creature enters the battlefield under your control, you gain 1 life.
- addCard(Zone.HAND, playerB, "Kor Celebrant", 1); // Creature {2}{W}
- addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
-
- addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
- // Cumulative upkeep {2}
- // When Illusions of Grandeur enters the battlefield, you gain 20 life.
- // When Illusions of Grandeur leaves the battlefield, you lose 20 life.
- addCard(Zone.HAND, playerA, "Illusions of Grandeur"); // Enchantment {3}{U}
-
- // At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
- addCard(Zone.HAND, playerA, "Puca's Mischief"); // Enchantment {3}{U}
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Illusions of Grandeur");
-
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Kor Celebrant");
-
- // Illusions of Grandeur - CumulativeUpkeepAbility: Cumulative upkeep {2}
- setChoice(playerA, true); // Pay {2}?
-
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Puca's Mischief");
-
- setChoice(playerA, "Cumulative upkeep"); // Triggered list (total 2) which trigger goes first on the stack
- addTarget(playerA, "Illusions of Grandeur"); // Own target permanent of Puca's Mischief
- addTarget(playerA, "Kor Celebrant"); // Opponent's target permanent of Puca's Mischief
-
- setChoice(playerA, true); // At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
- setChoice(playerA, false); // Pay {2}{2}?
-
- checkPermanentCounters("Age counters", 5, PhaseStep.PRECOMBAT_MAIN, playerB, "Illusions of Grandeur", CounterType.AGE, 2);
-
- setStopAt(5, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertLife(playerA, 40);
- assertLife(playerB, 21);
-
- assertPermanentCount(playerA, "Kor Celebrant", 1);
- assertPermanentCount(playerB, "Illusions of Grandeur", 1);
-
-
- }
-
-
+
+package org.mage.test.cards.abilities.keywords;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class CumulativeUpkeepTest extends CardTestPlayerBase {
+
+ @Test
+ public void basicTest() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
+ // Flying; fear
+ // Cumulative upkeep {B}
+ addCard(Zone.HAND, playerA, "Phobian Phantasm"); // Creature {1}{B}{B} 3/3
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm");
+
+ // Phobian Phantasm - CumulativeUpkeepAbility: Cumulative upkeep {B}
+ setChoice(playerA, true); // Pay {B}?
+ attack(3, playerA, "Phobian Phantasm");
+ checkPermanentCounters("Age counters", 3, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm", CounterType.AGE, 1);
+
+ setChoice(playerA, true); // Pay {B}{B}?
+ attack(5, playerA, "Phobian Phantasm");
+ checkPermanentCounters("Age counters", 5, PhaseStep.PRECOMBAT_MAIN, playerA, "Phobian Phantasm", CounterType.AGE, 2);
+
+ setChoice(playerA, false); // Pay {B}{B}{B}?
+
+ setStopAt(7, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Phobian Phantasm", 1);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 14);
+ }
+
+
+ /**
+ I changed control of a Illusions of Grandeur to an AI after cumulative upkeep had triggered but before it resolved.
+ I chose not to pay the upkeep cost and then either the AI sacrificed it or I sacrificed it, neither of which should happen.
+ I can't sacrifice it because it's not under my control. The AI can't sacrifice it because they are not instructed to do so.
+
+ Here is the reminder text for cumulative upkeep:
+ At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.
+ */
+ @Test
+ public void controlChangeTest() {
+ setStrictChooseMode(true);
+
+ // Whenever Kor Celebrant or another creature enters the battlefield under your control, you gain 1 life.
+ addCard(Zone.HAND, playerB, "Kor Celebrant", 1); // Creature {2}{W}
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 3);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
+ // Cumulative upkeep {2}
+ // When Illusions of Grandeur enters the battlefield, you gain 20 life.
+ // When Illusions of Grandeur leaves the battlefield, you lose 20 life.
+ addCard(Zone.HAND, playerA, "Illusions of Grandeur"); // Enchantment {3}{U}
+
+ // At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
+ addCard(Zone.HAND, playerA, "Puca's Mischief"); // Enchantment {3}{U}
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Illusions of Grandeur");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Kor Celebrant");
+
+ // Illusions of Grandeur - CumulativeUpkeepAbility: Cumulative upkeep {2}
+ setChoice(playerA, true); // Pay {2}?
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Puca's Mischief");
+
+ setChoice(playerA, "Cumulative upkeep"); // Triggered list (total 2) which trigger goes first on the stack
+ addTarget(playerA, "Illusions of Grandeur"); // Own target permanent of Puca's Mischief
+ addTarget(playerA, "Kor Celebrant"); // Opponent's target permanent of Puca's Mischief
+
+ setChoice(playerA, true); // At the beginning of your upkeep, you may exchange control of target nonland permanent you control and target nonland permanent an opponent controls with an equal or lesser converted mana cost.
+ setChoice(playerA, false); // Pay {2}{2}?
+
+ checkPermanentCounters("Age counters", 5, PhaseStep.PRECOMBAT_MAIN, playerB, "Illusions of Grandeur", CounterType.AGE, 2);
+
+ setStopAt(5, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 40);
+ assertLife(playerB, 21);
+
+ assertPermanentCount(playerA, "Kor Celebrant", 1);
+ assertPermanentCount(playerB, "Illusions of Grandeur", 1);
+
+
+ }
+
+
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EntwineTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EntwineTest.java
index 787d9d59f0..1946604d6f 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EntwineTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/EntwineTest.java
@@ -1,179 +1,179 @@
-package org.mage.test.cards.abilities.keywords;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- * @author LevelX2, JayDi85
- */
-
-public class EntwineTest extends CardTestPlayerBase {
-
- @Test
- public void test_CastWithoutEntwine() {
- // Choose one —
- //• Barbed Lightning deals 3 damage to target creature.
- //• Barbed Lightning deals 3 damage to target player or planeswalker.
- // Entwine {2} (Choose both if you pay the entwine cost.)
- addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
- //
- addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
- setChoice(playerA, false); // not use Entwine
- setModeChoice(playerA, "1"); // target creature
- addTarget(playerA, "Balduvian Bears");
-
- setStrictChooseMode(true);
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20);
- assertPermanentCount(playerA, "Balduvian Bears", 0);
- assertTappedCount("Mountain", true, 3);
- }
-
- @Test
- public void test_CastEntwine_Normal() {
- // Choose one —
- //• Barbed Lightning deals 3 damage to target creature.
- //• Barbed Lightning deals 3 damage to target player or planeswalker.
- // Entwine {2} (Choose both if you pay the entwine cost.)
- addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3 + 2);
- //
- addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
- setChoice(playerA, true); // use Entwine
- addTarget(playerA, "Balduvian Bears");
- addTarget(playerA, playerA);
-
- setStrictChooseMode(true);
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20 - 3);
- assertPermanentCount(playerA, "Balduvian Bears", 0);
- assertTappedCount("Mountain", true, 3 + 2);
- }
-
- @Test
- public void test_CastEntwine_CostReduction() {
- addCustomEffect_SpellCostModification(playerA, -4);
-
- // Choose one —
- //• Barbed Lightning deals 3 damage to target creature.
- //• Barbed Lightning deals 3 damage to target player or planeswalker.
- // Entwine {2} (Choose both if you pay the entwine cost.)
- addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); // -4 as cost reduction
- //
- addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
- setChoice(playerA, true); // use Entwine
- addTarget(playerA, "Balduvian Bears");
- addTarget(playerA, playerA);
-
- setStrictChooseMode(true);
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20 - 3);
- assertPermanentCount(playerA, "Balduvian Bears", 0);
- assertTappedCount("Mountain", true, 1);
- }
-
- @Test
- public void test_CastEntwine_CostIncreasing() {
- addCustomEffect_SpellCostModification(playerA, 5);
-
- // Choose one —
- //• Barbed Lightning deals 3 damage to target creature.
- //• Barbed Lightning deals 3 damage to target player or planeswalker.
- // Entwine {2} (Choose both if you pay the entwine cost.)
- addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3 + 2 + 5);
- //
- addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
- setChoice(playerA, true); // use Entwine
- addTarget(playerA, "Balduvian Bears");
- addTarget(playerA, playerA);
-
- setStrictChooseMode(true);
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20 - 3);
- assertPermanentCount(playerA, "Balduvian Bears", 0);
- assertTappedCount("Mountain", true, 3 + 2 + 5);
- }
-
- @Test
- public void test_CastEntwine_FreeFromHand() {
- // You may cast nonland cards from your hand without paying their mana costs.
- addCard(Zone.BATTLEFIELD, playerA, "Omniscience");
-
- // Choose one —
- //• Barbed Lightning deals 3 damage to target creature.
- //• Barbed Lightning deals 3 damage to target player or planeswalker.
- // Entwine {2} (Choose both if you pay the entwine cost.)
- addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); // only Entwine pay need
- //
- addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
- setChoice(playerA, true); // cast for free
- setChoice(playerA, true); // use Entwine
- addTarget(playerA, "Balduvian Bears");
- addTarget(playerA, playerA);
-
- setStrictChooseMode(true);
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20 - 3);
- assertPermanentCount(playerA, "Balduvian Bears", 0);
- assertTappedCount("Plains", true, 2);
- }
-
- @Test
- public void test_ToothAndNail() {
- setStrictChooseMode(true);
-
- addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
- addCard(Zone.LIBRARY, playerA, "Pillarfield Ox", 1);
-
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 9);
- // Choose one -
- // Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library;
- // or put up to two creature cards from your hand onto the battlefield.
- // Entwine {2}
- addCard(Zone.HAND, playerA, "Tooth and Nail"); // Sorcery {5}{G}{G}
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tooth and Nail");
- setChoice(playerA, true); // Message: Pay Entwine {2} ?
- addTarget(playerA, "Silvercoat Lion^Pillarfield Ox");
- setChoice(playerA, "Silvercoat Lion^Pillarfield Ox");
-
- setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
- execute();
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Silvercoat Lion", 1);
- assertPermanentCount(playerA, "Pillarfield Ox", 1);
- }
-}
+package org.mage.test.cards.abilities.keywords;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author LevelX2, JayDi85
+ */
+
+public class EntwineTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_CastWithoutEntwine() {
+ // Choose one —
+ //• Barbed Lightning deals 3 damage to target creature.
+ //• Barbed Lightning deals 3 damage to target player or planeswalker.
+ // Entwine {2} (Choose both if you pay the entwine cost.)
+ addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+ //
+ addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
+ setChoice(playerA, false); // not use Entwine
+ setModeChoice(playerA, "1"); // target creature
+ addTarget(playerA, "Balduvian Bears");
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20);
+ assertPermanentCount(playerA, "Balduvian Bears", 0);
+ assertTappedCount("Mountain", true, 3);
+ }
+
+ @Test
+ public void test_CastEntwine_Normal() {
+ // Choose one —
+ //• Barbed Lightning deals 3 damage to target creature.
+ //• Barbed Lightning deals 3 damage to target player or planeswalker.
+ // Entwine {2} (Choose both if you pay the entwine cost.)
+ addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3 + 2);
+ //
+ addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
+ setChoice(playerA, true); // use Entwine
+ addTarget(playerA, "Balduvian Bears");
+ addTarget(playerA, playerA);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20 - 3);
+ assertPermanentCount(playerA, "Balduvian Bears", 0);
+ assertTappedCount("Mountain", true, 3 + 2);
+ }
+
+ @Test
+ public void test_CastEntwine_CostReduction() {
+ addCustomEffect_SpellCostModification(playerA, -4);
+
+ // Choose one —
+ //• Barbed Lightning deals 3 damage to target creature.
+ //• Barbed Lightning deals 3 damage to target player or planeswalker.
+ // Entwine {2} (Choose both if you pay the entwine cost.)
+ addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); // -4 as cost reduction
+ //
+ addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
+ setChoice(playerA, true); // use Entwine
+ addTarget(playerA, "Balduvian Bears");
+ addTarget(playerA, playerA);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20 - 3);
+ assertPermanentCount(playerA, "Balduvian Bears", 0);
+ assertTappedCount("Mountain", true, 1);
+ }
+
+ @Test
+ public void test_CastEntwine_CostIncreasing() {
+ addCustomEffect_SpellCostModification(playerA, 5);
+
+ // Choose one —
+ //• Barbed Lightning deals 3 damage to target creature.
+ //• Barbed Lightning deals 3 damage to target player or planeswalker.
+ // Entwine {2} (Choose both if you pay the entwine cost.)
+ addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3 + 2 + 5);
+ //
+ addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
+ setChoice(playerA, true); // use Entwine
+ addTarget(playerA, "Balduvian Bears");
+ addTarget(playerA, playerA);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20 - 3);
+ assertPermanentCount(playerA, "Balduvian Bears", 0);
+ assertTappedCount("Mountain", true, 3 + 2 + 5);
+ }
+
+ @Test
+ public void test_CastEntwine_FreeFromHand() {
+ // You may cast nonland cards from your hand without paying their mana costs.
+ addCard(Zone.BATTLEFIELD, playerA, "Omniscience");
+
+ // Choose one —
+ //• Barbed Lightning deals 3 damage to target creature.
+ //• Barbed Lightning deals 3 damage to target player or planeswalker.
+ // Entwine {2} (Choose both if you pay the entwine cost.)
+ addCard(Zone.HAND, playerA, "Barbed Lightning", 1); // {2}{R}
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); // only Entwine pay need
+ //
+ addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Barbed Lightning");
+ setChoice(playerA, true); // cast for free
+ setChoice(playerA, true); // use Entwine
+ addTarget(playerA, "Balduvian Bears");
+ addTarget(playerA, playerA);
+
+ setStrictChooseMode(true);
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20 - 3);
+ assertPermanentCount(playerA, "Balduvian Bears", 0);
+ assertTappedCount("Plains", true, 2);
+ }
+
+ @Test
+ public void test_ToothAndNail() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
+ addCard(Zone.LIBRARY, playerA, "Pillarfield Ox", 1);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 9);
+ // Choose one -
+ // Search your library for up to two creature cards, reveal them, put them into your hand, then shuffle your library;
+ // or put up to two creature cards from your hand onto the battlefield.
+ // Entwine {2}
+ addCard(Zone.HAND, playerA, "Tooth and Nail"); // Sorcery {5}{G}{G}
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tooth and Nail");
+ setChoice(playerA, true); // Message: Pay Entwine {2} ?
+ addTarget(playerA, "Silvercoat Lion^Pillarfield Ox");
+ setChoice(playerA, "Silvercoat Lion^Pillarfield Ox");
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Silvercoat Lion", 1);
+ assertPermanentCount(playerA, "Pillarfield Ox", 1);
+ }
+}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
index a3c7ccfce2..125476f40e 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java
@@ -1,540 +1,540 @@
-package org.mage.test.cards.abilities.keywords;
-
-import mage.cards.Card;
-import mage.constants.EmptyNames;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.game.permanent.Permanent;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- * @author LevelX2
- */
-public class ManifestTest extends CardTestPlayerBase {
-
- /**
- * Tests that ETB triggered abilities did not trigger for manifested cards
- */
- @Test
- public void testETBTriggeredAbilities() {
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
- // Manifest the top card of your library {1}{W}
- addCard(Zone.HAND, playerA, "Soul Summons");
-
- // Tranquil Cove enters the battlefield tapped.
- // When Tranquil Cove enters the battlefield, you gain 1 life.
- // {T}: Add {W} or {U}.
- addCard(Zone.LIBRARY, playerA, "Tranquil Cove");
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- // a facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
- assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
- // not tapped
- assertTapped(EmptyNames.FACE_DOWN_CREATURE.toString(), false);
- }
-
- /**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not
- * trigger
- */
- @Test
- public void testETBTriggeredAbilities2() {
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
- // Manifest the top card of your library {1}{W}
- addCard(Zone.HAND, playerA, "Soul Summons");
-
- // Constellation - When Doomwake Giant or another enchantment enters the battlefield
- // under your control, creatures your opponents control get -1/-1 until end of turn.
- addCard(Zone.LIBRARY, playerA, "Doomwake Giant");
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- // a facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
- assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
- // PlayerB's Silvercoat Lion should not have get -1/-1/
- assertPermanentCount(playerB, "Silvercoat Lion", 1);
- assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
- }
-
- /**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not
- * trigger
- */
- @Test
- public void testETBTriggeredAbilities3() {
- addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
- // Exile target creature. Its controller manifests the top card of their library {1}{U}
- addCard(Zone.HAND, playerB, "Reality Shift");
-
- // Constellation - When Doomwake Giant or another enchantment enters the battlefield
- // under your control, creatures your opponents control get -1/-1 until end of turn.
- addCard(Zone.LIBRARY, playerA, "Doomwake Giant");
-
- addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
-
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion", 1);
- // a facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
- assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
- // PlayerA's Pillarfield Ox should not have get -1/-1/
- assertPermanentCount(playerB, "Pillarfield Ox", 1);
- assertPowerToughness(playerB, "Pillarfield Ox", 2, 4);
- }
-
- /**
- * If Doomwake Giant gets manifested, it's Constellation trigger may not
- * trigger
- */
- @Test
- public void testNylea() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
- // Exile target creature. Its controller manifests the top card of their library {1}{U}
- addCard(Zone.HAND, playerB, "Reality Shift");
-
- // As long as your devotion to white is less than five, Nylea isn't a creature.
- // (Each {G} in the mana costs of permanents you control counts towards your devotion to green.)
- addCard(Zone.LIBRARY, playerA, "Nylea, God of the Hunt");
-
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
-
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion", 1);
- // a facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
- assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
-
- }
-
- /*
- Had a Foundry Street Denizen and another creature out.
- Opponent Reality Shift'ed the other creature, manifested card was a red creature. This pumped the foundry street denizen even though it shouldn't.
- */
- @Test
- public void testColorOfManifestedCardDoesNotCount() {
- addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
- // Exile target creature. Its controller manifests the top card of their library {1}{U}
- addCard(Zone.HAND, playerB, "Reality Shift");
-
- // Gore Swine {2}{R}
- // 4/1
- addCard(Zone.LIBRARY, playerA, "Gore Swine");
-
- // Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
- addCard(Zone.BATTLEFIELD, playerA, "Foundry Street Denizen");
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
-
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion", 1);
- // a facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
- assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
- assertPowerToughness(playerA, "Foundry Street Denizen", 1, 1);
-
- }
-
- /*
- I casted a Silence the Believers on a manifested card. It moved to the exile zone face-down.
- */
- @Test
- public void testCardGetsExiledFaceUp() {
- addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4);
- // Exile target creature. Its controller manifests the top card of their library {1}{U}
- addCard(Zone.HAND, playerB, "Reality Shift");
- // Silence the Believers - Instant {2}{B}{B}
- // Strive — Silence the Believers costs more to cast for each target beyond the first.
- // Exile any number of target creatures and all Auras attached to them.
- addCard(Zone.HAND, playerB, "Silence the Believers");
- // Gore Swine {2}{R}
- // 4/1
- addCard(Zone.LIBRARY, playerA, "Gore Swine");
-
- // Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
-
- skipInitShuffling();
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
- // showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
- // showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Silence the Believers", EmptyNames.FACE_DOWN_CREATURE.toString());
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- assertGraveyardCount(playerB, "Reality Shift", 1);
- assertExileCount("Silvercoat Lion", 1);
- assertExileCount("Gore Swine", 1);
- // no facedown creature is on the battlefield
- assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
-
- for (Card card : currentGame.getExile().getAllCards(currentGame)) {
- if (card.getName().equals("Gore Swine")) {
- Assert.assertTrue("Gore Swine may not be face down in exile", !card.isFaceDown(currentGame));
- }
- }
-
- }
-
- // Qarsi High Priest went to manifest Illusory Gains,
- // but it made me choose a target for gains, then enchanted the card to that creature.
- @Test
- public void testManifestAura() {
-
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- addCard(Zone.LIBRARY, playerB, "Illusory Gains", 1);
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- setStopAt(2, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertGraveyardCount(playerB, "Illusory Gains", 0);
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
-
- // a facedown creature is on the battlefield
- assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
-
- }
-
- // Check if a Megamorph card is manifested and turned face up by their megamorph ability
- // it gets the +1/+1 counter.
- // 701.33c
- // If a card with morph is manifested, its controller may turn that card face up using
- // either the procedure described in rule 702.36e to turn a face-down permanent with morph face up
- // or the procedure described above to turn a manifested permanent face up.
- @Test
- public void testManifestMegamorph_TurnUpByMegamorphCost() {
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
- addCard(Zone.BATTLEFIELD, playerB, "Forest", 6);
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- // Reach (This creature can block creatures with flying.)
- // Megamorph {5}{G}
- addCard(Zone.LIBRARY, playerB, "Aerie Bowmasters", 1);
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{5}{G}: Turn");
-
- setStrictChooseMode(true);
- setStopAt(2, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
-
- assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
- assertPermanentCount(playerB, "Aerie Bowmasters", 1);
- assertPowerToughness(playerB, "Aerie Bowmasters", 4, 5); // 3/4 and the +1/+1 counter from Megamorph
- Permanent aerie = getPermanent("Aerie Bowmasters", playerB);
- Assert.assertTrue("Aerie Bowmasters has to be green", aerie != null && aerie.getColor(currentGame).isGreen());
- }
-
- @Test
- public void testManifestMegamorph_TurnUpBySimpleCost() {
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
- addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- // {2}{G}{G}
- // Reach (This creature can block creatures with flying.)
- // Megamorph {5}{G}
- addCard(Zone.LIBRARY, playerB, "Aerie Bowmasters", 1);
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{2}{G}{G}: Turn");
-
- setStrictChooseMode(true);
- setStopAt(2, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
-
- assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
- assertPermanentCount(playerB, "Aerie Bowmasters", 1);
- assertPowerToughness(playerB, "Aerie Bowmasters", 3, 4); // 3/4 without counter (megamorph not used)
- Permanent aerie = getPermanent("Aerie Bowmasters", playerB);
- Assert.assertTrue("Aerie Bowmasters has to be green", aerie != null && aerie.getColor(currentGame).isGreen());
- }
-
- /**
- * When a Forest came manifested into play my Courser of Kruphix gained me a
- * life.
- */
- @Test
- public void testManifestForest() {
-
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
- // Play with the top card of your library revealed.
- // You may play the top card of your library if it's a land card.
- // Whenever a land enters the battlefield under your control, you gain 1 life.
- addCard(Zone.BATTLEFIELD, playerB, "Courser of Kruphix", 1);
-
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- addCard(Zone.LIBRARY, playerB, "Forest", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- setStopAt(2, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
-
- assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
-
- }
-
- /**
- * Whisperwood Elemental - Its sacrifice ability doesn't work..
- */
- @Test
- public void testWhisperwoodElemental() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
- // Seismic Rupture deals 2 damage to each creature without flying.
- addCard(Zone.HAND, playerA, "Seismic Rupture", 1);
-
- // At the beginning of your end step, manifest the top card of your library.
- // Sacrifice Whisperwood Elemental: Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library."
- addCard(Zone.BATTLEFIELD, playerB, "Whisperwood Elemental", 1);
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice");
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Seismic Rupture");
- setChoice(playerB, "When {this} dies"); // Order of triggers
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertGraveyardCount(playerA, "Seismic Rupture", 1);
- assertGraveyardCount(playerB, "Whisperwood Elemental", 1);
- assertGraveyardCount(playerB, "Silvercoat Lion", 2);
-
- assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 2);
-
- }
-
- /**
- * I sacrificed a manifested face-down Smothering Abomination to Nantuko
- * Husk and it made me draw a card.
- */
- @Test
- public void testDiesTriggeredAbilitiesOfManifestedCreatures() {
-
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
-
- // Sacrifice a creature: Nantuko Husk gets +2/+2 until end of turn.
- addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk", 1);
-
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- // Devoid
- // Flying
- // At the beginning of your upkeep, sacrifice a creature
- // Whenever you sacrifice a creature, draw a card.
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
- addCard(Zone.LIBRARY, playerB, "Smothering Abomination", 1);
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice a creature");
- setChoice(playerB, EmptyNames.FACE_DOWN_CREATURE.toString());
-
- setStrictChooseMode(true);
- setStopAt(2, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertPermanentCount(playerB, "Qarsi High Priest", 1);
- assertPermanentCount(playerB, "Nantuko Husk", 1);
-
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
- assertGraveyardCount(playerB, "Smothering Abomination", 1);
-
- assertPowerToughness(playerB, "Nantuko Husk", 4, 4);
-
- assertHandCount(playerB, "Mountain", 1);
-
- }
-
- @Test
- public void test_ManifestSorceryAndBlinkIt() {
-
- addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
-
- // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
- addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- // Exile target creature you control, then return that card to the battlefield under your control.
- addCard(Zone.HAND, playerB, "Cloudshift", 1); //Instant {W}
-
-
- // Devoid
- // Flying
- // At the beginning of your upkeep, sacrifice a creature
- // Whenever you sacrifice a creature, draw a card.
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
- addCard(Zone.LIBRARY, playerB, "Lightning Bolt", 1);
- addCard(Zone.LIBRARY, playerB, "Mountain", 1);
-
- skipInitShuffling();
-
- activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
- setChoice(playerB, "Silvercoat Lion");
-
- waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN, playerB);
-
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cloudshift", EmptyNames.FACE_DOWN_CREATURE.toString());
-
- setStrictChooseMode(true);
- setStopAt(2, PhaseStep.END_TURN);
- execute();
- assertAllCommandsUsed();
-
- // no life gain
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- assertPermanentCount(playerB, "Qarsi High Priest", 1);
-
- assertGraveyardCount(playerB, "Silvercoat Lion", 1);
- assertGraveyardCount(playerB, "Cloudshift", 1);
-
- assertPermanentCount(playerB, "Lightning Bolt", 0);
- assertExileCount(playerB, "Lightning Bolt", 1);
-
- assertHandCount(playerB, "Mountain", 1);
-
- }
-}
+package org.mage.test.cards.abilities.keywords;
+
+import mage.cards.Card;
+import mage.constants.EmptyNames;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.game.permanent.Permanent;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author LevelX2
+ */
+public class ManifestTest extends CardTestPlayerBase {
+
+ /**
+ * Tests that ETB triggered abilities did not trigger for manifested cards
+ */
+ @Test
+ public void testETBTriggeredAbilities() {
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+ // Manifest the top card of your library {1}{W}
+ addCard(Zone.HAND, playerA, "Soul Summons");
+
+ // Tranquil Cove enters the battlefield tapped.
+ // When Tranquil Cove enters the battlefield, you gain 1 life.
+ // {T}: Add {W} or {U}.
+ addCard(Zone.LIBRARY, playerA, "Tranquil Cove");
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+ assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
+ // not tapped
+ assertTapped(EmptyNames.FACE_DOWN_CREATURE.toString(), false);
+ }
+
+ /**
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
+ */
+ @Test
+ public void testETBTriggeredAbilities2() {
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+ // Manifest the top card of your library {1}{W}
+ addCard(Zone.HAND, playerA, "Soul Summons");
+
+ // Constellation - When Doomwake Giant or another enchantment enters the battlefield
+ // under your control, creatures your opponents control get -1/-1 until end of turn.
+ addCard(Zone.LIBRARY, playerA, "Doomwake Giant");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion");
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+ assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
+ // PlayerB's Silvercoat Lion should not have get -1/-1/
+ assertPermanentCount(playerB, "Silvercoat Lion", 1);
+ assertPowerToughness(playerB, "Silvercoat Lion", 2, 2);
+ }
+
+ /**
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
+ */
+ @Test
+ public void testETBTriggeredAbilities3() {
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
+ // Exile target creature. Its controller manifests the top card of their library {1}{U}
+ addCard(Zone.HAND, playerB, "Reality Shift");
+
+ // Constellation - When Doomwake Giant or another enchantment enters the battlefield
+ // under your control, creatures your opponents control get -1/-1 until end of turn.
+ addCard(Zone.LIBRARY, playerA, "Doomwake Giant");
+
+ addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox");
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
+
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ assertGraveyardCount(playerB, "Reality Shift", 1);
+ assertExileCount("Silvercoat Lion", 1);
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+ assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
+ // PlayerA's Pillarfield Ox should not have get -1/-1/
+ assertPermanentCount(playerB, "Pillarfield Ox", 1);
+ assertPowerToughness(playerB, "Pillarfield Ox", 2, 4);
+ }
+
+ /**
+ * If Doomwake Giant gets manifested, it's Constellation trigger may not
+ * trigger
+ */
+ @Test
+ public void testNylea() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
+ // Exile target creature. Its controller manifests the top card of their library {1}{U}
+ addCard(Zone.HAND, playerB, "Reality Shift");
+
+ // As long as your devotion to white is less than five, Nylea isn't a creature.
+ // (Each {G} in the mana costs of permanents you control counts towards your devotion to green.)
+ addCard(Zone.LIBRARY, playerA, "Nylea, God of the Hunt");
+
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
+
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ assertGraveyardCount(playerB, "Reality Shift", 1);
+ assertExileCount("Silvercoat Lion", 1);
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+ assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
+
+ }
+
+ /*
+ Had a Foundry Street Denizen and another creature out.
+ Opponent Reality Shift'ed the other creature, manifested card was a red creature. This pumped the foundry street denizen even though it shouldn't.
+ */
+ @Test
+ public void testColorOfManifestedCardDoesNotCount() {
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
+ // Exile target creature. Its controller manifests the top card of their library {1}{U}
+ addCard(Zone.HAND, playerB, "Reality Shift");
+
+ // Gore Swine {2}{R}
+ // 4/1
+ addCard(Zone.LIBRARY, playerA, "Gore Swine");
+
+ // Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
+ addCard(Zone.BATTLEFIELD, playerA, "Foundry Street Denizen");
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
+
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ assertGraveyardCount(playerB, "Reality Shift", 1);
+ assertExileCount("Silvercoat Lion", 1);
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+ assertPowerToughness(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 2, 2);
+ assertPowerToughness(playerA, "Foundry Street Denizen", 1, 1);
+
+ }
+
+ /*
+ I casted a Silence the Believers on a manifested card. It moved to the exile zone face-down.
+ */
+ @Test
+ public void testCardGetsExiledFaceUp() {
+ addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 4);
+ // Exile target creature. Its controller manifests the top card of their library {1}{U}
+ addCard(Zone.HAND, playerB, "Reality Shift");
+ // Silence the Believers - Instant {2}{B}{B}
+ // Strive — Silence the Believers costs more to cast for each target beyond the first.
+ // Exile any number of target creatures and all Auras attached to them.
+ addCard(Zone.HAND, playerB, "Silence the Believers");
+ // Gore Swine {2}{R}
+ // 4/1
+ addCard(Zone.LIBRARY, playerA, "Gore Swine");
+
+ // Whenever another red creature enters the battlefield under your control, Foundry Street Denizen gets +1/+0 until end of turn.
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
+
+ skipInitShuffling();
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Reality Shift", "Silvercoat Lion");
+ // showBattlefield("A battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerA);
+ // showBattlefield("B battle", 1, PhaseStep.POSTCOMBAT_MAIN, playerB);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Silence the Believers", EmptyNames.FACE_DOWN_CREATURE.toString());
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ assertGraveyardCount(playerB, "Reality Shift", 1);
+ assertExileCount("Silvercoat Lion", 1);
+ assertExileCount("Gore Swine", 1);
+ // no facedown creature is on the battlefield
+ assertPermanentCount(playerA, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
+
+ for (Card card : currentGame.getExile().getAllCards(currentGame)) {
+ if (card.getName().equals("Gore Swine")) {
+ Assert.assertTrue("Gore Swine may not be face down in exile", !card.isFaceDown(currentGame));
+ }
+ }
+
+ }
+
+ // Qarsi High Priest went to manifest Illusory Gains,
+ // but it made me choose a target for gains, then enchanted the card to that creature.
+ @Test
+ public void testManifestAura() {
+
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ addCard(Zone.LIBRARY, playerB, "Illusory Gains", 1);
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertGraveyardCount(playerB, "Illusory Gains", 0);
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+
+ // a facedown creature is on the battlefield
+ assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+
+ }
+
+ // Check if a Megamorph card is manifested and turned face up by their megamorph ability
+ // it gets the +1/+1 counter.
+ // 701.33c
+ // If a card with morph is manifested, its controller may turn that card face up using
+ // either the procedure described in rule 702.36e to turn a face-down permanent with morph face up
+ // or the procedure described above to turn a manifested permanent face up.
+ @Test
+ public void testManifestMegamorph_TurnUpByMegamorphCost() {
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+ addCard(Zone.BATTLEFIELD, playerB, "Forest", 6);
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ // Reach (This creature can block creatures with flying.)
+ // Megamorph {5}{G}
+ addCard(Zone.LIBRARY, playerB, "Aerie Bowmasters", 1);
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{5}{G}: Turn");
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+
+ assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
+ assertPermanentCount(playerB, "Aerie Bowmasters", 1);
+ assertPowerToughness(playerB, "Aerie Bowmasters", 4, 5); // 3/4 and the +1/+1 counter from Megamorph
+ Permanent aerie = getPermanent("Aerie Bowmasters", playerB);
+ Assert.assertTrue("Aerie Bowmasters has to be green", aerie != null && aerie.getColor(currentGame).isGreen());
+ }
+
+ @Test
+ public void testManifestMegamorph_TurnUpBySimpleCost() {
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+ addCard(Zone.BATTLEFIELD, playerB, "Forest", 4);
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ // {2}{G}{G}
+ // Reach (This creature can block creatures with flying.)
+ // Megamorph {5}{G}
+ addCard(Zone.LIBRARY, playerB, "Aerie Bowmasters", 1);
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "{2}{G}{G}: Turn");
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+
+ assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 0);
+ assertPermanentCount(playerB, "Aerie Bowmasters", 1);
+ assertPowerToughness(playerB, "Aerie Bowmasters", 3, 4); // 3/4 without counter (megamorph not used)
+ Permanent aerie = getPermanent("Aerie Bowmasters", playerB);
+ Assert.assertTrue("Aerie Bowmasters has to be green", aerie != null && aerie.getColor(currentGame).isGreen());
+ }
+
+ /**
+ * When a Forest came manifested into play my Courser of Kruphix gained me a
+ * life.
+ */
+ @Test
+ public void testManifestForest() {
+
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+ // Play with the top card of your library revealed.
+ // You may play the top card of your library if it's a land card.
+ // Whenever a land enters the battlefield under your control, you gain 1 life.
+ addCard(Zone.BATTLEFIELD, playerB, "Courser of Kruphix", 1);
+
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ addCard(Zone.LIBRARY, playerB, "Forest", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+
+ assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 1);
+
+ }
+
+ /**
+ * Whisperwood Elemental - Its sacrifice ability doesn't work..
+ */
+ @Test
+ public void testWhisperwoodElemental() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+ // Seismic Rupture deals 2 damage to each creature without flying.
+ addCard(Zone.HAND, playerA, "Seismic Rupture", 1);
+
+ // At the beginning of your end step, manifest the top card of your library.
+ // Sacrifice Whisperwood Elemental: Until end of turn, face-up, nontoken creatures you control gain "When this creature dies, manifest the top card of your library."
+ addCard(Zone.BATTLEFIELD, playerB, "Whisperwood Elemental", 1);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Sacrifice");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Seismic Rupture");
+ setChoice(playerB, "When {this} dies"); // Order of triggers
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertGraveyardCount(playerA, "Seismic Rupture", 1);
+ assertGraveyardCount(playerB, "Whisperwood Elemental", 1);
+ assertGraveyardCount(playerB, "Silvercoat Lion", 2);
+
+ assertPermanentCount(playerB, EmptyNames.FACE_DOWN_CREATURE.toString(), 2);
+
+ }
+
+ /**
+ * I sacrificed a manifested face-down Smothering Abomination to Nantuko
+ * Husk and it made me draw a card.
+ */
+ @Test
+ public void testDiesTriggeredAbilitiesOfManifestedCreatures() {
+
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 2);
+
+ // Sacrifice a creature: Nantuko Husk gets +2/+2 until end of turn.
+ addCard(Zone.BATTLEFIELD, playerB, "Nantuko Husk", 1);
+
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ // Devoid
+ // Flying
+ // At the beginning of your upkeep, sacrifice a creature
+ // Whenever you sacrifice a creature, draw a card.
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+ addCard(Zone.LIBRARY, playerB, "Smothering Abomination", 1);
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ activateAbility(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice a creature");
+ setChoice(playerB, EmptyNames.FACE_DOWN_CREATURE.toString());
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertPermanentCount(playerB, "Qarsi High Priest", 1);
+ assertPermanentCount(playerB, "Nantuko Husk", 1);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+ assertGraveyardCount(playerB, "Smothering Abomination", 1);
+
+ assertPowerToughness(playerB, "Nantuko Husk", 4, 4);
+
+ assertHandCount(playerB, "Mountain", 1);
+
+ }
+
+ @Test
+ public void test_ManifestSorceryAndBlinkIt() {
+
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
+
+ // {1}{B}, {T}, Sacrifice another creature: Manifest the top card of your library.
+ addCard(Zone.BATTLEFIELD, playerB, "Qarsi High Priest", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ // Exile target creature you control, then return that card to the battlefield under your control.
+ addCard(Zone.HAND, playerB, "Cloudshift", 1); //Instant {W}
+
+
+ // Devoid
+ // Flying
+ // At the beginning of your upkeep, sacrifice a creature
+ // Whenever you sacrifice a creature, draw a card.
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+ addCard(Zone.LIBRARY, playerB, "Lightning Bolt", 1);
+ addCard(Zone.LIBRARY, playerB, "Mountain", 1);
+
+ skipInitShuffling();
+
+ activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}, {T}, Sacrifice another creature");
+ setChoice(playerB, "Silvercoat Lion");
+
+ waitStackResolved(2, PhaseStep.PRECOMBAT_MAIN, playerB);
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cloudshift", EmptyNames.FACE_DOWN_CREATURE.toString());
+
+ setStrictChooseMode(true);
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+ assertAllCommandsUsed();
+
+ // no life gain
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ assertPermanentCount(playerB, "Qarsi High Priest", 1);
+
+ assertGraveyardCount(playerB, "Silvercoat Lion", 1);
+ assertGraveyardCount(playerB, "Cloudshift", 1);
+
+ assertPermanentCount(playerB, "Lightning Bolt", 0);
+ assertExileCount(playerB, "Lightning Bolt", 1);
+
+ assertHandCount(playerB, "Mountain", 1);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/FerventChampionTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/FerventChampionTest.java
index 2370ee55c1..b74dfe0b12 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/FerventChampionTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modification/FerventChampionTest.java
@@ -1,39 +1,39 @@
-package org.mage.test.cards.cost.modification;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class FerventChampionTest extends CardTestPlayerBase {
-
- @Test
- public void testFerventChampion() {
- setStrictChooseMode(true);
- // First strike, Haste
- // Whenever Fervent Champion attacks, another target attacking Knight you control gets +1/+0 until end of turn.
- // Equip abilities you activate that target Fervent Champion cost {3} less to activate.
- addCard(Zone.BATTLEFIELD, playerA, "Fervent Champion");
-
- // Equipped creature gets +2/+2 and has protection from red and from blue.
- // Whenever equipped creature deals combat damage to a player, Sword of Fire
- // and Ice deals 2 damage to any target and you draw a card.
- // Equip {2}
- addCard(Zone.BATTLEFIELD, playerA, "Sword of Fire and Ice", 1);
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip");
- addTarget(playerA, "Fervent Champion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, "Fervent Champion", 3,3);
- }
+package org.mage.test.cards.cost.modification;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class FerventChampionTest extends CardTestPlayerBase {
+
+ @Test
+ public void testFerventChampion() {
+ setStrictChooseMode(true);
+ // First strike, Haste
+ // Whenever Fervent Champion attacks, another target attacking Knight you control gets +1/+0 until end of turn.
+ // Equip abilities you activate that target Fervent Champion cost {3} less to activate.
+ addCard(Zone.BATTLEFIELD, playerA, "Fervent Champion");
+
+ // Equipped creature gets +2/+2 and has protection from red and from blue.
+ // Whenever equipped creature deals combat damage to a player, Sword of Fire
+ // and Ice deals 2 damage to any target and you draw a card.
+ // Equip {2}
+ addCard(Zone.BATTLEFIELD, playerA, "Sword of Fire and Ice", 1);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip");
+ addTarget(playerA, "Fervent Champion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, "Fervent Champion", 3,3);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/PrimordialMistTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/PrimordialMistTest.java
index bf7a287c1d..0167be3c33 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/PrimordialMistTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/PrimordialMistTest.java
@@ -1,56 +1,56 @@
-package org.mage.test.cards.facedown;
-
-import mage.constants.EmptyNames;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class PrimordialMistTest extends CardTestPlayerBase {
-
- /**
- * I have Brine Elemental played face down as a morph, an artifact which has
- * been manifested and Kadena which has been turned face by Ixidron. I can't
- * seem to activate Primordial Mist's second ability for any of these kinds
- * of face down creatures:
- */
- @Test
- public void test_ExileAndCastMorphFaceDownCard() {
- setStrictChooseMode(true);
-
- // At the beginning of your end step, you may manifest the top card of your library.
- // Exile a face-down permanent you control face-up: You may play that card this turn
- addCard(Zone.BATTLEFIELD, playerA, "Primordial Mist");
- // Morph {5}{U}{U}
- // When Brine Elemental is turned face up, each opponent skips their next untap step.
- addCard(Zone.HAND, playerA, "Brine Elemental"); // Creature {5}{U}{U} (5/4)
- addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brine Elemental");
- setChoice(playerA, true); // cast it face down as 2/2 creature
-
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile a face-down permanent you control");
- setChoice(playerA, EmptyNames.FACE_DOWN_CREATURE.toString());
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Brine Elemental");
- setChoice(playerA, false); // cast it face down as 2/2 creature
-
- setChoice(playerA, true);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertExileCount(playerA, 0);
-
- assertPowerToughness(playerA, "Brine Elemental", 5, 4);
-
- }
-}
+package org.mage.test.cards.facedown;
+
+import mage.constants.EmptyNames;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class PrimordialMistTest extends CardTestPlayerBase {
+
+ /**
+ * I have Brine Elemental played face down as a morph, an artifact which has
+ * been manifested and Kadena which has been turned face by Ixidron. I can't
+ * seem to activate Primordial Mist's second ability for any of these kinds
+ * of face down creatures:
+ */
+ @Test
+ public void test_ExileAndCastMorphFaceDownCard() {
+ setStrictChooseMode(true);
+
+ // At the beginning of your end step, you may manifest the top card of your library.
+ // Exile a face-down permanent you control face-up: You may play that card this turn
+ addCard(Zone.BATTLEFIELD, playerA, "Primordial Mist");
+ // Morph {5}{U}{U}
+ // When Brine Elemental is turned face up, each opponent skips their next untap step.
+ addCard(Zone.HAND, playerA, "Brine Elemental"); // Creature {5}{U}{U} (5/4)
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 9);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brine Elemental");
+ setChoice(playerA, true); // cast it face down as 2/2 creature
+
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Exile a face-down permanent you control");
+ setChoice(playerA, EmptyNames.FACE_DOWN_CREATURE.toString());
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Brine Elemental");
+ setChoice(playerA, false); // cast it face down as 2/2 creature
+
+ setChoice(playerA, true);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertExileCount(playerA, 0);
+
+ assertPowerToughness(playerA, "Brine Elemental", 5, 4);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/TriggerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/TriggerTest.java
index 54035a4cfe..2a673dd635 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/facedown/TriggerTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/facedown/TriggerTest.java
@@ -1,62 +1,62 @@
-
-package org.mage.test.cards.facedown;
-
-import mage.cards.Card;
-import mage.constants.EmptyNames;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-
-
-public class TriggerTest extends CardTestPlayerBase {
-
- /**
- * Midnight Reaper triggers when dies face down #7063
- * Ixidron has turned Midnight Reaper and Balduvian Bears face down:
- *
- */
-
- // test that cards imprinted using Summoner's Egg are face down
- @Test
- public void testReaperDoesNotTriggerDiesTriggerFaceDown() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
- // As Ixidron enters the battlefield, turn all other nontoken creatures face down.
- // Ixidron's power and toughness are each equal to the number of face-down creatures on the battlefield.
- addCard(Zone.HAND, playerA, "Ixidron"); // Creature {3}{U}{U} (*/*)
- // Whenever a nontoken creature you control dies, Midnight Reaper deals 1 damage to you and you draw a card.
- addCard(Zone.BATTLEFIELD, playerA, "Midnight Reaper"); // Creature {2}{B}
-
- addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
- addCard(Zone.HAND, playerB, "Lightning Bolt"); // Instant 3 damage
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ixidron");
-
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", EmptyNames.FACE_DOWN_CREATURE.toString());
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerB, "Lightning Bolt", 1);
-
- assertGraveyardCount(playerA, "Midnight Reaper", 1);
- assertGraveyardCount(playerA, "Ixidron", 1);
-
- assertHandCount(playerA, 0);
- assertLife(playerA, 20);
-
- }
+
+package org.mage.test.cards.facedown;
+
+import mage.cards.Card;
+import mage.constants.EmptyNames;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+
+
+public class TriggerTest extends CardTestPlayerBase {
+
+ /**
+ * Midnight Reaper triggers when dies face down #7063
+ * Ixidron has turned Midnight Reaper and Balduvian Bears face down:
+ *
+ */
+
+ // test that cards imprinted using Summoner's Egg are face down
+ @Test
+ public void testReaperDoesNotTriggerDiesTriggerFaceDown() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
+ // As Ixidron enters the battlefield, turn all other nontoken creatures face down.
+ // Ixidron's power and toughness are each equal to the number of face-down creatures on the battlefield.
+ addCard(Zone.HAND, playerA, "Ixidron"); // Creature {3}{U}{U} (*/*)
+ // Whenever a nontoken creature you control dies, Midnight Reaper deals 1 damage to you and you draw a card.
+ addCard(Zone.BATTLEFIELD, playerA, "Midnight Reaper"); // Creature {2}{B}
+
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
+ addCard(Zone.HAND, playerB, "Lightning Bolt"); // Instant 3 damage
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ixidron");
+
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", EmptyNames.FACE_DOWN_CREATURE.toString());
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerB, "Lightning Bolt", 1);
+
+ assertGraveyardCount(playerA, "Midnight Reaper", 1);
+ assertGraveyardCount(playerA, "Ixidron", 1);
+
+ assertHandCount(playerA, 0);
+ assertLife(playerA, 20);
+
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/MultipleTimesUsableActivatedManaAbilitiesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/MultipleTimesUsableActivatedManaAbilitiesTest.java
index f6fe75c5fe..83a9f0f0df 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/MultipleTimesUsableActivatedManaAbilitiesTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/MultipleTimesUsableActivatedManaAbilitiesTest.java
@@ -1,45 +1,45 @@
-package org.mage.test.cards.mana;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class MultipleTimesUsableActivatedManaAbilitiesTest extends CardTestPlayerBase {
-
- /**
- * Seton, Krosan Protector - only seems to get counted as if it were one
- * mana for determining if a spell can be cast, regardless of how many
- * druids you have in playF
- */
- @Test
- public void testCanBeCastWithSetonKrosanProtector() {
- // Tap an untapped Druid you control: Add {G}.
- addCard(Zone.BATTLEFIELD, playerA, "Seton, Krosan Protector", 1); // Creature {G}{G}{G}
- addCard(Zone.BATTLEFIELD, playerA, "Citanul Druid", 3);
-
- addCard(Zone.HAND, playerA, "Leatherback Baloth", 1); // Creature 4/5
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Leatherback Baloth");
-
- setChoice(playerA, "Citanul Druid");
- setChoice(playerA, "Citanul Druid");
- setChoice(playerA, "Citanul Druid");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
-
-
- setStrictChooseMode(true);
- execute();
-
- assertAllCommandsUsed();
-
- assertTappedCount("Citanul Druid", true, 3);
- assertPermanentCount(playerA, "Leatherback Baloth", 1);
- }
-
-}
+package org.mage.test.cards.mana;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class MultipleTimesUsableActivatedManaAbilitiesTest extends CardTestPlayerBase {
+
+ /**
+ * Seton, Krosan Protector - only seems to get counted as if it were one
+ * mana for determining if a spell can be cast, regardless of how many
+ * druids you have in playF
+ */
+ @Test
+ public void testCanBeCastWithSetonKrosanProtector() {
+ // Tap an untapped Druid you control: Add {G}.
+ addCard(Zone.BATTLEFIELD, playerA, "Seton, Krosan Protector", 1); // Creature {G}{G}{G}
+ addCard(Zone.BATTLEFIELD, playerA, "Citanul Druid", 3);
+
+ addCard(Zone.HAND, playerA, "Leatherback Baloth", 1); // Creature 4/5
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Leatherback Baloth");
+
+ setChoice(playerA, "Citanul Druid");
+ setChoice(playerA, "Citanul Druid");
+ setChoice(playerA, "Citanul Druid");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+
+
+ setStrictChooseMode(true);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertTappedCount("Citanul Druid", true, 3);
+ assertPermanentCount(playerA, "Leatherback Baloth", 1);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/CrypticTrilobiteTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/CrypticTrilobiteTest.java
index 20c0c9f449..0cdf671f50 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/CrypticTrilobiteTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/CrypticTrilobiteTest.java
@@ -1,112 +1,112 @@
-package org.mage.test.cards.mana.conditional;
-
-import mage.abilities.mana.ManaOptions;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.counters.CounterType;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
-
-/**
- *
- * @author LevelX2
- */
-
-public class CrypticTrilobiteTest extends CardTestPlayerBase {
-
- @Test
- public void testAvailableManaCalculation(){
- setStrictChooseMode(true);
-
- // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
- // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
- // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
- addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
-
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
- setChoice(playerA, "X=5");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Cryptic Trilobite", 1);
-
- ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- assertManaOptions("{C}{C}{C}{C}{C}{C}{C}{C}{C}{C}[{CrypticTrilobiteManaCondition}]", manaOptions);
- }
-
- @Test
- public void testUse(){
- setStrictChooseMode(true);
-
- // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
- // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
- // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
- addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
- // Flying
- // {2}: Deathknell Kami gets +1/+1 until end of turn. Sacrifice it at the beginning of the next end step.
- // Soulshift 1 (When this creature dies, you may return target Spirit card with converted mana cost 1 or less from your graveyard to your hand.)
- addCard(Zone.BATTLEFIELD, playerA, "Deathknell Kami"); // Creature (0/1)
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
- setChoice(playerA, "X=5");
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}:");
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}:");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Cryptic Trilobite", 1);
- assertCounterCount(playerA, "Cryptic Trilobite", CounterType.P1P1, 3);
-
- assertPowerToughness(playerA, "Deathknell Kami", 2, 3);
-
- ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- assertManaOptions("{C}{C}{C}{C}{C}{C}[{CrypticTrilobiteManaCondition}]", manaOptions);
- }
-
- @Test
- public void testCantUse(){
- setStrictChooseMode(true);
-
- // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
- // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
- // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
- addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
-
- // {4}{W}: Return another target creature you control to its owner's hand.
- addCard(Zone.HAND, playerA, "Aegis Automaton"); // Creature {2} (0/2)
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
- setChoice(playerA, "X=5");
-
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
-
- checkPlayableAbility("can't play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Aegis Automaton", false);
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Cryptic Trilobite", 1);
- assertCounterCount(playerA, "Cryptic Trilobite", CounterType.P1P1, 5);
- }
-
-
+package org.mage.test.cards.mana.conditional;
+
+import mage.abilities.mana.ManaOptions;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class CrypticTrilobiteTest extends CardTestPlayerBase {
+
+ @Test
+ public void testAvailableManaCalculation(){
+ setStrictChooseMode(true);
+
+ // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
+ // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
+ // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
+ addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
+
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
+ setChoice(playerA, "X=5");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Cryptic Trilobite", 1);
+
+ ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
+ assertManaOptions("{C}{C}{C}{C}{C}{C}{C}{C}{C}{C}[{CrypticTrilobiteManaCondition}]", manaOptions);
+ }
+
+ @Test
+ public void testUse(){
+ setStrictChooseMode(true);
+
+ // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
+ // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
+ // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
+ addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
+ // Flying
+ // {2}: Deathknell Kami gets +1/+1 until end of turn. Sacrifice it at the beginning of the next end step.
+ // Soulshift 1 (When this creature dies, you may return target Spirit card with converted mana cost 1 or less from your graveyard to your hand.)
+ addCard(Zone.BATTLEFIELD, playerA, "Deathknell Kami"); // Creature (0/1)
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
+ setChoice(playerA, "X=5");
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}:");
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}:");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Cryptic Trilobite", 1);
+ assertCounterCount(playerA, "Cryptic Trilobite", CounterType.P1P1, 3);
+
+ assertPowerToughness(playerA, "Deathknell Kami", 2, 3);
+
+ ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
+ assertManaOptions("{C}{C}{C}{C}{C}{C}[{CrypticTrilobiteManaCondition}]", manaOptions);
+ }
+
+ @Test
+ public void testCantUse(){
+ setStrictChooseMode(true);
+
+ // Cryptic Trilobite enters the battlefield with X +1/+1 counters on it.
+ // Remove a +1/+1 counter from Cryptic Trilobite: Add {C}{C}. Spend this mana only to activate abilities.
+ // {1}, {T}: Put a +1/+1 counter on Cryptic Trilobite.
+ addCard(Zone.HAND, playerA, "Cryptic Trilobite"); // Creature {X}{X}
+
+ // {4}{W}: Return another target creature you control to its owner's hand.
+ addCard(Zone.HAND, playerA, "Aegis Automaton"); // Creature {2} (0/2)
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cryptic Trilobite");
+ setChoice(playerA, "X=5");
+
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
+
+ checkPlayableAbility("can't play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Aegis Automaton", false);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Cryptic Trilobite", 1);
+ assertCounterCount(playerA, "Cryptic Trilobite", CounterType.P1P1, 5);
+ }
+
+
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/TitansNestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/TitansNestTest.java
index 89cfbed009..a61f627ded 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/TitansNestTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/mana/conditional/TitansNestTest.java
@@ -1,44 +1,44 @@
-
-package org.mage.test.cards.mana.conditional;
-
-import mage.abilities.mana.ManaOptions;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
-
-/**
- *
- * @author LevelX2
- */
-public class TitansNestTest extends CardTestPlayerBase {
-
- @Test
- public void testTitansNest(){
- setStrictChooseMode(true);
-
- // At the beginning of your upkeep, look at the top card of your library. You may put that card into your graveyard.
- // Exile a card from your graveyard: Add {C}. Spend this mana only to cast a colored spell without {X} in its mana cost.
- addCard(Zone.HAND, playerA, "Titans' Nest"); // Enchantment {1}{B}{G}{U}
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
- addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
-
- addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears", 2);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Titans' Nest");
-
- setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Titans' Nest", 1);
-
- ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
- Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
- assertManaOptions("{C}{C}[{TitansNestManaCondition}]", manaOptions);
- }
+
+package org.mage.test.cards.mana.conditional;
+
+import mage.abilities.mana.ManaOptions;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class TitansNestTest extends CardTestPlayerBase {
+
+ @Test
+ public void testTitansNest(){
+ setStrictChooseMode(true);
+
+ // At the beginning of your upkeep, look at the top card of your library. You may put that card into your graveyard.
+ // Exile a card from your graveyard: Add {C}. Spend this mana only to cast a colored spell without {X} in its mana cost.
+ addCard(Zone.HAND, playerA, "Titans' Nest"); // Enchantment {1}{B}{G}{U}
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
+
+ addCard(Zone.GRAVEYARD, playerA, "Grizzly Bears", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Titans' Nest");
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Titans' Nest", 1);
+
+ ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
+ Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
+ assertManaOptions("{C}{C}[{TitansNestManaCondition}]", manaOptions);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAllDamageTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAllDamageTest.java
index 28e27aa624..c6fe1401b8 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAllDamageTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAllDamageTest.java
@@ -1,145 +1,145 @@
-package org.mage.test.cards.prevention;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class PreventAllDamageTest extends CardTestPlayerBase {
-
- @Test
- public void test_SafePassage() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
- // Prevent all damage that would be dealt to you and creatures you control this turn.
- addCard(Zone.HAND, playerA, "Safe Passage"); // Instant {2}{W}
-
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); // (2/2)
-
- addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 2); // (2/4)
- addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
-
- addCard(Zone.HAND, playerB, "Lightning Bolt", 2); // Instnat {R}
-
- castSpell(2, PhaseStep.UPKEEP, playerA, "Safe Passage");
-
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion");
-
- attack(2, playerB, "Pillarfield Ox");
- attack(2, playerB, "Pillarfield Ox");
-
- block(2, playerA, "Silvercoat Lion", "Pillarfield Ox");
-
- setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Safe Passage", 1);
- assertPermanentCount(playerA, "Silvercoat Lion", 1);
-
- assertGraveyardCount(playerB, "Lightning Bolt", 2);
-
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- }
-
- @Test
- public void test_EtherealHaze() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
- // Prevent all damage that would be dealt by creatures this turn.
- addCard(Zone.HAND, playerA, "Ethereal Haze"); // Instant {W}
-
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); // (2/2)
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2); // (2/4)
- addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
-
- addCard(Zone.HAND, playerB, "Lightning Bolt", 1); // Instant {R}
-
- castSpell(2, PhaseStep.UPKEEP, playerA, "Ethereal Haze");
-
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
-
- attack(2, playerB, "Silvercoat Lion");
- attack(2, playerB, "Silvercoat Lion");
-
- block(2, playerA, "Silvercoat Lion", "Silvercoat Lion");
-
- setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Ethereal Haze", 1);
- assertPermanentCount(playerA, "Silvercoat Lion", 1);
-
- assertPermanentCount(playerB, "Silvercoat Lion", 2);
- assertGraveyardCount(playerB, "Lightning Bolt", 1);
-
- assertLife(playerA, 17);
- assertLife(playerB, 20);
-
- }
-
- @Test
- public void test_EnergyStorm() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
- // Cumulative upkeep {1}
- // Prevent all damage that would be dealt by instant and sorcery spells.
- // Creatures with flying don't untap during their controllers' untap steps.
- addCard(Zone.HAND, playerA, "Energy Storm"); // ENCHANTMENT {1}{W}
-
- // Flying, vigilance
- addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 1); // (2/2)
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); // (2/2)
-
- addCard(Zone.BATTLEFIELD, playerB, "Mountain", 4);
- addCard(Zone.HAND, playerB, "Lightning Bolt", 2); // Instant {R}
- // Fire Ambush deals 3 damage to any target.
- addCard(Zone.HAND, playerB, "Fire Ambush", 2); // Sorcery {1}{R}
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Energy Storm");
-
- attack(1, playerA, "Abbey Griffin");
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Abbey Griffin");
-
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Fire Ambush", playerA);
- castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Fire Ambush", "Abbey Griffin");
-
- attack(2, playerB, "Silvercoat Lion");
-
- setChoice(playerA, false); // Pay {1}? Energy Storm - CumulativeUpkeepAbility: Cumulative upkeep {1}
-
- setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Energy Storm", 1);
- assertPermanentCount(playerA, "Abbey Griffin", 1);
-
- assertPermanentCount(playerB, "Silvercoat Lion", 1);
- assertGraveyardCount(playerB, "Lightning Bolt", 2);
- assertGraveyardCount(playerB, "Fire Ambush", 2);
-
- assertLife(playerA, 18);
- assertLife(playerB, 18);
-
- }
-}
+package org.mage.test.cards.prevention;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class PreventAllDamageTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_SafePassage() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
+ // Prevent all damage that would be dealt to you and creatures you control this turn.
+ addCard(Zone.HAND, playerA, "Safe Passage"); // Instant {2}{W}
+
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); // (2/2)
+
+ addCard(Zone.BATTLEFIELD, playerB, "Pillarfield Ox", 2); // (2/4)
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
+
+ addCard(Zone.HAND, playerB, "Lightning Bolt", 2); // Instnat {R}
+
+ castSpell(2, PhaseStep.UPKEEP, playerA, "Safe Passage");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion");
+
+ attack(2, playerB, "Pillarfield Ox");
+ attack(2, playerB, "Pillarfield Ox");
+
+ block(2, playerA, "Silvercoat Lion", "Pillarfield Ox");
+
+ setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Safe Passage", 1);
+ assertPermanentCount(playerA, "Silvercoat Lion", 1);
+
+ assertGraveyardCount(playerB, "Lightning Bolt", 2);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ }
+
+ @Test
+ public void test_EtherealHaze() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
+ // Prevent all damage that would be dealt by creatures this turn.
+ addCard(Zone.HAND, playerA, "Ethereal Haze"); // Instant {W}
+
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); // (2/2)
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2); // (2/4)
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
+
+ addCard(Zone.HAND, playerB, "Lightning Bolt", 1); // Instant {R}
+
+ castSpell(2, PhaseStep.UPKEEP, playerA, "Ethereal Haze");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
+
+ attack(2, playerB, "Silvercoat Lion");
+ attack(2, playerB, "Silvercoat Lion");
+
+ block(2, playerA, "Silvercoat Lion", "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Ethereal Haze", 1);
+ assertPermanentCount(playerA, "Silvercoat Lion", 1);
+
+ assertPermanentCount(playerB, "Silvercoat Lion", 2);
+ assertGraveyardCount(playerB, "Lightning Bolt", 1);
+
+ assertLife(playerA, 17);
+ assertLife(playerB, 20);
+
+ }
+
+ @Test
+ public void test_EnergyStorm() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+ // Cumulative upkeep {1}
+ // Prevent all damage that would be dealt by instant and sorcery spells.
+ // Creatures with flying don't untap during their controllers' untap steps.
+ addCard(Zone.HAND, playerA, "Energy Storm"); // ENCHANTMENT {1}{W}
+
+ // Flying, vigilance
+ addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 1); // (2/2)
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1); // (2/2)
+
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain", 4);
+ addCard(Zone.HAND, playerB, "Lightning Bolt", 2); // Instant {R}
+ // Fire Ambush deals 3 damage to any target.
+ addCard(Zone.HAND, playerB, "Fire Ambush", 2); // Sorcery {1}{R}
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Energy Storm");
+
+ attack(1, playerA, "Abbey Griffin");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Abbey Griffin");
+
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Fire Ambush", playerA);
+ castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Fire Ambush", "Abbey Griffin");
+
+ attack(2, playerB, "Silvercoat Lion");
+
+ setChoice(playerA, false); // Pay {1}? Energy Storm - CumulativeUpkeepAbility: Cumulative upkeep {1}
+
+ setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Energy Storm", 1);
+ assertPermanentCount(playerA, "Abbey Griffin", 1);
+
+ assertPermanentCount(playerB, "Silvercoat Lion", 1);
+ assertGraveyardCount(playerB, "Lightning Bolt", 2);
+ assertGraveyardCount(playerB, "Fire Ambush", 2);
+
+ assertLife(playerA, 18);
+ assertLife(playerB, 18);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/protection/EightAndAHalfTailsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/protection/EightAndAHalfTailsTest.java
index 4fd955ec87..69f900e8db 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/protection/EightAndAHalfTailsTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/protection/EightAndAHalfTailsTest.java
@@ -1,48 +1,48 @@
-package org.mage.test.cards.protection;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.counters.CounterType;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-
-/**
- *
- * @author LevelX2
- */
-public class EightAndAHalfTailsTest extends CardTestPlayerBase {
-
- @Test
- public void testProtectingPlaneswalker() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
-
- // Activated abilities of artifacts your opponents control can't be activated.
- // +1: Until your next turn, up to one target noncreature artifact becomes an artifact creature with power and toughness equal to its converted mana cost.
- // -2: You may choose an artifact card you own from outside the game or in exile, reveal that card, and put it into your hand.
- addCard(Zone.BATTLEFIELD, playerA, "Karn, the Great Creator"); // Planeswalker (5)
-
- // {1}{W}: Target permanent you control gains protection from white until end of turn.
- // {1}: Target spell or permanent becomes white until end of turn.
- addCard(Zone.BATTLEFIELD, playerA, "Eight-and-a-Half-Tails"); // Creature
-
- // Flying, double strike
- // Whenever a creature you control deals combat damage to a player, you and that player each gain that much life.
- // At the beginning of your end step, if you have at least 15 life more than your starting life total, each player Angel of Destiny attacked this turn loses the game.
- addCard(Zone.BATTLEFIELD, playerB, "Angel of Destiny"); // Creature
-
- attack(2, playerB, "Angel of Destiny", "Karn, the Great Creator");
- activateAbility(2, PhaseStep.DECLARE_ATTACKERS, playerA, "{1}{W}: Target permanent you control gains protection from white until end of turn.");
- addTarget(playerA, "Karn, the Great Creator");
-
- setStopAt(2, PhaseStep.END_COMBAT);
- execute();
-
- assertPermanentCount(playerA, "Karn, the Great Creator", 1);
- assertCounterCount("Karn, the Great Creator", CounterType.LOYALTY, 5);
-
- }
-
+package org.mage.test.cards.protection;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+
+/**
+ *
+ * @author LevelX2
+ */
+public class EightAndAHalfTailsTest extends CardTestPlayerBase {
+
+ @Test
+ public void testProtectingPlaneswalker() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+
+ // Activated abilities of artifacts your opponents control can't be activated.
+ // +1: Until your next turn, up to one target noncreature artifact becomes an artifact creature with power and toughness equal to its converted mana cost.
+ // -2: You may choose an artifact card you own from outside the game or in exile, reveal that card, and put it into your hand.
+ addCard(Zone.BATTLEFIELD, playerA, "Karn, the Great Creator"); // Planeswalker (5)
+
+ // {1}{W}: Target permanent you control gains protection from white until end of turn.
+ // {1}: Target spell or permanent becomes white until end of turn.
+ addCard(Zone.BATTLEFIELD, playerA, "Eight-and-a-Half-Tails"); // Creature
+
+ // Flying, double strike
+ // Whenever a creature you control deals combat damage to a player, you and that player each gain that much life.
+ // At the beginning of your end step, if you have at least 15 life more than your starting life total, each player Angel of Destiny attacked this turn loses the game.
+ addCard(Zone.BATTLEFIELD, playerB, "Angel of Destiny"); // Creature
+
+ attack(2, playerB, "Angel of Destiny", "Karn, the Great Creator");
+ activateAbility(2, PhaseStep.DECLARE_ATTACKERS, playerA, "{1}{W}: Target permanent you control gains protection from white until end of turn.");
+ addTarget(playerA, "Karn, the Great Creator");
+
+ setStopAt(2, PhaseStep.END_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Karn, the Great Creator", 1);
+ assertCounterCount("Karn, the Great Creator", CounterType.LOYALTY, 5);
+
+ }
+
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/ConduitOfRuinTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/ConduitOfRuinTest.java
index 727dda1f04..83eaf3783d 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/ConduitOfRuinTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/bfz/ConduitOfRuinTest.java
@@ -1,51 +1,51 @@
-package org.mage.test.cards.single.bfz;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class ConduitOfRuinTest extends CardTestPlayerBase {
-
- @Test
- public void testCast() {
- setStrictChooseMode(true);
-
- // Emrakul, the Aeons Torn can't be countered.
- // When you cast Emrakul, take an extra turn after this one.
- // Flying, protection from colored spells, annihilator 6
- // When Emrakul is put into a graveyard from anywhere, its owner shuffles their graveyard into their library.
- addCard(Zone.LIBRARY, playerA, "Emrakul, the Aeons Torn"); // Creature {15} 15/15
-
- // When you cast Conduit of Ruin, you may search your library for a colorless creature card with converted mana cost 7 or greater, then shuffle your library and put that card on top of it.
- // The first creature spell you cast each turn costs {2} less to cast.
- addCard(Zone.HAND, playerA, "Conduit of Ruin"); // Creature {6} 5/5
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 13);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conduit of Ruin");
- setChoice(playerA, true); // When you cast this spell, you may search...
- addTarget(playerA, "Emrakul, the Aeons Torn");
-
- setStopAt(3, PhaseStep.DRAW);
-
- execute();
-
- assertLibraryCount(playerA, "Emrakul, the Aeons Torn", 0);
- assertHandCount(playerA, "Emrakul, the Aeons Torn", 1);
-
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Emrakul, the Aeons Torn");
-
- setStopAt(3, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Conduit of Ruin", 1);
- assertPermanentCount(playerA, "Emrakul, the Aeons Torn", 1);
- }
+package org.mage.test.cards.single.bfz;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class ConduitOfRuinTest extends CardTestPlayerBase {
+
+ @Test
+ public void testCast() {
+ setStrictChooseMode(true);
+
+ // Emrakul, the Aeons Torn can't be countered.
+ // When you cast Emrakul, take an extra turn after this one.
+ // Flying, protection from colored spells, annihilator 6
+ // When Emrakul is put into a graveyard from anywhere, its owner shuffles their graveyard into their library.
+ addCard(Zone.LIBRARY, playerA, "Emrakul, the Aeons Torn"); // Creature {15} 15/15
+
+ // When you cast Conduit of Ruin, you may search your library for a colorless creature card with converted mana cost 7 or greater, then shuffle your library and put that card on top of it.
+ // The first creature spell you cast each turn costs {2} less to cast.
+ addCard(Zone.HAND, playerA, "Conduit of Ruin"); // Creature {6} 5/5
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 13);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conduit of Ruin");
+ setChoice(playerA, true); // When you cast this spell, you may search...
+ addTarget(playerA, "Emrakul, the Aeons Torn");
+
+ setStopAt(3, PhaseStep.DRAW);
+
+ execute();
+
+ assertLibraryCount(playerA, "Emrakul, the Aeons Torn", 0);
+ assertHandCount(playerA, "Emrakul, the Aeons Torn", 1);
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Emrakul, the Aeons Torn");
+
+ setStopAt(3, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Conduit of Ruin", 1);
+ assertPermanentCount(playerA, "Emrakul, the Aeons Torn", 1);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/TheUrDragonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/TheUrDragonTest.java
index a1e26783b4..8d6b756001 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/TheUrDragonTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/c17/TheUrDragonTest.java
@@ -1,49 +1,49 @@
-package org.mage.test.cards.single.c17;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class TheUrDragonTest extends CardTestPlayerBase {
-
-
- @Test
- public void test_basic() {
- setStrictChooseMode(true);
-
- addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
- skipInitShuffling();
- // Eminence — As long as The Ur-Dragon is in the command zone or on the battlefield, other Dragon spells you cast cost 1 less to cast.
- // Flying
- // Whenever one or more Dragons you control attack, draw that many cards, then you may put a permanent card from your hand onto the battlefield.
- addCard(Zone.BATTLEFIELD, playerA, "The Ur-Dragon", 1); // Creature (10/10)
- // Flying
- // {R}: Dragon Hatchling gets +1/+0 until end of turn.
- addCard(Zone.HAND, playerA, "Dragon Hatchling", 2); // Creature Dragon {1}{R} (0/1)
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragon Hatchling");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragon Hatchling");
-
- attack(3, playerA, "The Ur-Dragon");
- attack(3, playerA, "Dragon Hatchling");
- attack(3, playerA, "Dragon Hatchling");
- setChoice(playerA, true); // Put a permanent card from your hand onto the battlefield?
- setChoice(playerA, "Silvercoat Lion");
-
- setStopAt(3, PhaseStep.END_COMBAT);
-
- execute();
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Dragon Hatchling", 2);
- assertPermanentCount(playerA, "Silvercoat Lion", 1 );
- assertHandCount(playerA, 3);
-
- }
+package org.mage.test.cards.single.c17;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class TheUrDragonTest extends CardTestPlayerBase {
+
+
+ @Test
+ public void test_basic() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
+ skipInitShuffling();
+ // Eminence — As long as The Ur-Dragon is in the command zone or on the battlefield, other Dragon spells you cast cost 1 less to cast.
+ // Flying
+ // Whenever one or more Dragons you control attack, draw that many cards, then you may put a permanent card from your hand onto the battlefield.
+ addCard(Zone.BATTLEFIELD, playerA, "The Ur-Dragon", 1); // Creature (10/10)
+ // Flying
+ // {R}: Dragon Hatchling gets +1/+0 until end of turn.
+ addCard(Zone.HAND, playerA, "Dragon Hatchling", 2); // Creature Dragon {1}{R} (0/1)
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragon Hatchling");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dragon Hatchling");
+
+ attack(3, playerA, "The Ur-Dragon");
+ attack(3, playerA, "Dragon Hatchling");
+ attack(3, playerA, "Dragon Hatchling");
+ setChoice(playerA, true); // Put a permanent card from your hand onto the battlefield?
+ setChoice(playerA, "Silvercoat Lion");
+
+ setStopAt(3, PhaseStep.END_COMBAT);
+
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Dragon Hatchling", 2);
+ assertPermanentCount(playerA, "Silvercoat Lion", 1 );
+ assertHandCount(playerA, 3);
+
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/c18/AminatousAuguryTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/c18/AminatousAuguryTest.java
index a8d36115ce..167c09d5ad 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/c18/AminatousAuguryTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/c18/AminatousAuguryTest.java
@@ -1,75 +1,75 @@
-
-package org.mage.test.cards.single.c18;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class AminatousAuguryTest extends CardTestPlayerBase {
-
- @Test
- public void testCastMultiple() {
- setStrictChooseMode(true);
-
-
- addCard(Zone.LIBRARY, playerA, "Pillarfield Ox"); // Creature (2/4)
- // As an additional cost to cast this spell, discard a card.
- // Draw two cards.
- addCard(Zone.LIBRARY, playerA, "Tormenting Voice"); // Sorcery
- // {1}: Adarkar Sentinel gets +0/+1 until end of turn.
- addCard(Zone.LIBRARY, playerA, "Adarkar Sentinel"); // Artifact Creature {5} (3/3)
- addCard(Zone.LIBRARY, playerA, "Storm Crow");
- // You have hexproof. (You can't be the target of spells or abilities your opponents control.)
- addCard(Zone.LIBRARY, playerA, "Aegis of the Gods"); // Enchantment Creature {1}{W} (2/1)
- addCard(Zone.LIBRARY, playerA, "Lightning Bolt"); // Instant
- addCard(Zone.LIBRARY, playerA, "Badlands");
- skipInitShuffling();
- // Exile the top eight cards of your library. You may put a land card from among them onto the battlefield.
- // Until end of turn, for each nonland card type, you may cast a card of that type from among the exiled cards
- // without paying its mana cost.
- addCard(Zone.HAND, playerA, "Aminatou's Augury"); // SORCERY {6}{U}{U}
- addCard(Zone.HAND, playerA, "Mountain");
- addCard(Zone.HAND, playerA, "Silvercoat Lion");
- addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
-
- playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aminatou's Augury");
- setChoice(playerA, true); // Put a land from among the exiled cards into play?
- setChoice(playerA, "Badlands"); // Select a land card
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Adarkar Sentinel");
- setChoice(playerA, "Artifact"); // Which card type do you want to consume?
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aegis of the Gods");
- setChoice(playerA, "Enchantment"); // Which card type do you want to consume?
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Storm Crow");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tormenting Voice");
- setChoice(playerA, "Silvercoat Lion"); // Select a card (discard cost)
-
- checkPlayableAbility("Cannot cast second creature from exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Pillarfield Ox", Boolean.FALSE); // Type Creature type is already consumed
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Aminatou's Augury", 1);
- assertPermanentCount(playerA, "Mountain", 1);
- assertPermanentCount(playerA, "Badlands", 1);
- assertPermanentCount(playerA, "Adarkar Sentinel", 1);
- assertPermanentCount(playerA, "Aegis of the Gods", 1);
- assertPermanentCount(playerA, "Storm Crow", 1);
- assertGraveyardCount(playerA, "Lightning Bolt", 1);
-
- assertLife(playerA, 20);
- assertLife(playerB, 17);
-
- assertHandCount(playerA, 2);
- assertGraveyardCount(playerA, "Silvercoat Lion",1);
- assertExileCount(playerA, 2);
- }
-
-}
+
+package org.mage.test.cards.single.c18;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class AminatousAuguryTest extends CardTestPlayerBase {
+
+ @Test
+ public void testCastMultiple() {
+ setStrictChooseMode(true);
+
+
+ addCard(Zone.LIBRARY, playerA, "Pillarfield Ox"); // Creature (2/4)
+ // As an additional cost to cast this spell, discard a card.
+ // Draw two cards.
+ addCard(Zone.LIBRARY, playerA, "Tormenting Voice"); // Sorcery
+ // {1}: Adarkar Sentinel gets +0/+1 until end of turn.
+ addCard(Zone.LIBRARY, playerA, "Adarkar Sentinel"); // Artifact Creature {5} (3/3)
+ addCard(Zone.LIBRARY, playerA, "Storm Crow");
+ // You have hexproof. (You can't be the target of spells or abilities your opponents control.)
+ addCard(Zone.LIBRARY, playerA, "Aegis of the Gods"); // Enchantment Creature {1}{W} (2/1)
+ addCard(Zone.LIBRARY, playerA, "Lightning Bolt"); // Instant
+ addCard(Zone.LIBRARY, playerA, "Badlands");
+ skipInitShuffling();
+ // Exile the top eight cards of your library. You may put a land card from among them onto the battlefield.
+ // Until end of turn, for each nonland card type, you may cast a card of that type from among the exiled cards
+ // without paying its mana cost.
+ addCard(Zone.HAND, playerA, "Aminatou's Augury"); // SORCERY {6}{U}{U}
+ addCard(Zone.HAND, playerA, "Mountain");
+ addCard(Zone.HAND, playerA, "Silvercoat Lion");
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 8);
+
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aminatou's Augury");
+ setChoice(playerA, true); // Put a land from among the exiled cards into play?
+ setChoice(playerA, "Badlands"); // Select a land card
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Adarkar Sentinel");
+ setChoice(playerA, "Artifact"); // Which card type do you want to consume?
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Aegis of the Gods");
+ setChoice(playerA, "Enchantment"); // Which card type do you want to consume?
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Storm Crow");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tormenting Voice");
+ setChoice(playerA, "Silvercoat Lion"); // Select a card (discard cost)
+
+ checkPlayableAbility("Cannot cast second creature from exile", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Pillarfield Ox", Boolean.FALSE); // Type Creature type is already consumed
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Aminatou's Augury", 1);
+ assertPermanentCount(playerA, "Mountain", 1);
+ assertPermanentCount(playerA, "Badlands", 1);
+ assertPermanentCount(playerA, "Adarkar Sentinel", 1);
+ assertPermanentCount(playerA, "Aegis of the Gods", 1);
+ assertPermanentCount(playerA, "Storm Crow", 1);
+ assertGraveyardCount(playerA, "Lightning Bolt", 1);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 17);
+
+ assertHandCount(playerA, 2);
+ assertGraveyardCount(playerA, "Silvercoat Lion",1);
+ assertExileCount(playerA, 2);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/c20/PakoArcaneRetrieverTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/c20/PakoArcaneRetrieverTest.java
index 5f7ab83c38..849e3ede9b 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/c20/PakoArcaneRetrieverTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/c20/PakoArcaneRetrieverTest.java
@@ -1,96 +1,96 @@
-
-package org.mage.test.cards.single.c20;
-
-import mage.cards.Card;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.counters.CounterType;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class PakoArcaneRetrieverTest extends CardTestPlayerBase {
-
- @Test
- public void test_CheckExiled() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
-
- addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
- addCard(Zone.LIBRARY, playerB, "Pillarfield Ox", 1);
-
- skipInitShuffling();
- // Partner with Pako, Arcane Retriever
- // You may play noncreature cards from exile with fetch counters on them if you
- // exiled them, and you may spend mana as though it were mana of any color to cast those spells.
- addCard(Zone.BATTLEFIELD, playerA, "Haldan, Avid Arcanist", 1);
- // Partner with Haldan, Avid Arcanist
- // Haste
- // Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way.
- addCard(Zone.BATTLEFIELD, playerA, "Pako, Arcane Retriever", 1); // Creature {3}{R}{G} (3/3)
-
- attack(1, playerA, "Pako, Arcane Retriever");
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertLife(playerA, 20);
- assertLife(playerB, 17);
-
- assertExileCount(playerA, "Silvercoat Lion", 1);
- assertExileCount(playerB, "Pillarfield Ox", 1);
-
- for(Card card :currentGame.getExile().getAllCards(currentGame)) {
- Assert.assertTrue(card.getName() + " has a fetch counter",card.getCounters(currentGame).getCount(CounterType.FETCH) == 1);
- }
-
- }
-
- @Test
- public void test_CastExiled() {
- // setStrictChooseMode(true);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
-
- addCard(Zone.LIBRARY, playerA, "Lightning Bolt", 1); // Instant 3 damge
- // Create a 3/3 green Centaur creature token.
- addCard(Zone.LIBRARY, playerB, "Call of the Conclave", 1); // Sorcery {W}{G}
-
- skipInitShuffling();
- // Partner with Pako, Arcane Retriever
- // You may play noncreature cards from exile with fetch counters on them if you
- // exiled them, and you may spend mana as though it were mana of any color to cast those spells.
- addCard(Zone.BATTLEFIELD, playerA, "Haldan, Avid Arcanist", 1);
- // Partner with Haldan, Avid Arcanist
- // Haste
- // Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way.
- addCard(Zone.BATTLEFIELD, playerA, "Pako, Arcane Retriever", 1); // Creature {3}{R}{G} (3/3)
-
- attack(1, playerA, "Pako, Arcane Retriever");
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Call of the Conclave");
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertLife(playerA, 20);
- assertLife(playerB, 12); // 3+2 (attack) + 3 Lighning Bolt
-
- assertGraveyardCount(playerA, "Lightning Bolt", 1);
- assertGraveyardCount(playerB, "Call of the Conclave", 1);
-
-
- }
-}
+
+package org.mage.test.cards.single.c20;
+
+import mage.cards.Card;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class PakoArcaneRetrieverTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_CheckExiled() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
+
+ addCard(Zone.LIBRARY, playerA, "Silvercoat Lion", 1);
+ addCard(Zone.LIBRARY, playerB, "Pillarfield Ox", 1);
+
+ skipInitShuffling();
+ // Partner with Pako, Arcane Retriever
+ // You may play noncreature cards from exile with fetch counters on them if you
+ // exiled them, and you may spend mana as though it were mana of any color to cast those spells.
+ addCard(Zone.BATTLEFIELD, playerA, "Haldan, Avid Arcanist", 1);
+ // Partner with Haldan, Avid Arcanist
+ // Haste
+ // Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way.
+ addCard(Zone.BATTLEFIELD, playerA, "Pako, Arcane Retriever", 1); // Creature {3}{R}{G} (3/3)
+
+ attack(1, playerA, "Pako, Arcane Retriever");
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 17);
+
+ assertExileCount(playerA, "Silvercoat Lion", 1);
+ assertExileCount(playerB, "Pillarfield Ox", 1);
+
+ for(Card card :currentGame.getExile().getAllCards(currentGame)) {
+ Assert.assertTrue(card.getName() + " has a fetch counter",card.getCounters(currentGame).getCount(CounterType.FETCH) == 1);
+ }
+
+ }
+
+ @Test
+ public void test_CastExiled() {
+ // setStrictChooseMode(true);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
+
+ addCard(Zone.LIBRARY, playerA, "Lightning Bolt", 1); // Instant 3 damge
+ // Create a 3/3 green Centaur creature token.
+ addCard(Zone.LIBRARY, playerB, "Call of the Conclave", 1); // Sorcery {W}{G}
+
+ skipInitShuffling();
+ // Partner with Pako, Arcane Retriever
+ // You may play noncreature cards from exile with fetch counters on them if you
+ // exiled them, and you may spend mana as though it were mana of any color to cast those spells.
+ addCard(Zone.BATTLEFIELD, playerA, "Haldan, Avid Arcanist", 1);
+ // Partner with Haldan, Avid Arcanist
+ // Haste
+ // Whenever Pako, Arcane Retriever attacks, exile the top card of each player's library and put a fetch counter on each of them. Put a +1/+1 counter on Pako for each noncreature card exiled this way.
+ addCard(Zone.BATTLEFIELD, playerA, "Pako, Arcane Retriever", 1); // Creature {3}{R}{G} (3/3)
+
+ attack(1, playerA, "Pako, Arcane Retriever");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Call of the Conclave");
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 12); // 3+2 (attack) + 3 Lighning Bolt
+
+ assertGraveyardCount(playerA, "Lightning Bolt", 1);
+ assertGraveyardCount(playerB, "Call of the Conclave", 1);
+
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/DemonsHornTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/DemonsHornTest.java
index 6f91f4cbde..c8c47a1bee 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/DemonsHornTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/dst/DemonsHornTest.java
@@ -1,72 +1,72 @@
-package org.mage.test.cards.single.dst;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class DemonsHornTest extends CardTestPlayerBase {
-
-
- @Test
- public void testWithBlackSpell() {
- setStrictChooseMode(true);
-
- // When Abyssal Gatekeeper dies, each player sacrifices a creature.
- addCard(Zone.HAND, playerA, "Abyssal Gatekeeper", 1); // Creature {2}{B} 1/1
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
-
- // Whenever a player casts a black spell, you may gain 1 life.
- addCard(Zone.BATTLEFIELD, playerB, "Demon's Horn", 1);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Abyssal Gatekeeper");
- setChoice(playerB, true);
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Abyssal Gatekeeper", 1);
-
- assertLife(playerA, 20);
- assertLife(playerB, 21);
- }
-
- /**
- * https://github.com/magefree/mage/issues/6890
- *
- * Color == Color Identity #6890
- *
- * Alesha, Who Smiles at Death triggers Demon's Horn
- */
- @Test
- public void testSpellWithBlackManaOnlyInTriggeredOptionalCost() {
- setStrictChooseMode(true);
-
- // First strike
- // Whenever Alesha, Who Smiles at Death attacks, you may pay {W/B}{W/B}. If you do, return target creature card with power 2 or less from your graveyard to the battlefield tapped and attacking.
- addCard(Zone.HAND, playerA, "Alesha, Who Smiles at Death", 1); // Creature {2}{R} 3/2
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
-
- // Whenever a player casts a black spell, you may gain 1 life.
- addCard(Zone.BATTLEFIELD, playerB, "Demon's Horn", 1);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alesha, Who Smiles at Death");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Alesha, Who Smiles at Death", 1);
-
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- }
-
-}
+package org.mage.test.cards.single.dst;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class DemonsHornTest extends CardTestPlayerBase {
+
+
+ @Test
+ public void testWithBlackSpell() {
+ setStrictChooseMode(true);
+
+ // When Abyssal Gatekeeper dies, each player sacrifices a creature.
+ addCard(Zone.HAND, playerA, "Abyssal Gatekeeper", 1); // Creature {2}{B} 1/1
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
+
+ // Whenever a player casts a black spell, you may gain 1 life.
+ addCard(Zone.BATTLEFIELD, playerB, "Demon's Horn", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Abyssal Gatekeeper");
+ setChoice(playerB, true);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Abyssal Gatekeeper", 1);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 21);
+ }
+
+ /**
+ * https://github.com/magefree/mage/issues/6890
+ *
+ * Color == Color Identity #6890
+ *
+ * Alesha, Who Smiles at Death triggers Demon's Horn
+ */
+ @Test
+ public void testSpellWithBlackManaOnlyInTriggeredOptionalCost() {
+ setStrictChooseMode(true);
+
+ // First strike
+ // Whenever Alesha, Who Smiles at Death attacks, you may pay {W/B}{W/B}. If you do, return target creature card with power 2 or less from your graveyard to the battlefield tapped and attacking.
+ addCard(Zone.HAND, playerA, "Alesha, Who Smiles at Death", 1); // Creature {2}{R} 3/2
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+
+ // Whenever a player casts a black spell, you may gain 1 life.
+ addCard(Zone.BATTLEFIELD, playerB, "Demon's Horn", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alesha, Who Smiles at Death");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Alesha, Who Smiles at Death", 1);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/BarteredCowTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/BarteredCowTest.java
index 4e951974c1..7be461ae76 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/BarteredCowTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/BarteredCowTest.java
@@ -1,88 +1,88 @@
-package org.mage.test.cards.single.eld;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class BarteredCowTest extends CardTestPlayerBase {
-
- @Test
- public void testDiesTrigger() {
- setStrictChooseMode(true);
-
- // When Bartered Cow dies or when you discard it, create a Food token.
- addCard(Zone.BATTLEFIELD, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
-
- addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
- addCard(Zone.BATTLEFIELD, playerB, "Mountain");
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Bartered Cow");
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerB, "Lightning Bolt", 1);
- assertGraveyardCount(playerA, "Bartered Cow", 1);
- assertPermanentCount(playerA, "Food", 1);
- }
-
- @Test
- public void testDiscardTrigger() {
- setStrictChooseMode(true);
-
- // When Bartered Cow dies or when you discard it, create a Food token.
- addCard(Zone.HAND, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
- // Choose one —
- // • Target player discards a card.
- // • Target creature gets +2/-1 until end of turn.
- // • Target creature gains swampwalk until end of turn. (It can't be blocked as long as defending player controls a Swamp.)
- addCard(Zone.HAND, playerB, "Funeral Charm", 1); // Instant {B}
- addCard(Zone.BATTLEFIELD, playerB, "Swamp");
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Funeral Charm");
- setModeChoice(playerB, "1");
- addTarget(playerB, playerA);
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerB, "Funeral Charm", 1);
- assertGraveyardCount(playerA, "Bartered Cow", 1);
- assertPermanentCount(playerA, "Food", 1);
- }
-
- @Test
- public void testDiscardTriggerWithTorturedExistence() {
- setStrictChooseMode(true);
-
- // When Bartered Cow dies or when you discard it, create a Food token.
- addCard(Zone.HAND, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
-
- // {B}, Discard a creature card: Return target creature card from your graveyard to your hand.
- addCard(Zone.BATTLEFIELD, playerA, "Tortured Existence", 1); // Instant {B}
- addCard(Zone.BATTLEFIELD, playerA, "Swamp");
- addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Discard a creature card");
- setChoice(playerA, "Bartered Cow");
- addTarget(playerA, "Silvercoat Lion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Bartered Cow", 1);
- assertHandCount(playerA, "Silvercoat Lion", 1);
- assertPermanentCount(playerA, "Food", 1);
- }
-
-}
+package org.mage.test.cards.single.eld;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class BarteredCowTest extends CardTestPlayerBase {
+
+ @Test
+ public void testDiesTrigger() {
+ setStrictChooseMode(true);
+
+ // When Bartered Cow dies or when you discard it, create a Food token.
+ addCard(Zone.BATTLEFIELD, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
+
+ addCard(Zone.HAND, playerB, "Lightning Bolt", 1);
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Bartered Cow");
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerB, "Lightning Bolt", 1);
+ assertGraveyardCount(playerA, "Bartered Cow", 1);
+ assertPermanentCount(playerA, "Food", 1);
+ }
+
+ @Test
+ public void testDiscardTrigger() {
+ setStrictChooseMode(true);
+
+ // When Bartered Cow dies or when you discard it, create a Food token.
+ addCard(Zone.HAND, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
+ // Choose one —
+ // • Target player discards a card.
+ // • Target creature gets +2/-1 until end of turn.
+ // • Target creature gains swampwalk until end of turn. (It can't be blocked as long as defending player controls a Swamp.)
+ addCard(Zone.HAND, playerB, "Funeral Charm", 1); // Instant {B}
+ addCard(Zone.BATTLEFIELD, playerB, "Swamp");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Funeral Charm");
+ setModeChoice(playerB, "1");
+ addTarget(playerB, playerA);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerB, "Funeral Charm", 1);
+ assertGraveyardCount(playerA, "Bartered Cow", 1);
+ assertPermanentCount(playerA, "Food", 1);
+ }
+
+ @Test
+ public void testDiscardTriggerWithTorturedExistence() {
+ setStrictChooseMode(true);
+
+ // When Bartered Cow dies or when you discard it, create a Food token.
+ addCard(Zone.HAND, playerA, "Bartered Cow"); // Creature {3}{W} 3/3
+
+ // {B}, Discard a creature card: Return target creature card from your graveyard to your hand.
+ addCard(Zone.BATTLEFIELD, playerA, "Tortured Existence", 1); // Instant {B}
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp");
+ addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion");
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{B}, Discard a creature card");
+ setChoice(playerA, "Bartered Cow");
+ addTarget(playerA, "Silvercoat Lion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Bartered Cow", 1);
+ assertHandCount(playerA, "Silvercoat Lion", 1);
+ assertPermanentCount(playerA, "Food", 1);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/OnceUponATimeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/OnceUponATimeTest.java
index ec736c19a5..2982fe655c 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/OnceUponATimeTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/OnceUponATimeTest.java
@@ -1,89 +1,89 @@
-package org.mage.test.cards.single.eld;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class OnceUponATimeTest extends CardTestPlayerBase {
-
- @Test
- public void test_castRegularly() {
- setStrictChooseMode(true);
-
- addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
- addCard(Zone.LIBRARY, playerA, "Plains", 4);
- skipInitShuffling();
-
- // If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.
- // Look at the top five cards of your library.
- // You may reveal a creature or land card from among them and put it into your hand.
- // Put the rest on the bottom of your library in a random order.
- addCard(Zone.HAND, playerA, "Once Upon a Time"); // Instant {1}{G}
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
- addCard(Zone.HAND, playerA, "Forest", 1);
-
- playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Once Upon a Time");
-
- setChoice(playerA, false); // Cast without paying its mana cost?
-
- setChoice(playerA, true); // Do you wish to reveal a creature or land card and put into your hand?
- setChoice(playerA, "Silvercoat Lion");
-
- setStopAt(2, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Once Upon a Time", 1);
- assertTappedCount("Forest", true, 2);
- assertHandCount(playerA, "Silvercoat Lion", 1);
- }
-
- @Test
- public void test_castForFree() {
- setStrictChooseMode(true);
-
- addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
- addCard(Zone.LIBRARY, playerA, "Plains", 4);
-
- addCard(Zone.LIBRARY, playerB, "Silvercoat Lion", 5);
-
- skipInitShuffling();
-
- // If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.
- // Look at the top five cards of your library.
- // You may reveal a creature or land card from among them and put it into your hand.
- // Put the rest on the bottom of your library in a random order.
- addCard(Zone.HAND, playerA, "Once Upon a Time"); // Instant {1}{G}
- addCard(Zone.HAND, playerB, "Once Upon a Time"); // Instant {1}{G}
-
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Once Upon a Time");
- setChoice(playerA, true); // Cast without paying its mana cost?
- setChoice(playerA, true); // Do you wish to reveal a creature or land card and put into your hand?
- setChoice(playerA, "Silvercoat Lion");
-
- castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Once Upon a Time");
- setChoice(playerB, true); // Cast without paying its mana cost?
- setChoice(playerB, true); // Do you wish to reveal a creature or land card and put into your hand?
- setChoice(playerB, "Silvercoat Lion");
-
- setStopAt(2, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Once Upon a Time", 1);
- assertGraveyardCount(playerB, "Once Upon a Time", 1);
-
- assertHandCount(playerA, "Silvercoat Lion", 1);
- assertHandCount(playerB, "Silvercoat Lion", 2);
- }
+package org.mage.test.cards.single.eld;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class OnceUponATimeTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_castRegularly() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
+ addCard(Zone.LIBRARY, playerA, "Plains", 4);
+ skipInitShuffling();
+
+ // If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.
+ // Look at the top five cards of your library.
+ // You may reveal a creature or land card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
+ addCard(Zone.HAND, playerA, "Once Upon a Time"); // Instant {1}{G}
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
+ addCard(Zone.HAND, playerA, "Forest", 1);
+
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Once Upon a Time");
+
+ setChoice(playerA, false); // Cast without paying its mana cost?
+
+ setChoice(playerA, true); // Do you wish to reveal a creature or land card and put into your hand?
+ setChoice(playerA, "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Once Upon a Time", 1);
+ assertTappedCount("Forest", true, 2);
+ assertHandCount(playerA, "Silvercoat Lion", 1);
+ }
+
+ @Test
+ public void test_castForFree() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.LIBRARY, playerA, "Silvercoat Lion");
+ addCard(Zone.LIBRARY, playerA, "Plains", 4);
+
+ addCard(Zone.LIBRARY, playerB, "Silvercoat Lion", 5);
+
+ skipInitShuffling();
+
+ // If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.
+ // Look at the top five cards of your library.
+ // You may reveal a creature or land card from among them and put it into your hand.
+ // Put the rest on the bottom of your library in a random order.
+ addCard(Zone.HAND, playerA, "Once Upon a Time"); // Instant {1}{G}
+ addCard(Zone.HAND, playerB, "Once Upon a Time"); // Instant {1}{G}
+
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Once Upon a Time");
+ setChoice(playerA, true); // Cast without paying its mana cost?
+ setChoice(playerA, true); // Do you wish to reveal a creature or land card and put into your hand?
+ setChoice(playerA, "Silvercoat Lion");
+
+ castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Once Upon a Time");
+ setChoice(playerB, true); // Cast without paying its mana cost?
+ setChoice(playerB, true); // Do you wish to reveal a creature or land card and put into your hand?
+ setChoice(playerB, "Silvercoat Lion");
+
+ setStopAt(2, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Once Upon a Time", 1);
+ assertGraveyardCount(playerB, "Once Upon a Time", 1);
+
+ assertHandCount(playerA, "Silvercoat Lion", 1);
+ assertHandCount(playerB, "Silvercoat Lion", 2);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/SyrGwynHeroOfAshvaleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/SyrGwynHeroOfAshvaleTest.java
index d00136c897..eab21ba875 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/SyrGwynHeroOfAshvaleTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/eld/SyrGwynHeroOfAshvaleTest.java
@@ -1,57 +1,57 @@
-package org.mage.test.cards.single.eld;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class SyrGwynHeroOfAshvaleTest extends CardTestPlayerBase {
-
- @Test
- public void equipKnightTest() {
- // Equipped creature gets +2/+2 and has trample and lifelink.
- addCard(Zone.BATTLEFIELD, playerA, "Behemoth Sledge"); // Artifact - Equipment {1}{G}{W}
-
- // Vigilance, menace
- // Whenever an equipped creature you control attacks, you draw a card and you lose 1 life.
- // Equipment you control have equip Knight {0}.
- addCard(Zone.BATTLEFIELD, playerA, "Syr Gwyn, Hero of Ashvale"); // Legendary Creature {3}{R}{W}{B} 5/5 Human Knight
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip Knight", "Syr Gwyn, Hero of Ashvale");
-
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertPowerToughness(playerA, "Syr Gwyn, Hero of Ashvale", 7, 7);
-
- }
-
- @Test
- public void equipKnightTestInstantSpeed() {
- // Equipped creature gets +2/+2 and has trample and lifelink.
- addCard(Zone.BATTLEFIELD, playerA, "Behemoth Sledge"); // Artifact - Equipment {1}{G}{W}
-
- // You may activate equip abilities any time you could cast an instant.
- addCard(Zone.BATTLEFIELD, playerA, "Leonin Shikari", 2); // Creature 2/2
-
- // Vigilance, menace
- // Whenever an equipped creature you control attacks, you draw a card and you lose 1 life.
- // Equipment you control have equip Knight {0}.
- addCard(Zone.BATTLEFIELD, playerA, "Syr Gwyn, Hero of Ashvale"); // Legendary Creature {3}{R}{W}{B} 5/5 Human Knight
-
- activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "Equip Knight", "Syr Gwyn, Hero of Ashvale");
-
-
- setStopAt(1, PhaseStep.END_COMBAT);
- execute();
-
- assertPowerToughness(playerA, "Syr Gwyn, Hero of Ashvale", 7, 7);
-
- }
-}
+package org.mage.test.cards.single.eld;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class SyrGwynHeroOfAshvaleTest extends CardTestPlayerBase {
+
+ @Test
+ public void equipKnightTest() {
+ // Equipped creature gets +2/+2 and has trample and lifelink.
+ addCard(Zone.BATTLEFIELD, playerA, "Behemoth Sledge"); // Artifact - Equipment {1}{G}{W}
+
+ // Vigilance, menace
+ // Whenever an equipped creature you control attacks, you draw a card and you lose 1 life.
+ // Equipment you control have equip Knight {0}.
+ addCard(Zone.BATTLEFIELD, playerA, "Syr Gwyn, Hero of Ashvale"); // Legendary Creature {3}{R}{W}{B} 5/5 Human Knight
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip Knight", "Syr Gwyn, Hero of Ashvale");
+
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPowerToughness(playerA, "Syr Gwyn, Hero of Ashvale", 7, 7);
+
+ }
+
+ @Test
+ public void equipKnightTestInstantSpeed() {
+ // Equipped creature gets +2/+2 and has trample and lifelink.
+ addCard(Zone.BATTLEFIELD, playerA, "Behemoth Sledge"); // Artifact - Equipment {1}{G}{W}
+
+ // You may activate equip abilities any time you could cast an instant.
+ addCard(Zone.BATTLEFIELD, playerA, "Leonin Shikari", 2); // Creature 2/2
+
+ // Vigilance, menace
+ // Whenever an equipped creature you control attacks, you draw a card and you lose 1 life.
+ // Equipment you control have equip Knight {0}.
+ addCard(Zone.BATTLEFIELD, playerA, "Syr Gwyn, Hero of Ashvale"); // Legendary Creature {3}{R}{W}{B} 5/5 Human Knight
+
+ activateAbility(1, PhaseStep.DECLARE_ATTACKERS, playerA, "Equip Knight", "Syr Gwyn, Hero of Ashvale");
+
+
+ setStopAt(1, PhaseStep.END_COMBAT);
+ execute();
+
+ assertPowerToughness(playerA, "Syr Gwyn, Hero of Ashvale", 7, 7);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/grn/PeltCollectorTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/grn/PeltCollectorTest.java
index 1833604d25..ea87437b73 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/grn/PeltCollectorTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/grn/PeltCollectorTest.java
@@ -1,245 +1,245 @@
-package org.mage.test.cards.single.grn;
-
-import mage.abilities.keyword.TrampleAbility;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.counters.CounterType;
-import mage.filter.Filter;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- * @author LevelX2, TheElk801
- */
-public class PeltCollectorTest extends CardTestPlayerBase {
-
- private static final String collector = "Pelt Collector";
- private static final String lion = "Silvercoat Lion";
- private static final String trostani = "Trostani Discordant";
- private static final String bear = "Grizzly Bears";
- private static final String murder = "Murder";
- private static final String courser = "Centaur Courser";
- private static final String growth = "Giant Growth";
- private static final String karstoderm = "Karstoderm";
-
- @Test
- public void test_Simple() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
- // Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than Pelt Collector's, put a +1/+1 counter on Pelt Collector.
- // As long as Pelt Collector has three or more +1/+1 counters on it, it has trample.
- addCard(Zone.HAND, playerA, collector, 1); // Creature {G}
- addCard(Zone.HAND, playerA, lion, 1); // Creature {1}{W}
-
- addCard(Zone.BATTLEFIELD, playerB, collector, 1);// Creature {G}
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, collector);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lion);
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
-
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerB, collector, 1, 1);
-
- assertPowerToughness(playerA, lion, 2, 2);
- assertPowerToughness(playerA, collector, 2, 2);
- assertAbility(playerA, collector, TrampleAbility.getInstance(), false);
- assertAbility(playerB, collector, TrampleAbility.getInstance(), false);
- }
-
- /**
- * To determine if Pelt Collector’s first ability triggers when a creature
- * enters the battlefield, use the creature’s power after applying any
- * static abilities (such as that of Trostani Discordant) that modify its
- * power.
- */
- @Test
- public void test_TrostaniDiscordant() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
- addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
- // Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than Pelt Collector's, put a +1/+1 counter on Pelt Collector.
- // As long as Pelt Collector has three or more +1/+1 counters on it, it has trample.
- addCard(Zone.HAND, playerA, collector, 1); // Creature {G}
- addCard(Zone.HAND, playerA, lion, 1); // Creature {1}{W}
- // Other creatures you control get +1/+1.
- // When Trostani Discordant enters the battlefield, create two 1/1 white Soldier creature tokens with lifelink.
- // At the beginning of your end step, each player gains control of all creatures they own.
- addCard(Zone.HAND, playerA, trostani, 1); // Creature {3}{G}{W} /1/4)
-
- addCard(Zone.BATTLEFIELD, playerB, collector, 1);// Creature {G}
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, trostani);
-
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, collector);
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, lion);
-
- setStopAt(3, PhaseStep.BEGIN_COMBAT);
-
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerB, collector, 1, 1);
-
- assertPowerToughness(playerA, "Soldier", 2, 2, Filter.ComparisonScope.All);
-
- assertPowerToughness(playerA, lion, 3, 3);
- assertPowerToughness(playerA, collector, 3, 3);
- assertAbility(playerA, collector, TrampleAbility.getInstance(), false);
- assertAbility(playerB, collector, TrampleAbility.getInstance(), false);
-
- }
-
-
- @Test
- public void testEntersTrigger() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, bear);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 2, 2);
- assertCounterCount(collector, CounterType.P1P1, 1);
- }
-
- @Test
- public void testEntersTrigger2() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, karstoderm);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, karstoderm);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 2, 2);
- assertCounterCount(collector, CounterType.P1P1, 1);
- }
-
- @Test
- public void testDiesTrigger() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, bear);
- addCard(Zone.HAND, playerA, murder);
- addCard(Zone.BATTLEFIELD, playerA, "Bayou", 5);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, bear);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 2, 2);
- assertCounterCount(collector, CounterType.P1P1, 1);
- }
-
- @Test
- public void testDiesTrigger2() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, courser);
- addCard(Zone.HAND, playerA, murder);
- addCard(Zone.BATTLEFIELD, playerA, "Bayou", 6);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, courser);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, courser);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 3, 3);
- assertCounterCount(collector, CounterType.P1P1, 2);
- }
-
- @Test
- public void testDiesTrigger3() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, karstoderm);
- addCard(Zone.HAND, playerA, murder);
- addCard(Zone.BATTLEFIELD, playerA, "Bayou", 7);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, karstoderm);
- castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, karstoderm);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 3, 3);
- assertCounterCount(collector, CounterType.P1P1, 2);
- }
-
- @Test
- public void testInterveningIf() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, bear);
- addCard(Zone.HAND, playerA, growth);
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, growth, collector);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 4, 4);
- assertCounterCount(collector, CounterType.P1P1, 0);
- }
-
- @Test
- public void testInterveningIf2() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, collector);
- addCard(Zone.HAND, playerA, bear);
- addCard(Zone.HAND, playerA, "Scar");
- addCard(Zone.BATTLEFIELD, playerA, "Bayou", 3);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scar", bear);
-
- setStopAt(1, PhaseStep.END_TURN);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, collector, 1, 1);
- assertCounterCount(collector, CounterType.P1P1, 0);
- }
-}
+package org.mage.test.cards.single.grn;
+
+import mage.abilities.keyword.TrampleAbility;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.filter.Filter;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author LevelX2, TheElk801
+ */
+public class PeltCollectorTest extends CardTestPlayerBase {
+
+ private static final String collector = "Pelt Collector";
+ private static final String lion = "Silvercoat Lion";
+ private static final String trostani = "Trostani Discordant";
+ private static final String bear = "Grizzly Bears";
+ private static final String murder = "Murder";
+ private static final String courser = "Centaur Courser";
+ private static final String growth = "Giant Growth";
+ private static final String karstoderm = "Karstoderm";
+
+ @Test
+ public void test_Simple() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
+ // Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than Pelt Collector's, put a +1/+1 counter on Pelt Collector.
+ // As long as Pelt Collector has three or more +1/+1 counters on it, it has trample.
+ addCard(Zone.HAND, playerA, collector, 1); // Creature {G}
+ addCard(Zone.HAND, playerA, lion, 1); // Creature {1}{W}
+
+ addCard(Zone.BATTLEFIELD, playerB, collector, 1);// Creature {G}
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, collector);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, lion);
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerB, collector, 1, 1);
+
+ assertPowerToughness(playerA, lion, 2, 2);
+ assertPowerToughness(playerA, collector, 2, 2);
+ assertAbility(playerA, collector, TrampleAbility.getInstance(), false);
+ assertAbility(playerB, collector, TrampleAbility.getInstance(), false);
+ }
+
+ /**
+ * To determine if Pelt Collector’s first ability triggers when a creature
+ * enters the battlefield, use the creature’s power after applying any
+ * static abilities (such as that of Trostani Discordant) that modify its
+ * power.
+ */
+ @Test
+ public void test_TrostaniDiscordant() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Plains", 3);
+ // Whenever another creature you control enters the battlefield or dies, if that creature's power is greater than Pelt Collector's, put a +1/+1 counter on Pelt Collector.
+ // As long as Pelt Collector has three or more +1/+1 counters on it, it has trample.
+ addCard(Zone.HAND, playerA, collector, 1); // Creature {G}
+ addCard(Zone.HAND, playerA, lion, 1); // Creature {1}{W}
+ // Other creatures you control get +1/+1.
+ // When Trostani Discordant enters the battlefield, create two 1/1 white Soldier creature tokens with lifelink.
+ // At the beginning of your end step, each player gains control of all creatures they own.
+ addCard(Zone.HAND, playerA, trostani, 1); // Creature {3}{G}{W} /1/4)
+
+ addCard(Zone.BATTLEFIELD, playerB, collector, 1);// Creature {G}
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, trostani);
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, collector);
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, lion);
+
+ setStopAt(3, PhaseStep.BEGIN_COMBAT);
+
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerB, collector, 1, 1);
+
+ assertPowerToughness(playerA, "Soldier", 2, 2, Filter.ComparisonScope.All);
+
+ assertPowerToughness(playerA, lion, 3, 3);
+ assertPowerToughness(playerA, collector, 3, 3);
+ assertAbility(playerA, collector, TrampleAbility.getInstance(), false);
+ assertAbility(playerB, collector, TrampleAbility.getInstance(), false);
+
+ }
+
+
+ @Test
+ public void testEntersTrigger() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, bear);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 2, 2);
+ assertCounterCount(collector, CounterType.P1P1, 1);
+ }
+
+ @Test
+ public void testEntersTrigger2() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, karstoderm);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, karstoderm);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 2, 2);
+ assertCounterCount(collector, CounterType.P1P1, 1);
+ }
+
+ @Test
+ public void testDiesTrigger() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, bear);
+ addCard(Zone.HAND, playerA, murder);
+ addCard(Zone.BATTLEFIELD, playerA, "Bayou", 5);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, bear);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 2, 2);
+ assertCounterCount(collector, CounterType.P1P1, 1);
+ }
+
+ @Test
+ public void testDiesTrigger2() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, courser);
+ addCard(Zone.HAND, playerA, murder);
+ addCard(Zone.BATTLEFIELD, playerA, "Bayou", 6);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, courser);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, courser);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 3, 3);
+ assertCounterCount(collector, CounterType.P1P1, 2);
+ }
+
+ @Test
+ public void testDiesTrigger3() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, karstoderm);
+ addCard(Zone.HAND, playerA, murder);
+ addCard(Zone.BATTLEFIELD, playerA, "Bayou", 7);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, karstoderm);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, murder, karstoderm);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 3, 3);
+ assertCounterCount(collector, CounterType.P1P1, 2);
+ }
+
+ @Test
+ public void testInterveningIf() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, bear);
+ addCard(Zone.HAND, playerA, growth);
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, growth, collector);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 4, 4);
+ assertCounterCount(collector, CounterType.P1P1, 0);
+ }
+
+ @Test
+ public void testInterveningIf2() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, collector);
+ addCard(Zone.HAND, playerA, bear);
+ addCard(Zone.HAND, playerA, "Scar");
+ addCard(Zone.BATTLEFIELD, playerA, "Bayou", 3);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bear);
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, true);
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Scar", bear);
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, collector, 1, 1);
+ assertCounterCount(collector, CounterType.P1P1, 0);
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/TormentOfHailfireTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/TormentOfHailfireTest.java
index 4d2d4d2aff..7dc01ca0e7 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/TormentOfHailfireTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/hou/TormentOfHailfireTest.java
@@ -1,88 +1,88 @@
-package org.mage.test.cards.single.hou;
-
-import java.io.FileNotFoundException;
-
-import mage.constants.MultiplayerAttackOption;
-import mage.constants.PhaseStep;
-import mage.constants.RangeOfInfluence;
-import mage.constants.Zone;
-import mage.game.FreeForAll;
-import mage.game.Game;
-import mage.game.GameException;
-import mage.game.mulligan.MulliganType;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestMultiPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
-
- @Override
- protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
- // Start Life = 2
- Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
- // Player order: A -> D -> C -> B
- playerA = createPlayer(game, playerA, "PlayerA");
- playerB = createPlayer(game, playerB, "PlayerB");
- playerC = createPlayer(game, playerC, "PlayerC");
- playerD = createPlayer(game, playerD, "PlayerD");
- return game;
- }
-
- @Test
- public void test_Normal() {
- setStrictChooseMode(true);
-
- // Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card.
- addCard(Zone.HAND, playerA, "Torment of Hailfire", 1); // Sorcery {X}{B}{B}
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 12);
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
- addCard(Zone.HAND, playerB, "Plains", 1);
-
- addCard(Zone.BATTLEFIELD, playerC, "Silvercoat Lion", 3);
-
- addCard(Zone.BATTLEFIELD, playerD, "Silvercoat Lion", 3);
- addCard(Zone.HAND, playerD, "Plains", 1);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Torment of Hailfire");
- setChoice(playerA, "X=10");
-
- setChoice(playerD, true);// Sacrifices a nonland permanent?
- setChoice(playerD, "Silvercoat Lion");
-
- setChoice(playerB, true);// Sacrifices a nonland permanent?
- setChoice(playerB, "Silvercoat Lion");
-
- setChoice(playerD, true);// Sacrifices a nonland permanent?
- setChoice(playerD, "Silvercoat Lion");
-
- setChoice(playerB, true);// Sacrifices a nonland permanent?
- setChoice(playerB, "Silvercoat Lion");
-
- setChoice(playerD, false);// Sacrifices a nonland permanent?
- setChoice(playerD, true);// Discard a card?
-
- setChoice(playerB, true);// Discard a card?
-
- setChoice(playerD, true);// Sacrifices a nonland permanent?
- setChoice(playerD, "Silvercoat Lion");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Torment of Hailfire", 1);
-
- assertLife(playerA, 20);
- assertLife(playerC, 20);
- assertLife(playerD, 2);
- assertLife(playerB, -1);
- Assert.assertFalse("Player B is dead", playerB.isInGame());
-
- }
-}
+package org.mage.test.cards.single.hou;
+
+import java.io.FileNotFoundException;
+
+import mage.constants.MultiplayerAttackOption;
+import mage.constants.PhaseStep;
+import mage.constants.RangeOfInfluence;
+import mage.constants.Zone;
+import mage.game.FreeForAll;
+import mage.game.Game;
+import mage.game.GameException;
+import mage.game.mulligan.MulliganType;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestMultiPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class TormentOfHailfireTest extends CardTestMultiPlayerBase {
+
+ @Override
+ protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
+ // Start Life = 2
+ Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
+ // Player order: A -> D -> C -> B
+ playerA = createPlayer(game, playerA, "PlayerA");
+ playerB = createPlayer(game, playerB, "PlayerB");
+ playerC = createPlayer(game, playerC, "PlayerC");
+ playerD = createPlayer(game, playerD, "PlayerD");
+ return game;
+ }
+
+ @Test
+ public void test_Normal() {
+ setStrictChooseMode(true);
+
+ // Repeat the following process X times. Each opponent loses 3 life unless they sacrifice a nonland permanent or discards a card.
+ addCard(Zone.HAND, playerA, "Torment of Hailfire", 1); // Sorcery {X}{B}{B}
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 12);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
+ addCard(Zone.HAND, playerB, "Plains", 1);
+
+ addCard(Zone.BATTLEFIELD, playerC, "Silvercoat Lion", 3);
+
+ addCard(Zone.BATTLEFIELD, playerD, "Silvercoat Lion", 3);
+ addCard(Zone.HAND, playerD, "Plains", 1);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Torment of Hailfire");
+ setChoice(playerA, "X=10");
+
+ setChoice(playerD, true);// Sacrifices a nonland permanent?
+ setChoice(playerD, "Silvercoat Lion");
+
+ setChoice(playerB, true);// Sacrifices a nonland permanent?
+ setChoice(playerB, "Silvercoat Lion");
+
+ setChoice(playerD, true);// Sacrifices a nonland permanent?
+ setChoice(playerD, "Silvercoat Lion");
+
+ setChoice(playerB, true);// Sacrifices a nonland permanent?
+ setChoice(playerB, "Silvercoat Lion");
+
+ setChoice(playerD, false);// Sacrifices a nonland permanent?
+ setChoice(playerD, true);// Discard a card?
+
+ setChoice(playerB, true);// Discard a card?
+
+ setChoice(playerD, true);// Sacrifices a nonland permanent?
+ setChoice(playerD, "Silvercoat Lion");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Torment of Hailfire", 1);
+
+ assertLife(playerA, 20);
+ assertLife(playerC, 20);
+ assertLife(playerD, 2);
+ assertLife(playerB, -1);
+ Assert.assertFalse("Player B is dead", playerB.isInGame());
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java
index c80bb289e7..0614756504 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/OboshThePreypiercerTest.java
@@ -1,34 +1,34 @@
-package org.mage.test.cards.single.iko;
-
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- * @author LevelX2
- */
-
-public class OboshThePreypiercerTest extends CardTestPlayerBase {
-
- @Test
- public void testZeroCMSIsHandledAsOdd() {
- setStrictChooseMode(true);
- // At the beginning of your upkeep, flip a coin. If you lose the flip, Mana Crypt deals 3 damage to you.
- // {T}: Add {C}{C}.
- addCard(Zone.BATTLEFIELD, playerA, "Mana Crypt");
- // Companion — Your starting deck contains only cards with odd converted mana costs and land cards.
- // If a source you control with an odd converted mana cost would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.
- addCard(Zone.BATTLEFIELD, playerA, "Obosh, the Preypiercer");
-
- // lose the flip
- setFlipCoinResult(playerA, false);
-
- setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
- execute();
- assertAllCommandsUsed();
-
- assertLife(playerA, 20 - 3);
- }
+package org.mage.test.cards.single.iko;
+
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ * @author LevelX2
+ */
+
+public class OboshThePreypiercerTest extends CardTestPlayerBase {
+
+ @Test
+ public void testZeroCMSIsHandledAsOdd() {
+ setStrictChooseMode(true);
+ // At the beginning of your upkeep, flip a coin. If you lose the flip, Mana Crypt deals 3 damage to you.
+ // {T}: Add {C}{C}.
+ addCard(Zone.BATTLEFIELD, playerA, "Mana Crypt");
+ // Companion — Your starting deck contains only cards with odd converted mana costs and land cards.
+ // If a source you control with an odd converted mana cost would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.
+ addCard(Zone.BATTLEFIELD, playerA, "Obosh, the Preypiercer");
+
+ // lose the flip
+ setFlipCoinResult(playerA, false);
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertLife(playerA, 20 - 3);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/SkycatSovereignTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/SkycatSovereignTest.java
index ddd6ca85e2..d94ae7d1b5 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/SkycatSovereignTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/iko/SkycatSovereignTest.java
@@ -1,90 +1,90 @@
-package org.mage.test.cards.single.iko;
-
-import mage.ObjectColor;
-import mage.abilities.keyword.FlyingAbility;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class SkycatSovereignTest extends CardTestPlayerBase {
-
- @Test
- public void test_BoostFromFlyers() {
- setStrictChooseMode(true);
-
- // Flying
- // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
- // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
- addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
-
- // Flying, vigilance
- addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
-
- setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
- assertPowerToughness(playerA, "Skycat Sovereign", 3, 3);
- }
-
- /**
- * Skycat Sovereign still gets +1/+1 for each creature that is supposed to have flying when there's an opposing Archetype of Imagination.
- */
- @Test
- public void test_NoBoostIfFlyingLost() {
- setStrictChooseMode(true);
-
- // Flying
- // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
- // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
- addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
-
- // Flying, vigilance
- addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
-
- // Creatures you control have flying.
- // Creatures your opponents control lose flying and can't have or gain flying.
- addCard(Zone.BATTLEFIELD, playerB, "Archetype of Imagination"); //
-
- setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
- execute();
-
- assertAllCommandsUsed();
- assertPowerToughness(playerA, "Skycat Sovereign", 1, 1);
- }
-
- @Test
- public void test_BoostFromToken() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Plains");
- addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
- // Flying
- // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
- // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
- addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
-
- // Flying, vigilance
- addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
-
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{W}{U}: Create");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Cat Bird", 1);
- assertColor(playerA, "Cat Bird", ObjectColor.WHITE, true);
- assertColor(playerA, "Cat Bird", ObjectColor.BLUE, false);
- assertAbility(playerA, "Cat Bird", FlyingAbility.getInstance(), true);
-
- assertPowerToughness(playerA, "Skycat Sovereign", 4, 4);
- }
+package org.mage.test.cards.single.iko;
+
+import mage.ObjectColor;
+import mage.abilities.keyword.FlyingAbility;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class SkycatSovereignTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_BoostFromFlyers() {
+ setStrictChooseMode(true);
+
+ // Flying
+ // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
+ // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
+ addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
+
+ // Flying, vigilance
+ addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+ assertPowerToughness(playerA, "Skycat Sovereign", 3, 3);
+ }
+
+ /**
+ * Skycat Sovereign still gets +1/+1 for each creature that is supposed to have flying when there's an opposing Archetype of Imagination.
+ */
+ @Test
+ public void test_NoBoostIfFlyingLost() {
+ setStrictChooseMode(true);
+
+ // Flying
+ // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
+ // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
+ addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
+
+ // Flying, vigilance
+ addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
+
+ // Creatures you control have flying.
+ // Creatures your opponents control lose flying and can't have or gain flying.
+ addCard(Zone.BATTLEFIELD, playerB, "Archetype of Imagination"); //
+
+ setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
+ execute();
+
+ assertAllCommandsUsed();
+ assertPowerToughness(playerA, "Skycat Sovereign", 1, 1);
+ }
+
+ @Test
+ public void test_BoostFromToken() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Plains");
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
+ // Flying
+ // Skycat Sovereign gets +1/+1 for each other creature you control with flying.
+ // {2}{W}{U}: Create a 1/1 white Cat Bird creature token with flying.
+ addCard(Zone.BATTLEFIELD, playerA, "Skycat Sovereign"); // Creature {W}{U} (1/1)
+
+ // Flying, vigilance
+ addCard(Zone.BATTLEFIELD, playerA, "Abbey Griffin", 2); // Creature — Griffin (2/2)
+
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{W}{U}: Create");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Cat Bird", 1);
+ assertColor(playerA, "Cat Bird", ObjectColor.WHITE, true);
+ assertColor(playerA, "Cat Bird", ObjectColor.BLUE, false);
+ assertAbility(playerA, "Cat Bird", FlyingAbility.getInstance(), true);
+
+ assertPowerToughness(playerA, "Skycat Sovereign", 4, 4);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh1/PlagueEngineerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh1/PlagueEngineerTest.java
index 2ef638aea1..8626a0bc76 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/mh1/PlagueEngineerTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/mh1/PlagueEngineerTest.java
@@ -1,39 +1,39 @@
-package org.mage.test.cards.single.mh1;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class PlagueEngineerTest extends CardTestPlayerBase {
-
- @Test
- public void test_Standard() {
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
- // Deathtouch
- // As Plague Engineer enters the battlefield, choose a creature type.
- // Creatures of the chosen type your opponents control get -1/-1.
- addCard(Zone.HAND, playerA, "Plague Engineer"); // Creature {2}{B} (2/2)
-
- addCard(Zone.BATTLEFIELD, playerA, "Defiant Elf", 2); //Creature - Elf (1/1)
- addCard(Zone.BATTLEFIELD, playerB, "Defiant Elf", 2); //Creature - Elf (1/1)
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plague Engineer");
- setChoice(playerA, "Elf");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertPermanentCount(playerA, "Plague Engineer", 1);
-
- assertPermanentCount(playerA, "Defiant Elf", 2);
- assertGraveyardCount(playerB, "Defiant Elf", 2);
-
- assertLife(playerA, 20);
- assertLife(playerB, 20);
- }
+package org.mage.test.cards.single.mh1;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class PlagueEngineerTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_Standard() {
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
+ // Deathtouch
+ // As Plague Engineer enters the battlefield, choose a creature type.
+ // Creatures of the chosen type your opponents control get -1/-1.
+ addCard(Zone.HAND, playerA, "Plague Engineer"); // Creature {2}{B} (2/2)
+
+ addCard(Zone.BATTLEFIELD, playerA, "Defiant Elf", 2); //Creature - Elf (1/1)
+ addCard(Zone.BATTLEFIELD, playerB, "Defiant Elf", 2); //Creature - Elf (1/1)
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Plague Engineer");
+ setChoice(playerA, "Elf");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Plague Engineer", 1);
+
+ assertPermanentCount(playerA, "Defiant Elf", 2);
+ assertGraveyardCount(playerB, "Defiant Elf", 2);
+
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/som/NimDeathmantleTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/som/NimDeathmantleTest.java
index 24990a6699..44104a5f8c 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/single/som/NimDeathmantleTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/som/NimDeathmantleTest.java
@@ -1,51 +1,51 @@
-package org.mage.test.cards.single.som;
-
-import mage.abilities.keyword.IntimidateAbility;
-import mage.constants.CardType;
-import mage.constants.PhaseStep;
-import mage.constants.SubType;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class NimDeathmantleTest extends CardTestPlayerBase {
-
- @Test
- public void test_Basic() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
- // Equipped creature gets +2/+2, has intimidate, and is a black Zombie.
- // Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it.
- addCard(Zone.HAND, playerA, "Nim Deathmantle"); // Artifact Equipment {2}
-
- addCard(Zone.BATTLEFIELD, playerB, "Mountain");
- addCard(Zone.HAND, playerB, "Lightning Bolt");
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nim Deathmantle");
-
- waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion");
- setChoice(playerA, true); // Message: Nim Deathmantle - Pay {4}?
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerB, "Lightning Bolt",1);
-
- assertPermanentCount(playerA, "Nim Deathmantle", 1);
-
- assertPowerToughness(playerA, "Silvercoat Lion", 4, 4);
- assertAbility(playerA, "Silvercoat Lion", IntimidateAbility.getInstance(), true);
- assertType("Silvercoat Lion", CardType.CREATURE, SubType.ZOMBIE);
-
- }
+package org.mage.test.cards.single.som;
+
+import mage.abilities.keyword.IntimidateAbility;
+import mage.constants.CardType;
+import mage.constants.PhaseStep;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class NimDeathmantleTest extends CardTestPlayerBase {
+
+ @Test
+ public void test_Basic() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
+ // Equipped creature gets +2/+2, has intimidate, and is a black Zombie.
+ // Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it.
+ addCard(Zone.HAND, playerA, "Nim Deathmantle"); // Artifact Equipment {2}
+
+ addCard(Zone.BATTLEFIELD, playerB, "Mountain");
+ addCard(Zone.HAND, playerB, "Lightning Bolt");
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Nim Deathmantle");
+
+ waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion");
+ setChoice(playerA, true); // Message: Nim Deathmantle - Pay {4}?
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerB, "Lightning Bolt",1);
+
+ assertPermanentCount(playerA, "Nim Deathmantle", 1);
+
+ assertPowerToughness(playerA, "Silvercoat Lion", 4, 4);
+ assertAbility(playerA, "Silvercoat Lion", IntimidateAbility.getInstance(), true);
+ assertType("Silvercoat Lion", CardType.CREATURE, SubType.ZOMBIE);
+
+ }
}
\ No newline at end of file
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/KardurDoomscourgeAndKithkinMourncallerTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/KardurDoomscourgeAndKithkinMourncallerTest.java
index 4895bca974..206a3dea49 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/KardurDoomscourgeAndKithkinMourncallerTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/KardurDoomscourgeAndKithkinMourncallerTest.java
@@ -1,103 +1,103 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.mage.test.cards.triggers;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author jeffwadsworth
- */
-public class KardurDoomscourgeAndKithkinMourncallerTest extends CardTestPlayerBase {
-
- @Test
- public void testKDRemovedFromCombatViaRegenerateAbility() {
- setStrictChooseMode(true);
- // Kardur, Doomscourge: if an attacking creature dies, each opponent loses 1 life and you gain 1 life
- addCard(Zone.BATTLEFIELD, playerA, "Kardur, Doomscourge");
- addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers");
- addCard(Zone.BATTLEFIELD, playerB, "Serra Angel");
- addCard(Zone.HAND, playerA, "Regenerate");
- addCard(Zone.HAND, playerA, "Terror");
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Regenerate", "Elvish Archers");
-
- attack(1, playerA, "Elvish Archers");
- block(1, playerB, "Serra Angel", "Elvish Archers"); // regeneration shield used up and EA is removed from combat
-
- castSpell(1, PhaseStep.END_COMBAT, playerA, "Terror", "Elvish Archers"); // still within the combat phase, the EA is destroyed/dies
-
- setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
- execute();
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Elvish Archers", 1);
-
- // does not fire due to the Elvish Archers not in an attacking state
- assertLife(playerA, 20);
- assertLife(playerB, 20);
-
- }
-
- @Test
- public void testSuccessfulKDTrigger() {
- setStrictChooseMode(true);
- // Kardur, Doomscourge: if an attacking creature dies, each opponent loses 1 life and you gain 1 life
- addCard(Zone.BATTLEFIELD, playerA, "Kardur, Doomscourge");
- addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers"); // 2/2 first strike
- addCard(Zone.BATTLEFIELD, playerB, "Serra Angel"); // 4/4 vigilance
-
- attack(1, playerA, "Elvish Archers");
- block(1, playerB, "Serra Angel", "Elvish Archers"); // Elvish Archer dies causing KD to trigger
-
- setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
- execute();
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Elvish Archers", 1);
-
- // successful fire so playerA gains 1 life and playerB loses 1 life
- assertLife(playerA, 21);
- assertLife(playerB, 19);
-
- }
-
- @Test
- public void testKMTrigger() {
- setStrictChooseMode(true);
- // Kithkin Mourncaller: if an elf or kithkin dies, you may draw a card
- addCard(Zone.BATTLEFIELD, playerA, "Kithkin Mourncaller");
- addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers"); // 2/1 first strike
- addCard(Zone.BATTLEFIELD, playerA, "Pearled Unicorn"); // 2/2
- addCard(Zone.BATTLEFIELD, playerB, "Serra Angel"); // 4/4 vigilance
- addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear"); // 2/2
- addCard(Zone.LIBRARY, playerA, "Island", 2); // used for draw trigger
-
- attack(1, playerA, "Elvish Archers");
- attack(1, playerA, "Pearled Unicorn");
- block(1, playerB, "Serra Angel", "Elvish Archers"); // Elvish Achers will die and trigger KM
- block(1, playerB, "Runeclaw Bear", "Pearled Unicorn"); // Pearled Unicorn will die but not trigger KM
-
- setChoice(playerA, "Yes"); // accept the drawing of a card from the single trigger (Elvish Archers "elf type")
-
- setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
- execute();
- assertAllCommandsUsed();
-
- assertGraveyardCount(playerA, "Elvish Archers", 1);
- assertGraveyardCount(playerA, "Pearled Unicorn", 1);
-
- // successful fire due to dead Elvish Archers (elf) so playerA draws a card
- assertHandCount(playerA, 1);
-
- }
-
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.mage.test.cards.triggers;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public class KardurDoomscourgeAndKithkinMourncallerTest extends CardTestPlayerBase {
+
+ @Test
+ public void testKDRemovedFromCombatViaRegenerateAbility() {
+ setStrictChooseMode(true);
+ // Kardur, Doomscourge: if an attacking creature dies, each opponent loses 1 life and you gain 1 life
+ addCard(Zone.BATTLEFIELD, playerA, "Kardur, Doomscourge");
+ addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers");
+ addCard(Zone.BATTLEFIELD, playerB, "Serra Angel");
+ addCard(Zone.HAND, playerA, "Regenerate");
+ addCard(Zone.HAND, playerA, "Terror");
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 4);
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 4);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Regenerate", "Elvish Archers");
+
+ attack(1, playerA, "Elvish Archers");
+ block(1, playerB, "Serra Angel", "Elvish Archers"); // regeneration shield used up and EA is removed from combat
+
+ castSpell(1, PhaseStep.END_COMBAT, playerA, "Terror", "Elvish Archers"); // still within the combat phase, the EA is destroyed/dies
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Elvish Archers", 1);
+
+ // does not fire due to the Elvish Archers not in an attacking state
+ assertLife(playerA, 20);
+ assertLife(playerB, 20);
+
+ }
+
+ @Test
+ public void testSuccessfulKDTrigger() {
+ setStrictChooseMode(true);
+ // Kardur, Doomscourge: if an attacking creature dies, each opponent loses 1 life and you gain 1 life
+ addCard(Zone.BATTLEFIELD, playerA, "Kardur, Doomscourge");
+ addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers"); // 2/2 first strike
+ addCard(Zone.BATTLEFIELD, playerB, "Serra Angel"); // 4/4 vigilance
+
+ attack(1, playerA, "Elvish Archers");
+ block(1, playerB, "Serra Angel", "Elvish Archers"); // Elvish Archer dies causing KD to trigger
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Elvish Archers", 1);
+
+ // successful fire so playerA gains 1 life and playerB loses 1 life
+ assertLife(playerA, 21);
+ assertLife(playerB, 19);
+
+ }
+
+ @Test
+ public void testKMTrigger() {
+ setStrictChooseMode(true);
+ // Kithkin Mourncaller: if an elf or kithkin dies, you may draw a card
+ addCard(Zone.BATTLEFIELD, playerA, "Kithkin Mourncaller");
+ addCard(Zone.BATTLEFIELD, playerA, "Elvish Archers"); // 2/1 first strike
+ addCard(Zone.BATTLEFIELD, playerA, "Pearled Unicorn"); // 2/2
+ addCard(Zone.BATTLEFIELD, playerB, "Serra Angel"); // 4/4 vigilance
+ addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear"); // 2/2
+ addCard(Zone.LIBRARY, playerA, "Island", 2); // used for draw trigger
+
+ attack(1, playerA, "Elvish Archers");
+ attack(1, playerA, "Pearled Unicorn");
+ block(1, playerB, "Serra Angel", "Elvish Archers"); // Elvish Achers will die and trigger KM
+ block(1, playerB, "Runeclaw Bear", "Pearled Unicorn"); // Pearled Unicorn will die but not trigger KM
+
+ setChoice(playerA, "Yes"); // accept the drawing of a card from the single trigger (Elvish Archers "elf type")
+
+ setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
+ execute();
+ assertAllCommandsUsed();
+
+ assertGraveyardCount(playerA, "Elvish Archers", 1);
+ assertGraveyardCount(playerA, "Pearled Unicorn", 1);
+
+ // successful fire due to dead Elvish Archers (elf) so playerA draws a card
+ assertHandCount(playerA, 1);
+
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/AshenRiderTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/AshenRiderTest.java
index ed02d06706..9de90e04f4 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/AshenRiderTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/AshenRiderTest.java
@@ -1,68 +1,68 @@
-package org.mage.test.cards.triggers.dies;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class AshenRiderTest extends CardTestPlayerBase {
-
- /*
- * Volrath, the Shapestealer and Ashen Rider, Ashen Rider has a counter on it:
- Turn Volrath into Ashen Rider:
- Destroy the Volrath (who's the Ashen Rider) with Putrefy:
- The death trigger for the Volrath copying Ashen Rider did not trigger.
- */
- @Test
- public void cartelAristrocraftInteractionOpponentDoesNotPayLife() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
-
- addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
- addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
- addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
-
- // Flying
- // When Ashen Rider enters the battlefield or dies, exile target permanent.
- addCard(Zone.BATTLEFIELD, playerA, "Ashen Rider"); // Creature {4}{W}{W}{B}{B}
-
- // At the beginning of combat on your turn, put a -1/-1 counter on up to one target creature.
- // {1}: Until your next turn, Volrath, the Shapestealer becomes a copy of target creature with a counter on it, except it's 7/5 and it has this ability.
- addCard(Zone.HAND, playerA, "Volrath, the Shapestealer"); // Creature {2}{B}{G}{U}
- addTarget(playerA, "Ashen Rider");
-
- // Destroy target artifact or creature. It can't be regenerated.
- addCard(Zone.HAND, playerA, "Putrefy"); // Instant {1}{B}{G}
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volrath, the Shapestealer");
-
- activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: Until your next turn");
- addTarget(playerA, "Ashen Rider");
-
- waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
-
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Putrefy", "Ashen Rider[only copy]");
-
- addTarget(playerA, "Silvercoat Lion"); // Dies trigger of Volrath, the Shapestealer copied from Ashen Rider
-
- setStopAt(3, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertAllCommandsUsed();
-
- assertPowerToughness(playerA, "Ashen Rider", 4,4);
-
- assertGraveyardCount(playerA, "Putrefy", 1);
- assertGraveyardCount(playerA, "Volrath, the Shapestealer", 1);
-
- assertExileCount(playerB, "Silvercoat Lion", 1);
-
- }
-}
+package org.mage.test.cards.triggers.dies;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class AshenRiderTest extends CardTestPlayerBase {
+
+ /*
+ * Volrath, the Shapestealer and Ashen Rider, Ashen Rider has a counter on it:
+ Turn Volrath into Ashen Rider:
+ Destroy the Volrath (who's the Ashen Rider) with Putrefy:
+ The death trigger for the Volrath copying Ashen Rider did not trigger.
+ */
+ @Test
+ public void cartelAristrocraftInteractionOpponentDoesNotPayLife() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
+ addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
+
+ // Flying
+ // When Ashen Rider enters the battlefield or dies, exile target permanent.
+ addCard(Zone.BATTLEFIELD, playerA, "Ashen Rider"); // Creature {4}{W}{W}{B}{B}
+
+ // At the beginning of combat on your turn, put a -1/-1 counter on up to one target creature.
+ // {1}: Until your next turn, Volrath, the Shapestealer becomes a copy of target creature with a counter on it, except it's 7/5 and it has this ability.
+ addCard(Zone.HAND, playerA, "Volrath, the Shapestealer"); // Creature {2}{B}{G}{U}
+ addTarget(playerA, "Ashen Rider");
+
+ // Destroy target artifact or creature. It can't be regenerated.
+ addCard(Zone.HAND, playerA, "Putrefy"); // Instant {1}{B}{G}
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Volrath, the Shapestealer");
+
+ activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}: Until your next turn");
+ addTarget(playerA, "Ashen Rider");
+
+ waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN);
+
+ castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Putrefy", "Ashen Rider[only copy]");
+
+ addTarget(playerA, "Silvercoat Lion"); // Dies trigger of Volrath, the Shapestealer copied from Ashen Rider
+
+ setStopAt(3, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertAllCommandsUsed();
+
+ assertPowerToughness(playerA, "Ashen Rider", 4,4);
+
+ assertGraveyardCount(playerA, "Putrefy", 1);
+ assertGraveyardCount(playerA, "Volrath, the Shapestealer", 1);
+
+ assertExileCount(playerB, "Silvercoat Lion", 1);
+
+ }
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderColorChangeTest.java b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderColorChangeTest.java
index e3cf24ae1e..c4f23c1ebf 100644
--- a/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderColorChangeTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/commander/duel/CommanderColorChangeTest.java
@@ -1,122 +1,122 @@
-package org.mage.test.commander.duel;
-
-import java.io.FileNotFoundException;
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import mage.game.Game;
-import mage.game.GameException;
-import mage.game.permanent.Permanent;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestCommanderDuelBase;
-
-/**
- *
- * @author LevelX2
- */
-
-public class CommanderColorChangeTest extends CardTestCommanderDuelBase {
-
- @Override
- protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
- // When a player casts a spell or a creature attacks, exile Norin the Wary. Return it to the battlefield under its owner's control at the beginning of the next end step.
- setDecknamePlayerA("CMDNorinTheWary.dck"); // Commander = Norin the Wary {R}
- return super.createNewGameAndPlayers();
- }
-
- @Test
- public void castCommanderWithAddedBlueColor() {
- setStrictChooseMode(true);
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
-
- // As Painter's Servant enters the battlefield, choose a color.
- // All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
- addCard(Zone.HAND, playerA, "Painter's Servant", 1); // Artifact Creature {2}
-
- // Whenever a player casts a blue spell, you may gain 1 life.
- addCard(Zone.BATTLEFIELD, playerA, "Kraken's Eye", 1);
-
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
- setChoice(playerA, "Blue");
-
- // When a player casts a spell or a creature attacks, exile Norin the Wary.
- // Return it to the battlefield under its owner's control at the beginning of the next end step.
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Norin the Wary");
- setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
- assertAllCommandsUsed();
-
- assertPermanentCount(playerA, "Norin the Wary", 1);
-
- Permanent norin = getPermanent("Norin the Wary", playerA);
- Assert.assertEquals(true, norin.getColor(currentGame).isBlue());
- Assert.assertEquals(true, norin.getColor(currentGame).isRed());
-
- Permanent kraken = getPermanent("Kraken's Eye", playerA);
- Assert.assertEquals(true, kraken.getColor(currentGame).isBlue());
-
- assertLife(playerA, 41);
- assertLife(playerB, 40);
-
- }
-
-
- /**
- * I played a Painter's Servant, named black, but the other commanders get a extra colors
- * Later it got removed but the commanders and some cards still have the extra color
- * I played it again later, named green, and the previously affected cards get the extra color
- * so now they have 2 extra colors and the commander get and additional color on top of that
- * And finally I got the empty hand error #6738 on my turn for what I assume is the Painter's Servant + Grindstone combo I have,
- * but nonetheless manage to tie the game so it go into a second game and the issue carry over,
- * all the commanders have all the extra colors they gain from the first game
- */
-
- @Test
- public void castCommanderWithoutAddedBlueColor() {
- setStrictChooseMode(true);
-
- addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
-
- // As Painter's Servant enters the battlefield, choose a color.
- // All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
- addCard(Zone.HAND, playerA, "Painter's Servant", 1); // Artifact Creature {2}
-
- // Whenever a player casts a blue spell, you may gain 1 life.
- addCard(Zone.BATTLEFIELD, playerA, "Kraken's Eye", 1);
-
-
- // Exile target artifact or enchantment.
- addCard(Zone.HAND, playerB, "Altar's Light", 1); // Instant {2}{W}{W}
- addCard(Zone.BATTLEFIELD, playerB, "Plains", 4);
-
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
- setChoice(playerA, "Blue");
-
- // When a player casts a spell or a creature attacks, exile Norin the Wary.
- // Return it to the battlefield under its owner's control at the beginning of the next end step.
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Norin the Wary");
- setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Altar's Light", "Painter's Servant", "Norin the Wary");
- setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertPermanentCount(playerA, "Norin the Wary", 1);
- assertAllCommandsUsed();
-
- Permanent norin = getPermanent("Norin the Wary", playerA);
- Assert.assertEquals(false, norin.getColor(currentGame).isBlue());
- Assert.assertEquals(true, norin.getColor(currentGame).isRed());
-
- Permanent kraken = getPermanent("Kraken's Eye", playerA);
- Assert.assertEquals(false, kraken.getColor(currentGame).isBlue());
-
- assertLife(playerA, 42);
- assertLife(playerB, 40);
-
- }
-}
+package org.mage.test.commander.duel;
+
+import java.io.FileNotFoundException;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.GameException;
+import mage.game.permanent.Permanent;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestCommanderDuelBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+
+public class CommanderColorChangeTest extends CardTestCommanderDuelBase {
+
+ @Override
+ protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
+ // When a player casts a spell or a creature attacks, exile Norin the Wary. Return it to the battlefield under its owner's control at the beginning of the next end step.
+ setDecknamePlayerA("CMDNorinTheWary.dck"); // Commander = Norin the Wary {R}
+ return super.createNewGameAndPlayers();
+ }
+
+ @Test
+ public void castCommanderWithAddedBlueColor() {
+ setStrictChooseMode(true);
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+
+ // As Painter's Servant enters the battlefield, choose a color.
+ // All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
+ addCard(Zone.HAND, playerA, "Painter's Servant", 1); // Artifact Creature {2}
+
+ // Whenever a player casts a blue spell, you may gain 1 life.
+ addCard(Zone.BATTLEFIELD, playerA, "Kraken's Eye", 1);
+
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
+ setChoice(playerA, "Blue");
+
+ // When a player casts a spell or a creature attacks, exile Norin the Wary.
+ // Return it to the battlefield under its owner's control at the beginning of the next end step.
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Norin the Wary");
+ setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+ assertAllCommandsUsed();
+
+ assertPermanentCount(playerA, "Norin the Wary", 1);
+
+ Permanent norin = getPermanent("Norin the Wary", playerA);
+ Assert.assertEquals(true, norin.getColor(currentGame).isBlue());
+ Assert.assertEquals(true, norin.getColor(currentGame).isRed());
+
+ Permanent kraken = getPermanent("Kraken's Eye", playerA);
+ Assert.assertEquals(true, kraken.getColor(currentGame).isBlue());
+
+ assertLife(playerA, 41);
+ assertLife(playerB, 40);
+
+ }
+
+
+ /**
+ * I played a Painter's Servant, named black, but the other commanders get a extra colors
+ * Later it got removed but the commanders and some cards still have the extra color
+ * I played it again later, named green, and the previously affected cards get the extra color
+ * so now they have 2 extra colors and the commander get and additional color on top of that
+ * And finally I got the empty hand error #6738 on my turn for what I assume is the Painter's Servant + Grindstone combo I have,
+ * but nonetheless manage to tie the game so it go into a second game and the issue carry over,
+ * all the commanders have all the extra colors they gain from the first game
+ */
+
+ @Test
+ public void castCommanderWithoutAddedBlueColor() {
+ setStrictChooseMode(true);
+
+ addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
+
+ // As Painter's Servant enters the battlefield, choose a color.
+ // All cards that aren't on the battlefield, spells, and permanents are the chosen color in addition to their other colors.
+ addCard(Zone.HAND, playerA, "Painter's Servant", 1); // Artifact Creature {2}
+
+ // Whenever a player casts a blue spell, you may gain 1 life.
+ addCard(Zone.BATTLEFIELD, playerA, "Kraken's Eye", 1);
+
+
+ // Exile target artifact or enchantment.
+ addCard(Zone.HAND, playerB, "Altar's Light", 1); // Instant {2}{W}{W}
+ addCard(Zone.BATTLEFIELD, playerB, "Plains", 4);
+
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Painter's Servant");
+ setChoice(playerA, "Blue");
+
+ // When a player casts a spell or a creature attacks, exile Norin the Wary.
+ // Return it to the battlefield under its owner's control at the beginning of the next end step.
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Norin the Wary");
+ setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Altar's Light", "Painter's Servant", "Norin the Wary");
+ setChoice(playerA, true); // Whenever a player casts a blue spell, you may gain 1 life. Choices: Yes - No
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPermanentCount(playerA, "Norin the Wary", 1);
+ assertAllCommandsUsed();
+
+ Permanent norin = getPermanent("Norin the Wary", playerA);
+ Assert.assertEquals(false, norin.getColor(currentGame).isBlue());
+ Assert.assertEquals(true, norin.getColor(currentGame).isRed());
+
+ Permanent kraken = getPermanent("Kraken's Eye", playerA);
+ Assert.assertEquals(false, kraken.getColor(currentGame).isBlue());
+
+ assertLife(playerA, 42);
+ assertLife(playerB, 40);
+
+ }
+}
diff --git a/Mage/src/main/java/mage/ApprovingObject.java b/Mage/src/main/java/mage/ApprovingObject.java
index 3701880d71..9468aad157 100644
--- a/Mage/src/main/java/mage/ApprovingObject.java
+++ b/Mage/src/main/java/mage/ApprovingObject.java
@@ -1,28 +1,28 @@
-package mage;
-
-import mage.abilities.Ability;
-import mage.game.Game;
-
-/**
- *
- * @author LevelX2
- */
-public class ApprovingObject {
-
- private final Ability approvingAbility;
- private final MageObjectReference approvingMageObjectReference;
-
- public ApprovingObject(Ability source, Game game) {
- this.approvingAbility = source;
- this.approvingMageObjectReference = new MageObjectReference(source.getSourceId(), game);
- }
-
- public Ability getApprovingAbility() {
- return approvingAbility;
- }
-
- public MageObjectReference getApprovingMageObjectReference() {
- return approvingMageObjectReference;
- }
-
-}
+package mage;
+
+import mage.abilities.Ability;
+import mage.game.Game;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ApprovingObject {
+
+ private final Ability approvingAbility;
+ private final MageObjectReference approvingMageObjectReference;
+
+ public ApprovingObject(Ability source, Game game) {
+ this.approvingAbility = source;
+ this.approvingMageObjectReference = new MageObjectReference(source.getSourceId(), game);
+ }
+
+ public Ability getApprovingAbility() {
+ return approvingAbility;
+ }
+
+ public MageObjectReference getApprovingMageObjectReference() {
+ return approvingMageObjectReference;
+ }
+
+}
diff --git a/Mage/src/main/java/mage/abilities/common/AttackingCreaturePutIntoGraveyardTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttackingCreaturePutIntoGraveyardTriggeredAbility.java
index 58f656fdd8..8f83c2834c 100644
--- a/Mage/src/main/java/mage/abilities/common/AttackingCreaturePutIntoGraveyardTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/AttackingCreaturePutIntoGraveyardTriggeredAbility.java
@@ -1,124 +1,124 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package mage.abilities.common;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.effects.Effect;
-import mage.constants.Zone;
-import mage.filter.FilterPermanent;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import static mage.game.events.GameEvent.EventType.END_COMBAT_STEP_POST;
-import static mage.game.events.GameEvent.EventType.REMOVED_FROM_COMBAT;
-import static mage.game.events.GameEvent.EventType.ZONE_CHANGE;
-import mage.game.events.ZoneChangeEvent;
-import mage.game.permanent.Permanent;
-
-/**
- *
- * @author weirddan455 and jeffwadsworth
- */
-public class AttackingCreaturePutIntoGraveyardTriggeredAbility extends TriggeredAbilityImpl {
-
- protected FilterPermanent filterPermanent;
- private final boolean onlyToControllerGraveyard;
- private final boolean itDies;
-
- public AttackingCreaturePutIntoGraveyardTriggeredAbility(Effect effect, FilterPermanent filterPermanent, Boolean onlyToControllerGraveyard, Boolean itDies, Boolean optional) {
- super(Zone.BATTLEFIELD, effect, optional);
- this.filterPermanent = filterPermanent;
- this.onlyToControllerGraveyard = onlyToControllerGraveyard;
- this.itDies = itDies;
- }
-
- private AttackingCreaturePutIntoGraveyardTriggeredAbility(final AttackingCreaturePutIntoGraveyardTriggeredAbility ability) {
- super(ability);
- this.filterPermanent = ability.filterPermanent;
- this.onlyToControllerGraveyard = ability.onlyToControllerGraveyard;
- this.itDies = ability.itDies;
- }
-
- @Override
- public AttackingCreaturePutIntoGraveyardTriggeredAbility copy() {
- return new AttackingCreaturePutIntoGraveyardTriggeredAbility(this);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- switch (event.getType()) {
- case ATTACKER_DECLARED:
- case END_COMBAT_STEP_POST:
- case ZONE_CHANGE:
- case REMOVED_FROM_COMBAT:
- return true;
- default:
- return false;
- }
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- switch (event.getType()) {
- case ATTACKER_DECLARED:
- Permanent permanent = game.getPermanent(event.getSourceId());
- if (permanent != null
- && !filterPermanent.match(permanent, game)) {
- return false;
- }
- List attackersList = new ArrayList<>();
- List attackersListCopy = (List) game.getState().getValue(this.getSourceId() + "Attackers");
- if (attackersListCopy == null) {
- attackersListCopy = attackersList;
- }
- attackersListCopy.add(event.getSourceId()); // add the filtered creature to the list
- game.getState().setValue(this.getSourceId() + "Attackers", attackersListCopy);
- return false;
- case END_COMBAT_STEP_POST:
- game.getState().setValue(this.getSourceId() + "Attackers", null);
- return false;
- case ZONE_CHANGE:
- ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- if (zEvent.getFromZone() == Zone.BATTLEFIELD
- && zEvent.getToZone() == Zone.GRAVEYARD) {
- if (onlyToControllerGraveyard
- && !this.isControlledBy(game.getOwnerId(zEvent.getTargetId()))) {
- return false;
- }
- if (itDies
- && !zEvent.isDiesEvent()) {
- return false;
- }
- List attackers = (List) game.getState().getValue(this.getSourceId() + "Attackers");
- return attackers != null
- && attackers.contains(zEvent.getTargetId());
- }
- case REMOVED_FROM_COMBAT:
- // a card removed from combat is no longer an attacker or blocker so remove it from the list
- List attackersListRFC = (List) game.getState().getValue(this.getSourceId() + "Attackers");
- if (attackersListRFC != null
- && attackersListRFC.contains(event.getTargetId())) {
- attackersListRFC.remove(event.getTargetId());
- game.getState().setValue(this.getSourceId() + "Attackers", attackersListRFC);
- }
-
- default:
- return false;
- }
- }
-
- @Override
- public String getTriggerPhrase() {
- if (itDies) {
- return "Whenever " + filterPermanent.getMessage() + " dies, ";
- }
- return "Whenever " + filterPermanent.getMessage() + " is put into " + (onlyToControllerGraveyard ? "your" : "a")
- + " graveyard from the battlefield, ";
- }
-
-}
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package mage.abilities.common;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.Effect;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import static mage.game.events.GameEvent.EventType.END_COMBAT_STEP_POST;
+import static mage.game.events.GameEvent.EventType.REMOVED_FROM_COMBAT;
+import static mage.game.events.GameEvent.EventType.ZONE_CHANGE;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+
+/**
+ *
+ * @author weirddan455 and jeffwadsworth
+ */
+public class AttackingCreaturePutIntoGraveyardTriggeredAbility extends TriggeredAbilityImpl {
+
+ protected FilterPermanent filterPermanent;
+ private final boolean onlyToControllerGraveyard;
+ private final boolean itDies;
+
+ public AttackingCreaturePutIntoGraveyardTriggeredAbility(Effect effect, FilterPermanent filterPermanent, Boolean onlyToControllerGraveyard, Boolean itDies, Boolean optional) {
+ super(Zone.BATTLEFIELD, effect, optional);
+ this.filterPermanent = filterPermanent;
+ this.onlyToControllerGraveyard = onlyToControllerGraveyard;
+ this.itDies = itDies;
+ }
+
+ private AttackingCreaturePutIntoGraveyardTriggeredAbility(final AttackingCreaturePutIntoGraveyardTriggeredAbility ability) {
+ super(ability);
+ this.filterPermanent = ability.filterPermanent;
+ this.onlyToControllerGraveyard = ability.onlyToControllerGraveyard;
+ this.itDies = ability.itDies;
+ }
+
+ @Override
+ public AttackingCreaturePutIntoGraveyardTriggeredAbility copy() {
+ return new AttackingCreaturePutIntoGraveyardTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ switch (event.getType()) {
+ case ATTACKER_DECLARED:
+ case END_COMBAT_STEP_POST:
+ case ZONE_CHANGE:
+ case REMOVED_FROM_COMBAT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ switch (event.getType()) {
+ case ATTACKER_DECLARED:
+ Permanent permanent = game.getPermanent(event.getSourceId());
+ if (permanent != null
+ && !filterPermanent.match(permanent, game)) {
+ return false;
+ }
+ List attackersList = new ArrayList<>();
+ List attackersListCopy = (List) game.getState().getValue(this.getSourceId() + "Attackers");
+ if (attackersListCopy == null) {
+ attackersListCopy = attackersList;
+ }
+ attackersListCopy.add(event.getSourceId()); // add the filtered creature to the list
+ game.getState().setValue(this.getSourceId() + "Attackers", attackersListCopy);
+ return false;
+ case END_COMBAT_STEP_POST:
+ game.getState().setValue(this.getSourceId() + "Attackers", null);
+ return false;
+ case ZONE_CHANGE:
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (zEvent.getFromZone() == Zone.BATTLEFIELD
+ && zEvent.getToZone() == Zone.GRAVEYARD) {
+ if (onlyToControllerGraveyard
+ && !this.isControlledBy(game.getOwnerId(zEvent.getTargetId()))) {
+ return false;
+ }
+ if (itDies
+ && !zEvent.isDiesEvent()) {
+ return false;
+ }
+ List attackers = (List) game.getState().getValue(this.getSourceId() + "Attackers");
+ return attackers != null
+ && attackers.contains(zEvent.getTargetId());
+ }
+ case REMOVED_FROM_COMBAT:
+ // a card removed from combat is no longer an attacker or blocker so remove it from the list
+ List attackersListRFC = (List) game.getState().getValue(this.getSourceId() + "Attackers");
+ if (attackersListRFC != null
+ && attackersListRFC.contains(event.getTargetId())) {
+ attackersListRFC.remove(event.getTargetId());
+ game.getState().setValue(this.getSourceId() + "Attackers", attackersListRFC);
+ }
+
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public String getTriggerPhrase() {
+ if (itDies) {
+ return "Whenever " + filterPermanent.getMessage() + " dies, ";
+ }
+ return "Whenever " + filterPermanent.getMessage() + " is put into " + (onlyToControllerGraveyard ? "your" : "a")
+ + " graveyard from the battlefield, ";
+ }
+
+}
diff --git a/Mage/src/main/java/mage/abilities/condition/common/DidNotAttackThisTurnEnchantedCondition.java b/Mage/src/main/java/mage/abilities/condition/common/DidNotAttackThisTurnEnchantedCondition.java
index 80fc43a452..a45b5d5eaf 100644
--- a/Mage/src/main/java/mage/abilities/condition/common/DidNotAttackThisTurnEnchantedCondition.java
+++ b/Mage/src/main/java/mage/abilities/condition/common/DidNotAttackThisTurnEnchantedCondition.java
@@ -1,31 +1,31 @@
-package mage.abilities.condition.common;
-
-import mage.MageObjectReference;
-import mage.abilities.Ability;
-import mage.abilities.condition.Condition;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.watchers.common.AttackedThisTurnWatcher;
-
-/**
- *
- * @author jeffwadsworth
- */
-public enum DidNotAttackThisTurnEnchantedCondition implements Condition {
-
- instance;
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent auraPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
- if (auraPermanent != null) {
- Permanent enchantedPermanent = game.getPermanent(auraPermanent.getAttachedTo());
- AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
- return enchantedPermanent != null
- && watcher != null
- && !watcher.getAttackedThisTurnCreatures().contains(
- new MageObjectReference(enchantedPermanent, game));
- }
- return false;
- }
-}
+package mage.abilities.condition.common;
+
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.watchers.common.AttackedThisTurnWatcher;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public enum DidNotAttackThisTurnEnchantedCondition implements Condition {
+
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent auraPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (auraPermanent != null) {
+ Permanent enchantedPermanent = game.getPermanent(auraPermanent.getAttachedTo());
+ AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
+ return enchantedPermanent != null
+ && watcher != null
+ && !watcher.getAttackedThisTurnCreatures().contains(
+ new MageObjectReference(enchantedPermanent, game));
+ }
+ return false;
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeDividedValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeDividedValue.java
index d6a3138440..351dcea28b 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeDividedValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeDividedValue.java
@@ -1,48 +1,48 @@
-package mage.abilities.dynamicvalue.common;
-
-import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
-import mage.game.Game;
-import mage.players.Player;
-
-/**
- *
- * @author LevelX2
- */
-public class ControllerLifeDividedValue implements DynamicValue {
-
- private final Integer divider;
-
- public ControllerLifeDividedValue(Integer divider) {
- this.divider = divider;
- }
-
- public ControllerLifeDividedValue(final ControllerLifeDividedValue dynamicValue) {
- this.divider = dynamicValue.divider;
- }
-
- @Override
- public int calculate(Game game, Ability sourceAbility, Effect effect) {
- Player p = game.getPlayer(sourceAbility.getControllerId());
- if (p != null) {
- return p.getLife() / divider;
- }
- return 0;
- }
-
- @Override
- public ControllerLifeDividedValue copy() {
- return new ControllerLifeDividedValue(this);
- }
-
- @Override
- public String toString() {
- return "X";
- }
-
- @Override
- public String getMessage() {
- return "";
- }
-}
+package mage.abilities.dynamicvalue.common;
+
+import mage.abilities.Ability;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.game.Game;
+import mage.players.Player;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class ControllerLifeDividedValue implements DynamicValue {
+
+ private final Integer divider;
+
+ public ControllerLifeDividedValue(Integer divider) {
+ this.divider = divider;
+ }
+
+ public ControllerLifeDividedValue(final ControllerLifeDividedValue dynamicValue) {
+ this.divider = dynamicValue.divider;
+ }
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ Player p = game.getPlayer(sourceAbility.getControllerId());
+ if (p != null) {
+ return p.getLife() / divider;
+ }
+ return 0;
+ }
+
+ @Override
+ public ControllerLifeDividedValue copy() {
+ return new ControllerLifeDividedValue(this);
+ }
+
+ @Override
+ public String toString() {
+ return "X";
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestCMCOfPermanentValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestCMCOfPermanentValue.java
index 338e4b9b51..65bac59159 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestCMCOfPermanentValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/HighestCMCOfPermanentValue.java
@@ -1,62 +1,62 @@
-package mage.abilities.dynamicvalue.common;
-
-import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.effects.Effect;
-import mage.filter.FilterPermanent;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-
-/**
- *
- * @author LevelX2
- */
-public class HighestCMCOfPermanentValue implements DynamicValue {
-
- private final FilterPermanent filter;
- private final boolean onlyIfCanBeSacrificed;
-
- public HighestCMCOfPermanentValue(FilterPermanent filter, boolean onlyIfCanBeSacrificed) {
- super();
- this.filter = filter;
- this.onlyIfCanBeSacrificed = onlyIfCanBeSacrificed;
- }
-
- public HighestCMCOfPermanentValue(final HighestCMCOfPermanentValue dynamicValue) {
- this.filter = dynamicValue.filter;
- this.onlyIfCanBeSacrificed = dynamicValue.onlyIfCanBeSacrificed;
- }
-
- @Override
- public int calculate(Game game, Ability sourceAbility, Effect effect) {
- int value = 0;
- Player controller = game.getPlayer(sourceAbility.getControllerId());
- if (controller != null) {
- for (Permanent permanent : game.getBattlefield()
- .getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility.getSourceId(), game)) {
- if ((!onlyIfCanBeSacrificed || controller.canPaySacrificeCost(permanent, sourceAbility, sourceAbility.getControllerId(), game))
- && permanent.getManaValue() > value) {
- value = permanent.getManaValue();
- }
-
- }
- }
- return value;
- }
-
- @Override
- public HighestCMCOfPermanentValue copy() {
- return new HighestCMCOfPermanentValue(this);
- }
-
- @Override
- public String toString() {
- return "X";
- }
-
- @Override
- public String getMessage() {
- return filter.getMessage();
- }
-}
+package mage.abilities.dynamicvalue.common;
+
+import mage.abilities.Ability;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.effects.Effect;
+import mage.filter.FilterPermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class HighestCMCOfPermanentValue implements DynamicValue {
+
+ private final FilterPermanent filter;
+ private final boolean onlyIfCanBeSacrificed;
+
+ public HighestCMCOfPermanentValue(FilterPermanent filter, boolean onlyIfCanBeSacrificed) {
+ super();
+ this.filter = filter;
+ this.onlyIfCanBeSacrificed = onlyIfCanBeSacrificed;
+ }
+
+ public HighestCMCOfPermanentValue(final HighestCMCOfPermanentValue dynamicValue) {
+ this.filter = dynamicValue.filter;
+ this.onlyIfCanBeSacrificed = dynamicValue.onlyIfCanBeSacrificed;
+ }
+
+ @Override
+ public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ int value = 0;
+ Player controller = game.getPlayer(sourceAbility.getControllerId());
+ if (controller != null) {
+ for (Permanent permanent : game.getBattlefield()
+ .getActivePermanents(filter, sourceAbility.getControllerId(), sourceAbility.getSourceId(), game)) {
+ if ((!onlyIfCanBeSacrificed || controller.canPaySacrificeCost(permanent, sourceAbility, sourceAbility.getControllerId(), game))
+ && permanent.getManaValue() > value) {
+ value = permanent.getManaValue();
+ }
+
+ }
+ }
+ return value;
+ }
+
+ @Override
+ public HighestCMCOfPermanentValue copy() {
+ return new HighestCMCOfPermanentValue(this);
+ }
+
+ @Override
+ public String toString() {
+ return "X";
+ }
+
+ @Override
+ public String getMessage() {
+ return filter.getMessage();
+ }
+}
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index d6c8c2a37b..6a2eb625d3 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -1,5084 +1,5084 @@
-package mage.players;
-
-import com.google.common.collect.ImmutableMap;
-import mage.*;
-import mage.abilities.*;
-import mage.abilities.ActivatedAbility.ActivationStatus;
-import mage.abilities.common.PassAbility;
-import mage.abilities.common.PlayLandAsCommanderAbility;
-import mage.abilities.common.WhileSearchingPlayFromLibraryAbility;
-import mage.abilities.common.delayed.AtTheEndOfTurnStepPostDelayedTriggeredAbility;
-import mage.abilities.costs.*;
-import mage.abilities.costs.mana.AlternateManaPaymentAbility;
-import mage.abilities.costs.mana.ManaCost;
-import mage.abilities.costs.mana.ManaCosts;
-import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.RestrictionEffect;
-import mage.abilities.effects.RestrictionUntapNotMoreThanEffect;
-import mage.abilities.effects.common.LoseControlOnOtherPlayersControllerEffect;
-import mage.abilities.keyword.*;
-import mage.abilities.mana.ActivatedManaAbilityImpl;
-import mage.abilities.mana.ManaOptions;
-import mage.actions.MageDrawAction;
-import mage.cards.*;
-import mage.cards.decks.Deck;
-import mage.choices.Choice;
-import mage.choices.ChoiceImpl;
-import mage.constants.*;
-import mage.counters.Counter;
-import mage.counters.CounterType;
-import mage.counters.Counters;
-import mage.designations.Designation;
-import mage.designations.DesignationType;
-import mage.filter.FilterCard;
-import mage.filter.FilterMana;
-import mage.filter.FilterPermanent;
-import mage.filter.StaticFilters;
-import mage.filter.common.FilterControlledPermanent;
-import mage.filter.common.FilterCreatureForCombat;
-import mage.filter.common.FilterCreatureForCombatBlock;
-import mage.filter.predicate.Predicates;
-import mage.filter.predicate.permanent.PermanentIdPredicate;
-import mage.game.*;
-import mage.game.combat.CombatGroup;
-import mage.game.command.CommandObject;
-import mage.game.events.*;
-import mage.game.match.MatchPlayer;
-import mage.game.permanent.Permanent;
-import mage.game.permanent.PermanentCard;
-import mage.game.permanent.PermanentToken;
-import mage.game.permanent.token.SquirrelToken;
-import mage.game.stack.Spell;
-import mage.game.stack.StackAbility;
-import mage.game.stack.StackObject;
-import mage.game.turn.Step;
-import mage.players.net.UserData;
-import mage.target.Target;
-import mage.target.TargetAmount;
-import mage.target.TargetCard;
-import mage.target.TargetPermanent;
-import mage.target.common.TargetCardInLibrary;
-import mage.target.common.TargetDiscard;
-import mage.util.CardUtil;
-import mage.util.GameLog;
-import mage.util.RandomUtil;
-import org.apache.log4j.Logger;
-
-import java.io.Serializable;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-
-public abstract class PlayerImpl implements Player, Serializable {
-
- private static final Logger logger = Logger.getLogger(PlayerImpl.class);
-
- /**
- * Used to cancel waiting requests send to the player
- */
- protected boolean abort;
-
- protected final UUID playerId;
- protected String name;
- protected boolean human;
- protected int life;
- protected boolean wins;
- protected boolean draws;
- protected boolean loses;
- protected Library library;
- protected Cards sideboard;
- protected Cards hand;
- protected Graveyard graveyard;
- protected Set commandersIds = new HashSet<>(0);
- protected Abilities abilities;
- protected Counters counters;
- protected int landsPlayed;
- protected int landsPerTurn = 1;
- protected int loyaltyUsePerTurn = 1;
- protected int maxHandSize = 7;
- protected int maxAttackedBy = Integer.MAX_VALUE;
- protected ManaPool manaPool;
- // priority control
- protected boolean passed; // player passed priority
- protected boolean passedTurn; // F4
- protected boolean passedTurnSkipStack; // F6 // TODO: research
- protected boolean passedUntilEndOfTurn; // F5
- protected boolean passedUntilNextMain; // F7
- protected boolean passedUntilStackResolved; // F10
- protected Date dateLastAddedToStack;
- protected boolean passedUntilEndStepBeforeMyTurn; // F11
- protected boolean skippedAtLeastOnce; // used to track if passed started in specific phase
- /**
- * This indicates that player passed all turns until their own turn starts
- * (F9). Note! This differs from passedTurn as it doesn't care about spells
- * and abilities in the stack and will pass them as well.
- */
- protected boolean passedAllTurns; // F9
- protected AbilityType justActivatedType; // used to check if priority can be passed automatically
-
- protected int turns;
- protected int storedBookmark = -1;
- protected int priorityTimeLeft = Integer.MAX_VALUE;
-
- // conceded or connection lost game
- protected boolean left;
- // set if the player quits the complete match
- protected boolean quit;
- // set if the player lost match because of priority timeout
- protected boolean timerTimeout;
- // set if the player lost match because of idle timeout
- protected boolean idleTimeout;
-
- protected RangeOfInfluence range;
- protected Set inRange = new HashSet<>(); // players list in current range of influence (updates each turn)
-
- protected boolean isTestMode = false;
- protected boolean canGainLife = true;
- protected boolean canLoseLife = true;
- protected boolean canPayLifeCost = true;
- protected boolean loseByZeroOrLessLife = true;
- protected boolean canPlayCardsFromGraveyard = true;
- protected boolean drawsOnOpponentsTurn = false;
-
- protected FilterPermanent sacrificeCostFilter;
-
- protected final List alternativeSourceCosts = new ArrayList<>();
-
- protected boolean isGameUnderControl = true;
- protected UUID turnController;
- protected List turnControllers = new ArrayList<>();
- protected Set playersUnderYourControl = new HashSet<>();
-
- protected Set usersAllowedToSeeHandCards = new HashSet<>();
-
- protected List attachments = new ArrayList<>();
-
- protected boolean topCardRevealed = false;
-
- // 800.4i When a player leaves the game, any continuous effects with durations that last until that player's next turn
- // or until a specific point in that turn will last until that turn would have begun.
- // They neither expire immediately nor last indefinitely.
- protected boolean reachedNextTurnAfterLeaving = false;
-
- // indicates that the spell with the set sourceId can be cast with an alternate mana costs (can also be no mana costs)
- // support multiple cards with alternative mana cost
- protected Set castSourceIdWithAlternateMana = new HashSet<>();
- protected Map> castSourceIdManaCosts = new HashMap<>();
- protected Map> castSourceIdCosts = new HashMap<>();
-
- // indicates that the player is in mana payment phase
- protected boolean payManaMode = false;
-
- protected UserData userData;
- protected MatchPlayer matchPlayer;
-
- protected List designations = new ArrayList<>();
-
- // mana colors the player can handle like Phyrexian mana
- protected FilterMana phyrexianColors;
-
- // Used during available mana calculation to give back possible available net mana from triggered mana abilities (No need to copy)
- protected final List> availableTriggeredManaList = new ArrayList<>();
-
- /**
- * During some steps we can't play anything
- */
- protected final Map silentPhaseSteps = ImmutableMap.builder().
- put(PhaseStep.DECLARE_ATTACKERS, Step.StepPart.PRE).build();
-
- public PlayerImpl(String name, RangeOfInfluence range) {
- this(UUID.randomUUID());
- this.name = name;
- this.range = range;
- hand = new CardsImpl();
- graveyard = new Graveyard();
- abilities = new AbilitiesImpl<>();
- counters = new Counters();
- manaPool = new ManaPool(playerId);
- library = new Library(playerId);
- sideboard = new CardsImpl();
- phyrexianColors = null;
- }
-
- protected PlayerImpl(UUID id) {
- this.playerId = id;
- }
-
- public PlayerImpl(final PlayerImpl player) {
- this.abort = player.abort;
- this.playerId = player.playerId;
-
- this.name = player.name;
- this.human = player.human;
- this.life = player.life;
- this.wins = player.wins;
- this.draws = player.draws;
- this.loses = player.loses;
-
- this.library = player.library.copy();
- this.sideboard = player.sideboard.copy();
- this.hand = player.hand.copy();
- this.graveyard = player.graveyard.copy();
- this.commandersIds = player.commandersIds;
- this.abilities = player.abilities.copy();
- this.counters = player.counters.copy();
-
- this.landsPlayed = player.landsPlayed;
- this.landsPerTurn = player.landsPerTurn;
- this.loyaltyUsePerTurn = player.loyaltyUsePerTurn;
- this.maxHandSize = player.maxHandSize;
- this.maxAttackedBy = player.maxAttackedBy;
- this.manaPool = player.manaPool.copy();
- this.turns = player.turns;
-
- this.left = player.left;
- this.quit = player.quit;
- this.timerTimeout = player.timerTimeout;
- this.idleTimeout = player.idleTimeout;
- this.range = player.range;
- this.canGainLife = player.canGainLife;
- this.canLoseLife = player.canLoseLife;
- this.loseByZeroOrLessLife = player.loseByZeroOrLessLife;
- this.canPlayCardsFromGraveyard = player.canPlayCardsFromGraveyard;
- this.drawsOnOpponentsTurn = player.drawsOnOpponentsTurn;
-
- this.attachments.addAll(player.attachments);
-
- this.inRange.addAll(player.inRange);
- this.userData = player.userData;
- this.matchPlayer = player.matchPlayer;
-
- this.canPayLifeCost = player.canPayLifeCost;
- this.sacrificeCostFilter = player.sacrificeCostFilter;
- this.alternativeSourceCosts.addAll(player.alternativeSourceCosts);
- this.storedBookmark = player.storedBookmark;
-
- this.topCardRevealed = player.topCardRevealed;
- this.playersUnderYourControl.addAll(player.playersUnderYourControl);
- this.usersAllowedToSeeHandCards.addAll(player.usersAllowedToSeeHandCards);
-
- this.isTestMode = player.isTestMode;
- this.isGameUnderControl = player.isGameUnderControl;
-
- this.turnController = player.turnController;
- this.turnControllers.addAll(player.turnControllers);
-
- this.passed = player.passed;
- this.passedTurn = player.passedTurn;
- this.passedTurnSkipStack = player.passedTurnSkipStack;
- this.passedUntilEndOfTurn = player.passedUntilEndOfTurn;
- this.passedUntilNextMain = player.passedUntilNextMain;
- this.passedUntilStackResolved = player.passedUntilStackResolved;
- this.dateLastAddedToStack = player.dateLastAddedToStack;
- this.passedUntilEndStepBeforeMyTurn = player.passedUntilEndStepBeforeMyTurn;
- this.skippedAtLeastOnce = player.skippedAtLeastOnce;
- this.passedAllTurns = player.passedAllTurns;
- this.justActivatedType = player.justActivatedType;
-
- this.priorityTimeLeft = player.getPriorityTimeLeft();
- this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving;
-
- this.castSourceIdWithAlternateMana.addAll(player.getCastSourceIdWithAlternateMana());
- for (Entry> entry : player.getCastSourceIdManaCosts().entrySet()) {
- this.castSourceIdManaCosts.put(entry.getKey(), (entry.getValue() == null ? null : entry.getValue().copy()));
- }
- for (Entry> entry : player.getCastSourceIdCosts().entrySet()) {
- this.castSourceIdCosts.put(entry.getKey(), (entry.getValue() == null ? null : entry.getValue().copy()));
- }
- this.payManaMode = player.payManaMode;
- this.phyrexianColors = player.getPhyrexianColors() != null ? player.phyrexianColors.copy() : null;
- for (Designation object : player.designations) {
- this.designations.add(object.copy());
- }
- }
-
- @Override
- public void restore(Player player) {
- this.name = player.getName();
- this.human = player.isHuman();
- this.life = player.getLife();
-
- this.passed = player.isPassed();
-
- // Don't restore more global states. If restored they are probably cause for unintended draws (https://github.com/magefree/mage/issues/1205).
-// this.wins = player.hasWon();
-// this.loses = player.hasLost();
-// this.left = player.hasLeft();
-// this.quit = player.hasQuit();
- // Makes no sense to restore
-// this.priorityTimeLeft = player.getPriorityTimeLeft();
-// this.idleTimeout = player.hasIdleTimeout();
-// this.timerTimeout = player.hasTimerTimeout();
- // can't change so no need to restore
-// this.isTestMode = player.isTestMode();
- // This is meta data and should'nt be restored by rollback
-// this.userData = player.getUserData();
- this.library = player.getLibrary().copy();
- this.sideboard = player.getSideboard().copy();
- this.hand = player.getHand().copy();
- this.graveyard = player.getGraveyard().copy();
-
- //noinspection deprecation - it's ok to use it in inner methods
- this.commandersIds = new HashSet<>(player.getCommandersIds());
-
- this.abilities = player.getAbilities().copy();
- this.counters = player.getCounters().copy();
-
- this.landsPlayed = player.getLandsPlayed();
- this.landsPerTurn = player.getLandsPerTurn();
- this.loyaltyUsePerTurn = player.getLoyaltyUsePerTurn();
- this.maxHandSize = player.getMaxHandSize();
- this.maxAttackedBy = player.getMaxAttackedBy();
- this.manaPool = player.getManaPool().copy();
- // Restore user specific settings in case changed since state save
- this.manaPool.setAutoPayment(this.getUserData().isManaPoolAutomatic());
- this.manaPool.setAutoPaymentRestricted(this.getUserData().isManaPoolAutomaticRestricted());
-
- this.turns = player.getTurns();
-
- this.range = player.getRange();
- this.canGainLife = player.isCanGainLife();
- this.canLoseLife = player.isCanLoseLife();
- this.attachments.clear();
- this.attachments.addAll(player.getAttachments());
-
- this.inRange.clear();
- this.inRange.addAll(player.getInRange());
- this.canPayLifeCost = player.getCanPayLifeCost();
- this.sacrificeCostFilter = player.getSacrificeCostFilter() != null
- ? player.getSacrificeCostFilter().copy() : null;
- this.loseByZeroOrLessLife = player.canLoseByZeroOrLessLife();
- this.canPlayCardsFromGraveyard = player.canPlayCardsFromGraveyard();
- this.drawsOnOpponentsTurn = player.isDrawsOnOpponentsTurn();
- this.alternativeSourceCosts.clear();
- this.alternativeSourceCosts.addAll(player.getAlternativeSourceCosts());
-
- this.topCardRevealed = player.isTopCardRevealed();
- this.playersUnderYourControl.clear();
- this.playersUnderYourControl.addAll(player.getPlayersUnderYourControl());
- this.isGameUnderControl = player.isGameUnderControl();
-
- this.turnController = player.getTurnControlledBy();
- this.turnControllers.clear();
- this.turnControllers.addAll(player.getTurnControllers());
- this.reachedNextTurnAfterLeaving = player.hasReachedNextTurnAfterLeaving();
-
- this.clearCastSourceIdManaCosts();
- this.castSourceIdWithAlternateMana.clear();
- this.castSourceIdWithAlternateMana.addAll(player.getCastSourceIdWithAlternateMana());
- for (Entry> entry : player.getCastSourceIdManaCosts().entrySet()) {
- this.castSourceIdManaCosts.put(entry.getKey(), (entry.getValue() == null ? null : entry.getValue().copy()));
- }
- for (Entry> entry : player.getCastSourceIdCosts().entrySet()) {
- this.castSourceIdCosts.put(entry.getKey(), (entry.getValue() == null ? null : entry.getValue().copy()));
- }
-
- this.phyrexianColors = player.getPhyrexianColors() != null ? player.getPhyrexianColors().copy() : null;
-
- this.designations.clear();
- for (Designation object : player.getDesignations()) {
- this.designations.add(object.copy());
- }
-
- // Don't restore!
- // this.storedBookmark
- // this.usersAllowedToSeeHandCards
- }
-
- @Override
- public void useDeck(Deck deck, Game game) {
- library.clear();
- library.addAll(deck.getCards(), game);
- sideboard.clear();
- for (Card card : deck.getSideboard()) {
- sideboard.add(card);
- }
- }
-
- /**
- * Cast e.g. from Karn Liberated to restart the current game
- *
- * @param game
- */
- @Override
- public void init(Game game) {
- init(game, false);
- }
-
- @Override
- public void init(Game game, boolean testMode) {
- this.abort = false;
- if (!testMode) {
- this.hand.clear();
- this.graveyard.clear();
- }
- this.library.reset();
- this.abilities.clear();
- this.counters.clear();
- this.wins = false;
- this.draws = false;
- this.loses = false;
- this.left = false;
- // reset is necessary because in tournament player will be used for each round
- this.quit = false;
- this.timerTimeout = false;
- this.idleTimeout = false;
-
- this.turns = 0;
- this.isGameUnderControl = true;
- this.turnController = this.getId();
- this.turnControllers.clear();
- this.playersUnderYourControl.clear();
-
- this.passed = false;
- this.passedTurn = false;
- this.passedTurnSkipStack = false;
- this.passedUntilEndOfTurn = false;
- this.passedUntilNextMain = false;
- this.passedUntilStackResolved = false;
- this.dateLastAddedToStack = null;
- this.passedUntilEndStepBeforeMyTurn = false;
- this.skippedAtLeastOnce = false;
- this.passedAllTurns = false;
- this.justActivatedType = null;
-
- this.canGainLife = true;
- this.canLoseLife = true;
- this.topCardRevealed = false;
- this.payManaMode = false;
- this.setLife(game.getStartingLife(), game, null);
- this.setReachedNextTurnAfterLeaving(false);
-
- this.clearCastSourceIdManaCosts();
-
- this.getManaPool().init(); // needed to remove mana that not empties on step change from previous game if left
- this.phyrexianColors = null;
-
- this.designations.clear();
- }
-
- /**
- * called before apply effects
- */
- @Override
- public void reset() {
- this.abilities.clear();
- this.landsPerTurn = 1;
- this.loyaltyUsePerTurn = 1;
- this.maxHandSize = 7;
- this.maxAttackedBy = Integer.MAX_VALUE;
- this.canGainLife = true;
- this.canLoseLife = true;
- this.canPayLifeCost = true;
- this.sacrificeCostFilter = null;
- this.loseByZeroOrLessLife = true;
- this.canPlayCardsFromGraveyard = false;
- this.drawsOnOpponentsTurn = false;
- this.topCardRevealed = false;
- this.alternativeSourceCosts.clear();
- this.clearCastSourceIdManaCosts();
- this.getManaPool().clearEmptyManaPoolRules();
- this.phyrexianColors = null;
- }
-
- @Override
- public Counters getCounters() {
- return counters;
- }
-
- @Override
- public void beginTurn(Game game) {
- this.landsPlayed = 0;
- updateRange(game);
- }
-
- @Override
- public RangeOfInfluence getRange() {
- return range;
- }
-
- @Override
- public void updateRange(Game game) {
- // 20100423 - 801.2c
- // 801.2c The particular players within each player’s range of influence are determined as each turn begins.
- // BUT it also uses before game start to fill game and card data in starting game events
- inRange.clear();
- inRange.add(this.playerId);
- inRange.addAll(getAllNearPlayers(game, true));
- inRange.addAll(getAllNearPlayers(game, false));
- }
-
- private Set getAllNearPlayers(Game game, boolean needPrevious) {
- // find all near players (search from current player position)
- Set foundedList = new HashSet<>();
- PlayerList players = game.getState().getPlayerList(this.playerId);
- int needAmount = this.getRange().getRange(); // distance to search (0 - ALL range)
- int foundedAmount = 0;
- while (needAmount == 0 || foundedAmount < needAmount) {
- Player foundedPlayer = needPrevious ? players.getPrevious(game) : players.getNext(game, false);
-
- // PlayerList is inifine, so stops on repeats
- if (foundedPlayer == null || foundedPlayer.getId().equals(this.playerId) || foundedList.contains(foundedPlayer.getId())) {
- break;
- }
- // skip leaved player (no needs cause next/previous code already checks it)
-
- foundedList.add(foundedPlayer.getId());
- foundedAmount++;
- }
- return foundedList;
- }
-
- @Override
- public Set getInRange() {
- if (inRange.isEmpty()) {
- // runtime check: inRange filled on beginTurn, but unit tests adds cards by cheat engine before game starting,
- // so inRange will be empty and some ETB effects can be broken (example: Spark Double puts direct to battlefield).
- // Cheat engine already have a workaround, so that error must not be visible in normal situation.
- throw new IllegalStateException("Wrong code usage (game is not started, but you call getInRange in some effects).");
- }
-
- return inRange;
- }
-
- @Override
- public Set getPlayersUnderYourControl() {
- return this.playersUnderYourControl;
- }
-
- @Override
- public void controlPlayersTurn(Game game, UUID playerId) {
- Player player = game.getPlayer(playerId);
- player.setTurnControlledBy(this.getId());
- game.informPlayers(getLogName() + " controls the turn of " + player.getLogName());
- if (!playerId.equals(this.getId())) {
- this.playersUnderYourControl.add(playerId);
- if (!player.hasLeft() && !player.hasLost()) {
- player.setGameUnderYourControl(false);
- }
- DelayedTriggeredAbility ability = new AtTheEndOfTurnStepPostDelayedTriggeredAbility(
- new LoseControlOnOtherPlayersControllerEffect(this.getLogName(), player.getLogName()));
- ability.setSourceId(getId());
- ability.setControllerId(getId());
- game.addDelayedTriggeredAbility(ability, null);
- }
- }
-
- @Override
- public void setTurnControlledBy(UUID playerId) {
- this.turnController = playerId;
- this.turnControllers.add(playerId);
- }
-
- @Override
- public List getTurnControllers() {
- return this.turnControllers;
- }
-
- @Override
- public UUID getTurnControlledBy() {
- return this.turnController;
- }
-
- @Override
- public void resetOtherTurnsControlled() {
- playersUnderYourControl.clear();
- }
-
- /**
- * returns true if the player has the control itself - false if the player
- * is controlled by another player
- *
- * @return
- */
- @Override
- public boolean isGameUnderControl() {
- return isGameUnderControl;
- }
-
- @Override
- public void setGameUnderYourControl(boolean value) {
- setGameUnderYourControl(value, true);
- }
-
- @Override
- public void setGameUnderYourControl(boolean value, boolean fullRestore) {
- this.isGameUnderControl = value;
- if (isGameUnderControl) {
- if (fullRestore) {
- this.turnControllers.clear();
- this.turnController = getId();
- } else {
- if (turnControllers.size() > 0) {
- this.turnControllers.remove(turnControllers.size() - 1);
- }
- if (turnControllers.isEmpty()) {
- this.turnController = getId();
- } else {
- this.turnController = turnControllers.get(turnControllers.size() - 1);
- isGameUnderControl = false;
- }
- }
- }
- }
-
- @Override
- public void endOfTurn(Game game) {
- this.passedTurn = false;
- this.passedTurnSkipStack = false;
- }
-
- @Override
- public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) {
- if (this.hasLost() || this.hasLeft()) {
- return false;
- }
- if (source != null) {
- // there is only variant of shroud, so check the instance and any asthougheffects that would ignore it
- if (abilities.containsKey(ShroudAbility.getInstance().getId())
- && game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.SHROUD, null, sourceControllerId, game) == null) {
- return false;
- }
- // check for all variants of hexproof and any asthougheffects that would ignore it
- // TODO there may be "prevented by rule-modification" effects, so add them if known
- for (Ability a : abilities) {
- if (a instanceof HexproofBaseAbility
- && ((HexproofBaseAbility) a).checkObject(source, game)
- && game.getContinuousEffects().asThough(this.getId(), AsThoughEffectType.HEXPROOF, null, sourceControllerId, game) == null) {
- return false;
- }
- }
- return !hasProtectionFrom(source, game);
- }
- return true;
- }
-
- @Override
- public boolean hasProtectionFrom(MageObject source, Game game) {
- for (ProtectionAbility ability : abilities.getProtectionAbilities()) {
- if (!ability.canTarget(source, game)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public int drawCards(int num, Ability source, Game game) {
- if (num > 0) {
- return game.doAction(source, new MageDrawAction(this, num, null));
- }
- return 0;
- }
-
- @Override
- public int drawCards(int num, Ability source, Game game, GameEvent event) {
- return game.doAction(source, new MageDrawAction(this, num, event));
- }
-
- @Override
- public void discardToMax(Game game) {
- if (hand.size() > this.maxHandSize) {
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + " discards down to "
- + this.maxHandSize
- + (this.maxHandSize == 1
- ? " hand card" : " hand cards"));
- }
- discard(hand.size() - this.maxHandSize, false, false, null, game);
- }
- }
-
- /**
- * Don't use this in normal card code, it's for more internal use. Always
- * use the [Player].moveCards methods if possible for card movement of card
- * code.
- *
- * @param card
- * @param game
- * @return
- */
- @Override
- public boolean putInHand(Card card, Game game) {
- if (card.isOwnedBy(playerId)) {
- card.setZone(Zone.HAND, game);
- this.hand.add(card);
- } else {
- return game.getPlayer(card.getOwnerId()).putInHand(card, game);
- }
- return true;
- }
-
- @Override
- public boolean removeFromHand(Card card, Game game) {
- return hand.remove(card.getId());
- }
-
- @Override
- public boolean removeFromLibrary(Card card, Game game) {
- if (card == null) {
- return false;
- }
- library.remove(card.getId(), game);
- // must return true all the time (some cards can be removed directly from library, see getLibrary().removeFromTop)
- // TODO: replace removeFromTop logic to normal with moveToZone
- return true;
- }
-
- @Override
- public Card discardOne(boolean random, boolean payForCost, Ability source, Game game) {
- return discard(1, random, payForCost, source, game).getRandom(game);
- }
-
- @Override
- public Cards discard(int amount, boolean random, boolean payForCost, Ability source, Game game) {
- if (random) {
- return discard(getRandomToDiscard(amount, source, game), payForCost, source, game);
- }
- return discard(amount, amount, payForCost, source, game);
- }
-
- @Override
- public Cards discard(int minAmount, int maxAmount, boolean payForCost, Ability source, Game game) {
- return discard(getToDiscard(minAmount, maxAmount, source, game), payForCost, source, game);
- }
-
- @Override
- public Cards discard(Cards cards, boolean payForCost, Ability source, Game game) {
- Cards discardedCards = new CardsImpl();
- if (cards == null) {
- return discardedCards;
- }
- for (Card card : cards.getCards(game)) {
- if (doDiscard(card, source, game, payForCost, false)) {
- discardedCards.add(card);
- }
- }
- if (!discardedCards.isEmpty()) {
- game.fireEvent(new DiscardedCardsEvent(source, playerId, discardedCards.size(), discardedCards));
- }
- return discardedCards;
- }
-
- @Override
- public boolean discard(Card card, boolean payForCost, Ability source, Game game) {
- return doDiscard(card, source, game, payForCost, true);
- }
-
- private Cards getToDiscard(int minAmount, int maxAmount, Ability source, Game game) {
- Cards toDiscard = new CardsImpl();
- if (minAmount > maxAmount) {
- return getToDiscard(maxAmount, minAmount, source, game);
- }
- if (maxAmount < 1) {
- return toDiscard;
- }
- if (getHand().size() <= minAmount) {
- toDiscard.addAll(getHand());
- return toDiscard;
- }
- TargetDiscard target = new TargetDiscard(minAmount, maxAmount, StaticFilters.FILTER_CARD, getId());
- choose(Outcome.Discard, target, source != null ? source.getSourceId() : null, game);
- toDiscard.addAll(target.getTargets());
- return toDiscard;
- }
-
- private Cards getRandomToDiscard(int amount, Ability source, Game game) {
- Cards toDiscard = new CardsImpl();
- Cards hand = getHand().copy();
- for (int i = 0; i < amount; i++) {
- if (hand.isEmpty()) {
- break;
- }
- Card card = hand.getRandom(game);
- hand.remove(card);
- toDiscard.add(card);
- }
- return toDiscard;
- }
-
- private boolean doDiscard(Card card, Ability source, Game game, boolean payForCost, boolean fireFinalEvent) {
- //20100716 - 701.7
- /* 701.7. Discard #
- 701.7a To discard a card, move it from its owners hand to that players graveyard.
- 701.7b By default, effects that cause a player to discard a card allow the affected
- player to choose which card to discard. Some effects, however, require a random
- discard or allow another player to choose which card is discarded.
- 701.7c If a card is discarded, but an effect causes it to be put into a hidden zone
- instead of into its owners graveyard without being revealed, all values of that
- cards characteristics are considered to be undefined.
- TODO:
- If a card is discarded this way to pay a cost that specifies a characteristic
- about the discarded card, that cost payment is illegal; the game returns to
- the moment before the cost was paid (see rule 717, "Handling Illegal Actions").
- */
- if (card == null) {
- return false;
- }
- GameEvent gameEvent = GameEvent.getEvent(GameEvent.EventType.DISCARD_CARD, card.getId(), source, playerId);
- gameEvent.setFlag(!payForCost); // event from effect (1) or from cost (0)
- if (game.replaceEvent(gameEvent, source)) {
- return false;
- }
- // write info to game log first so game log infos from triggered or replacement effects follow in the game log
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + " discards " + card.getLogName() + CardUtil.getSourceLogName(game, source));
- }
- /* If a card is discarded while Rest in Peace is on the battlefield, abilities that function
- * when a card is discarded (such as madness) still work, even though that card never reaches
- * a graveyard. In addition, spells or abilities that check the characteristics of a discarded
- * card (such as Chandra Ablaze's first ability) can find that card in exile. */
- card.moveToZone(Zone.GRAVEYARD, source, game, false);
- // So discard is also successful if card is moved to another zone by replacement effect!
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, card.getId(), source, playerId));
-
- if (fireFinalEvent) {
- game.fireEvent(new DiscardedCardsEvent(source, playerId, 1, new CardsImpl(card)));
- }
- return true;
- }
-
- @Override
- public List getAttachments() {
- return attachments;
- }
-
- @Override
- public boolean addAttachment(UUID permanentId, Ability source, Game game) {
- if (!this.attachments.contains(permanentId)) {
- Permanent aura = game.getPermanent(permanentId);
- if (aura == null) {
- aura = game.getPermanentEntering(permanentId);
- }
- if (aura != null) {
- if (!game.replaceEvent(new EnchantPlayerEvent(playerId, aura, source))) {
- this.attachments.add(permanentId);
- aura.attachTo(playerId, source, game);
- game.fireEvent(new EnchantedPlayerEvent(playerId, aura, source));
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public boolean removeAttachment(Permanent attachment, Ability source, Game game) {
- if (this.attachments.contains(attachment.getId())) {
- if (!game.replaceEvent(new UnattachEvent(playerId, attachment.getId(), attachment, source))) {
- this.attachments.remove(attachment.getId());
- attachment.attachTo(null, source, game);
- game.fireEvent(new UnattachedEvent(playerId, attachment.getId(), attachment, source));
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean removeFromBattlefield(Permanent permanent, Ability source, Game game) {
- permanent.removeFromCombat(game, false);
- game.getBattlefield().removePermanent(permanent.getId());
- if (permanent.getAttachedTo() != null) {
- Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
- if (attachedTo != null) {
- attachedTo.removeAttachment(permanent.getId(), source, game);
- } else {
- Player attachedToPlayer = game.getPlayer(permanent.getAttachedTo());
- if (attachedToPlayer != null) {
- attachedToPlayer.removeAttachment(permanent, source, game);
- } else {
- Card attachedToCard = game.getCard(permanent.getAttachedTo());
- if (attachedToCard != null) {
- attachedToCard.removeAttachment(permanent.getId(), source, game);
- }
- }
- }
-
- }
- if (permanent.getPairedCard() != null) {
- Permanent pairedCard = permanent.getPairedCard().getPermanent(game);
- if (pairedCard != null) {
- pairedCard.clearPairedCard();
- }
- }
- if (permanent.getBandedCards() != null && !permanent.getBandedCards().isEmpty()) {
- for (UUID bandedId : permanent.getBandedCards()) {
- Permanent banded = game.getPermanent(bandedId);
- if (banded != null) {
- banded.removeBandedCard(permanent.getId());
- }
- }
- }
- return true;
- }
-
- @Override
- public boolean putInGraveyard(Card card, Game game) {
- if (card.isOwnedBy(playerId)) {
- this.graveyard.add(card);
- } else {
- return game.getPlayer(card.getOwnerId()).putInGraveyard(card, game);
- }
- return true;
- }
-
- @Override
- public boolean removeFromGraveyard(Card card, Game game) {
- return this.graveyard.remove(card);
- }
-
- @Override
- public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
- return putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, anyOrder);
- }
-
- @Override
- public boolean putCardsOnBottomOfLibrary(Cards cardsToLibrary, Game game, Ability source, boolean anyOrder) {
- if (!cardsToLibrary.isEmpty()) {
- Cards cards = new CardsImpl(cardsToLibrary); // prevent possible ConcurrentModificationException
- if (!anyOrder) {
- // random order
- List ids = new ArrayList<>(cards);
- Collections.shuffle(ids);
- for (UUID id : ids) {
- moveObjectToLibrary(id, source, game, false, false);
- }
- } else {
- // user defined order
- TargetCard target = new TargetCard(Zone.ALL,
- new FilterCard("card ORDER to put on the BOTTOM of your library (last one chosen will be bottommost)"));
- target.setRequired(true);
- while (cards.size() > 1 && this.canRespond()
- && this.choose(Outcome.Neutral, cards, target, game)) {
- UUID targetObjectId = target.getFirstTarget();
- if (targetObjectId == null) {
- break;
- }
- cards.remove(targetObjectId);
- moveObjectToLibrary(targetObjectId, source, game, false, false);
- target.clearChosen();
- }
- for (UUID c : cards) {
- moveObjectToLibrary(c, source, game, false, false);
- }
- }
- }
- return true;
- }
-
- @Override
- public boolean shuffleCardsToLibrary(Cards cards, Game game, Ability source) {
- if (cards.isEmpty()) {
- return true;
- }
- game.informPlayers(getLogName() + " shuffles " + CardUtil.numberToText(cards.size(), "a")
- + " card" + (cards.size() == 1 ? "" : "s")
- + " into their library" + CardUtil.getSourceLogName(game, source));
- boolean status = moveCards(cards, Zone.LIBRARY, source, game);
- shuffleLibrary(source, game);
- return status;
- }
-
- @Override
- public boolean shuffleCardsToLibrary(Card card, Game game, Ability source) {
- if (card == null) {
- return true;
- }
- return shuffleCardsToLibrary(new CardsImpl(card), game, source);
- }
-
- @Override
- public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop, boolean withName) {
- if (card.isOwnedBy(getId())) {
- if (library.size() + 1 < xFromTheTop) {
- putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true);
- } else {
- if (card.moveToZone(Zone.LIBRARY, source, game, true)
- && !(card instanceof PermanentToken) && !card.isCopy()) {
- Card cardInLib = getLibrary().getFromTop(game);
- if (cardInLib != null && cardInLib.getId().equals(card.getId())) { // check needed because e.g. commander can go to command zone
- cardInLib = getLibrary().removeFromTop(game);
- getLibrary().putCardToTopXPos(cardInLib, xFromTheTop, game);
- game.informPlayers(withName ? cardInLib.getLogName() : "A card"
- + " is put into "
- + getLogName()
- + "'s library "
- + CardUtil.numberToOrdinalText(xFromTheTop)
- + " from the top" + CardUtil.getSourceLogName(game, source, cardInLib.getId()));
- }
- } else {
- return false;
- }
- }
- } else {
- return game.getPlayer(card.getOwnerId()).putCardOnTopXOfLibrary(card, game, source, xFromTheTop, withName);
- }
- return true;
- }
-
- /**
- * Can be cards or permanents that go to library
- *
- * @param cardsToLibrary
- * @param game
- * @param source
- * @param anyOrder
- * @return
- */
- @Override
- public boolean putCardsOnTopOfLibrary(Cards cardsToLibrary, Game game, Ability source, boolean anyOrder) {
- if (cardsToLibrary != null && !cardsToLibrary.isEmpty()) {
- Cards cards = new CardsImpl(cardsToLibrary); // prevent possible ConcurrentModificationException
- if (!anyOrder) {
- // random order
- List ids = new ArrayList<>(cards);
- Collections.shuffle(ids);
- for (UUID id : ids) {
- moveObjectToLibrary(id, source, game, true, false);
- }
- } else {
- // user defined order
- TargetCard target = new TargetCard(Zone.ALL,
- new FilterCard("card ORDER to put on the TOP of your library (last one chosen will be topmost)"));
- target.setRequired(true);
- while (cards.size() > 1
- && this.canRespond()
- && this.choose(Outcome.Neutral, cards, target, game)) {
- UUID targetObjectId = target.getFirstTarget();
- if (targetObjectId == null) {
- break;
- }
- cards.remove(targetObjectId);
- moveObjectToLibrary(targetObjectId, source, game, true, false);
- target.clearChosen();
- }
- for (UUID c : cards) {
- moveObjectToLibrary(c, source, game, true, false);
- }
- }
- }
- return true;
- }
-
- @Override
- public boolean putCardsOnTopOfLibrary(Card cardToLibrary, Game game, Ability source, boolean anyOrder) {
- if (cardToLibrary != null) {
- return putCardsOnTopOfLibrary(new CardsImpl(cardToLibrary), game, source, anyOrder);
- }
- return true;
- }
-
- private boolean moveObjectToLibrary(UUID objectId, Ability source, Game game, boolean toTop, boolean withName) {
- MageObject mageObject = game.getObject(objectId);
- if (mageObject instanceof Spell && mageObject.isCopy()) {
- // Spell copies are not moved as cards, so here the no copy spell has to be selected to move
- // (but because copy and original have the same objectId the wrong sepell can be selected from stack).
- // So let's check if the original spell is on the stack and has to be selected. // TODO: Better handling so each spell could be selected by a unique id
- Spell spellNoCopy = game.getStack().getSpell(source.getSourceId(), false);
- if (spellNoCopy != null) {
- mageObject = spellNoCopy;
- }
- }
- if (mageObject != null) {
- Zone fromZone = game.getState().getZone(objectId);
- if ((mageObject instanceof Permanent)) {
- return this.moveCardToLibraryWithInfo((Permanent) mageObject, source, game, fromZone, toTop, withName);
- } else if (mageObject instanceof Card) {
- return this.moveCardToLibraryWithInfo((Card) mageObject, source, game, fromZone, toTop, withName);
- }
- }
- return false;
- }
-
- @Override
- public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs) {
- // cost must be copied for data consistence between game simulations
- castSourceIdWithAlternateMana.add(sourceId);
- castSourceIdManaCosts.put(sourceId, manaCosts != null ? manaCosts.copy() : null);
- castSourceIdCosts.put(sourceId, costs != null ? costs.copy() : null);
- }
-
- @Override
- public Set getCastSourceIdWithAlternateMana() {
- return castSourceIdWithAlternateMana;
- }
-
- @Override
- public Map> getCastSourceIdCosts() {
- return castSourceIdCosts;
- }
-
- @Override
- public Map> getCastSourceIdManaCosts() {
- return castSourceIdManaCosts;
- }
-
- @Override
- public void clearCastSourceIdManaCosts() {
- this.castSourceIdCosts.clear();
- this.castSourceIdManaCosts.clear();
- this.castSourceIdWithAlternateMana.clear();
- }
-
- @Override
- public void setPayManaMode(boolean payManaMode) {
- this.payManaMode = payManaMode;
- }
-
- @Override
- public boolean isInPayManaMode() {
- return payManaMode;
- }
-
- @Override
- public boolean playCard(Card card, Game game, boolean noMana, ApprovingObject approvingObject) {
- if (card == null) {
- return false;
- }
-
- // play without timing and from any zone
- boolean result;
- if (card.isLand(game)) {
- result = playLand(card, game, true);
- } else {
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- result = cast(this.chooseAbilityForCast(card, game, noMana), game, noMana, approvingObject);
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- }
-
- if (!result) {
- game.informPlayer(this, "You can't play " + card.getIdName() + '.');
- }
- return result;
- }
-
- /**
- * @param originalAbility
- * @param game
- * @param noMana cast it without paying mana costs
- * @param approvingObject which object approved the cast
- * @return
- */
- @Override
- public boolean cast(SpellAbility originalAbility, Game game, boolean noMana, ApprovingObject approvingObject) {
- if (game == null || originalAbility == null) {
- return false;
- }
-
- // Use ability copy to avoid problems with targets and costs on recast (issue https://github.com/magefree/mage/issues/5189).
- SpellAbility ability = originalAbility.copy();
- ability.setControllerId(getId());
- ability.setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(ability.getSourceId()));
-
- //20091005 - 601.2a
- if (ability.getSourceId() == null) {
- logger.error("Ability without sourceId turn " + game.getTurnNum() + ". Ability: " + ability.getRule());
- return false;
- }
- Card card = game.getCard(ability.getSourceId());
- if (card != null) {
- Zone fromZone = game.getState().getZone(card.getMainCard().getId());
- GameEvent castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL,
- ability.getId(), ability, playerId, approvingObject);
- castEvent.setZone(fromZone);
- if (!game.replaceEvent(castEvent, ability)) {
- int bookmark = game.bookmarkState();
- setStoredBookmark(bookmark); // move global bookmark to current state (if you activated mana before then you can't rollback it)
- card.cast(game, fromZone, ability, playerId);
- Spell spell = game.getStack().getSpell(ability.getId());
- if (spell == null) {
- logger.error("Got no spell from stack. ability: " + ability.getRule());
- return false;
- }
- if (card.isCopy()) {
- spell.setCopy(true, null);
- }
- // Update the zcc to the stack
- ability.setSourceObjectZoneChangeCounter(game.getState().getZoneChangeCounter(ability.getSourceId()));
-
- // ALTERNATIVE COST from dynamic effects
- // some effects set sourceId to cast without paying mana costs or other costs
- if (getCastSourceIdWithAlternateMana().contains(ability.getSourceId())) {
- Ability spellAbility = spell.getSpellAbility();
- ManaCosts alternateCosts = getCastSourceIdManaCosts().get(ability.getSourceId());
- Costs costs = getCastSourceIdCosts().get(ability.getSourceId());
- if (alternateCosts == null) {
- noMana = true;
- } else {
- spellAbility.getManaCosts().clear();
- spellAbility.getManaCostsToPay().clear();
- spellAbility.getManaCosts().add(alternateCosts.copy());
- spellAbility.getManaCostsToPay().add(alternateCosts.copy());
- }
- spellAbility.getCosts().clear();
- if (costs != null) {
- spellAbility.getCosts().addAll(costs);
- }
- }
- clearCastSourceIdManaCosts(); // TODO: test multiple alternative cost for different cards as same time
-
- castEvent = GameEvent.getEvent(GameEvent.EventType.CAST_SPELL,
- spell.getSpellAbility().getId(), spell.getSpellAbility(), playerId, approvingObject);
- castEvent.setZone(fromZone);
- game.fireEvent(castEvent);
- if (spell.activate(game, noMana)) {
- GameEvent castedEvent = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST,
- spell.getSpellAbility().getId(), spell.getSpellAbility(), playerId, approvingObject);
- castedEvent.setZone(fromZone);
- game.fireEvent(castedEvent);
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + spell.getActivatedMessage(game));
- }
- game.removeBookmark(bookmark);
- resetStoredBookmark(game);
- return true;
- }
- restoreState(bookmark, ability.getRule(), game);
- }
- }
- return false;
- }
-
- @Override
- public boolean playLand(Card card, Game game, boolean ignoreTiming) {
- // Check for alternate casting possibilities: e.g. land with Morph
- if (card == null) {
- return false;
- }
- ActivatedAbility playLandAbility = null;
- boolean foundAlternative = false;
- for (Ability ability : card.getAbilities(game)) {
- // if cast for noMana no Alternative costs are allowed
- if ((ability instanceof AlternativeSourceCosts)
- || (ability instanceof OptionalAdditionalSourceCosts)) {
- foundAlternative = true;
- }
- if (ability instanceof PlayLandAbility) {
- playLandAbility = (ActivatedAbility) ability;
- }
- }
-
- // try alternative cast (face down)
- if (foundAlternative) {
- SpellAbility spellAbility = new SpellAbility(null, "",
- game.getState().getZone(card.getId()), SpellAbilityType.FACE_DOWN_CREATURE);
- spellAbility.setControllerId(this.getId());
- spellAbility.setSourceId(card.getId());
- if (cast(spellAbility, game, false, null)) {
- return true;
- }
- }
-
- if (playLandAbility == null) {
- return false;
- }
-
- //20091005 - 114.2a
- ActivationStatus activationStatus = playLandAbility.canActivate(this.playerId, game);
- if (ignoreTiming) {
- if (!canPlayLand()) {
- return false; // ignore timing does not mean that more lands than normal can be played
- }
- } else {
- if (!activationStatus.canActivate()) {
- return false;
- }
- }
-
- //20091005 - 305.1
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,
- card.getId(), playLandAbility, playerId, activationStatus.getApprovingObject()))) {
- // int bookmark = game.bookmarkState();
- // land events must return original zone (uses for commander watcher)
- Zone cardZoneBefore = game.getState().getZone(card.getId());
- GameEvent landEventBefore = GameEvent.getEvent(GameEvent.EventType.PLAY_LAND,
- card.getId(), playLandAbility, playerId, activationStatus.getApprovingObject());
- landEventBefore.setZone(cardZoneBefore);
- game.fireEvent(landEventBefore);
-
- if (moveCards(card, Zone.BATTLEFIELD, playLandAbility, game, false, false, false, null)) {
- landsPlayed++;
- GameEvent landEventAfter = GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED,
- card.getId(), playLandAbility, playerId, activationStatus.getApprovingObject());
- landEventAfter.setZone(cardZoneBefore);
- game.fireEvent(landEventAfter);
-
- String playText = getLogName() + " plays " + card.getLogName();
- if (card instanceof ModalDoubleFacesCardHalf) {
- ModalDoubleFacesCard mdfCard = (ModalDoubleFacesCard) card.getMainCard();
- playText = getLogName() + " plays " + GameLog.replaceNameByColoredName(card, card.getName(), mdfCard)
- + " as MDF side of " + GameLog.getColoredObjectIdName(mdfCard);
- }
- game.fireInformEvent(playText);
- // game.removeBookmark(bookmark);
- resetStoredBookmark(game); // prevent undo after playing a land
- return true;
- }
- // putOntoBattlefield returned false if putOntoBattlefield was replaced by replacement effect (e.g. Kjeldoran Outpost).
- // But that would undo the effect completely,
- // what makes no real sense. So it makes no sense to generally do a restoreState here.
- // restoreState(bookmark, card.getName(), game);
- }
- // if the to play the land is replaced (e.g. Kjeldoran Outpost and don't sacrificing a Plains) it's a valid state so returning true here
- return true;
- }
-
- protected boolean playManaAbility(ActivatedManaAbilityImpl ability, Game game) {
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATE_ABILITY,
- ability.getId(), ability, playerId))) {
- int bookmark = game.bookmarkState();
- if (ability.activate(game, false)) {
- if (ability.resolve(game)) {
- if (ability.isUndoPossible()) {
- if (storedBookmark == -1 || storedBookmark > bookmark) { // e.g. useful for undo Nykthos, Shrine to Nyx
- setStoredBookmark(bookmark);
- }
- } else {
- resetStoredBookmark(game);
- }
- return true;
- }
- }
- restoreState(bookmark, ability.getRule(), game);
- }
- return false;
- }
-
- protected boolean playAbility(ActivatedAbility ability, Game game) {
- //20091005 - 602.2a
- if (ability.isUsesStack()) {
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATE_ABILITY,
- ability.getId(), ability, playerId))) {
- int bookmark = game.bookmarkState();
- setStoredBookmark(bookmark); // move global bookmark to current state (if you activated mana before then you can't rollback it)
- ability.newId();
- ability.setControllerId(playerId);
- game.getStack().push(new StackAbility(ability, playerId));
- if (ability.activate(game, false)) {
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.ACTIVATED_ABILITY,
- ability.getId(), ability, playerId));
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + ability.getGameLogMessage(game));
- }
- game.removeBookmark(bookmark);
- resetStoredBookmark(game);
- return true;
- }
- restoreState(bookmark, ability.getRule(), game);
- }
- } else {
- int bookmark = game.bookmarkState();
- if (ability.activate(game, false)) {
- ability.resolve(game);
- game.removeBookmark(bookmark);
- resetStoredBookmark(game);
- return true;
- }
- restoreState(bookmark, ability.getRule(), game);
- }
- return false;
- }
-
- protected boolean specialAction(SpecialAction action, Game game) {
- //20091005 - 114
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.TAKE_SPECIAL_ACTION,
- action.getId(), action, getId()))) {
- int bookmark = game.bookmarkState();
- if (action.activate(game, false)) {
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.TAKEN_SPECIAL_ACTION,
- action.getId(), action, getId()));
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + action.getGameLogMessage(game));
- }
- if (action.resolve(game)) {
- game.removeBookmark(bookmark);
- resetStoredBookmark(game);
- return true;
- }
- }
- restoreState(bookmark, action.getRule(), game);
- }
- return false;
- }
-
- protected boolean specialManaPayment(SpecialAction action, Game game) {
- //20091005 - 114
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.TAKE_SPECIAL_MANA_PAYMENT,
- action.getId(), action, getId()))) {
- int bookmark = game.bookmarkState();
- if (action.activate(game, false)) {
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.TAKEN_SPECIAL_MANA_PAYMENT,
- action.getId(), action, getId()));
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + action.getGameLogMessage(game));
- }
- if (action.resolve(game)) {
- game.removeBookmark(bookmark);
- resetStoredBookmark(game);
- return true;
- }
- }
- restoreState(bookmark, action.getRule(), game);
- }
- return false;
- }
-
- @Override
- public boolean activateAbility(ActivatedAbility ability, Game game) {
- if (ability == null) {
- return false;
- }
- boolean result;
- if (ability instanceof PassAbility) {
- pass(game);
- return true;
- }
- Card card = game.getCard(ability.getSourceId());
- if (ability instanceof PlayLandAsCommanderAbility) {
-
- // LAND as commander: play land with cost, but without stack
- ActivationStatus activationStatus = ability.canActivate(this.playerId, game);
- if (!activationStatus.canActivate() || !this.canPlayLand()) {
- return false;
- }
- if (card == null) {
- return false;
- }
-
- // as copy, tries to applie cost effects and pays
- Ability activatingAbility = ability.copy();
- if (activatingAbility.activate(game, false)) {
- result = playLand(card, game, false);
- } else {
- result = false;
- }
-
- } else if (ability instanceof PlayLandAbility) {
-
- // LAND as normal card: without cost and stack
- result = playLand(card, game, false);
-
- } else {
-
- // ABILITY
- ActivationStatus activationStatus = ability.canActivate(this.playerId, game);
- if (!activationStatus.canActivate()) {
- return false;
- }
-
- switch (ability.getAbilityType()) {
- case SPECIAL_ACTION:
- result = specialAction((SpecialAction) ability.copy(), game);
- break;
- case SPECIAL_MANA_PAYMENT:
- result = specialManaPayment((SpecialAction) ability.copy(), game);
- break;
- case MANA:
- result = playManaAbility((ActivatedManaAbilityImpl) ability.copy(), game);
- break;
- case SPELL:
- result = cast((SpellAbility) ability, game, false, activationStatus.getApprovingObject());
- break;
- default:
- result = playAbility(ability.copy(), game);
- break;
- }
- }
-
- //if player has taken an action then reset all player passed flags
- justActivatedType = null;
- if (result) {
- if (isHuman()
- && (ability.getAbilityType() == AbilityType.SPELL
- || ability.getAbilityType() == AbilityType.ACTIVATED)) {
- if (ability.isUsesStack()) { // if the ability does not use the stack (e.g. Suspend) auto pass would go to next phase unintended
- setJustActivatedType(ability.getAbilityType());
- }
- }
- game.getPlayers().resetPassed();
- }
- return result;
- }
-
- @Override
- public boolean triggerAbility(TriggeredAbility triggeredAbility, Game game) {
- if (triggeredAbility == null) {
- logger.warn("Null source in triggerAbility method");
- throw new IllegalArgumentException("source TriggeredAbility must not be null");
- }
- //20091005 - 603.3c, 603.3d
- int bookmark = game.bookmarkState();
- TriggeredAbility ability = triggeredAbility.copy();
- MageObject sourceObject = ability.getSourceObject(game);
- if (sourceObject != null) {
- sourceObject.adjustTargets(ability, game);
- }
- UUID triggerId = null;
- if (ability.canChooseTarget(game, playerId)) {
- if (ability.isUsesStack()) {
- game.getStack().push(new StackAbility(ability, playerId));
- }
- if (ability.activate(game, false)) {
- if ((ability.isUsesStack()
- || ability.getRuleVisible())
- && !game.isSimulation()) {
- game.informPlayers(getLogName() + " - " + ability.getGameLogMessage(game));
- }
- if (!ability.isUsesStack()) {
- ability.resolve(game);
- } else {
- game.fireEvent(new GameEvent(
- GameEvent.EventType.TRIGGERED_ABILITY,
- ability.getId(), ability, ability.getControllerId()
- ));
- triggerId = ability.getId();
- }
- game.removeBookmark(bookmark);
- return true;
- }
- }
- restoreState(bookmark, triggeredAbility.getRule(), game); // why restore is needed here? (to remove the triggered ability from the stack because of no possible targets)
- GameEvent event = new GameEvent(
- GameEvent.EventType.ABILITY_TRIGGERED,
- triggerId, ability, ability.getControllerId()
- );
- game.getState().setValue(event.getId().toString(), ability.getTriggerEvent());
- game.fireEvent(event);
- return false;
- }
-
- /**
- * Return spells for possible cast Uses in GUI to show only playable spells
- * for choosing from the card (example: effect allow to cast card and player
- * must choose the spell ability)
- *
- * @param game
- * @param playerId
- * @param object
- * @param zone
- * @param noMana
- * @return
- */
- public static LinkedHashMap getCastableSpellAbilities(Game game, UUID playerId, MageObject object, Zone zone, boolean noMana) {
- // it uses simple check from spellCanBeActivatedRegularlyNow
- // reason: no approved info here (e.g. forced to choose spell ability from cast card)
- LinkedHashMap useable = new LinkedHashMap<>();
- Abilities allAbilities;
- if (object instanceof Card) {
- allAbilities = ((Card) object).getAbilities(game);
- } else {
- allAbilities = object.getAbilities();
- }
-
- for (Ability ability : allAbilities) {
- if (ability instanceof SpellAbility) {
- SpellAbility spellAbility = (SpellAbility) ability;
-
- switch (spellAbility.getSpellAbilityType()) {
- case BASE_ALTERNATE:
- // rules:
- // If you cast a spell “without paying its mana cost,” you can’t choose to cast it for
- // any alternative costs. You can, however, pay additional costs, such as kicker costs.
- // If the card has any mandatory additional costs, those must be paid to cast the spell.
- // (2021-02-05)
- if (!noMana) {
- if (spellAbility.spellCanBeActivatedRegularlyNow(playerId, game)) {
- useable.put(spellAbility.getId(), spellAbility); // example: Chandra, Torch of Defiance +1 loyal ability
- }
- return useable;
- }
- break;
- case SPLIT_FUSED:
- // rules:
- // If you cast a split card with fuse from your hand without paying its mana cost,
- // you can choose to use its fuse ability and cast both halves without paying their mana costs.
- if (zone == Zone.HAND) {
- if (spellAbility.canChooseTarget(game, playerId)) {
- useable.put(spellAbility.getId(), spellAbility);
- }
- }
- case SPLIT:
- if (((SplitCard) object).getLeftHalfCard().getSpellAbility().canChooseTarget(game, playerId)) {
- useable.put(((SplitCard) object).getLeftHalfCard().getSpellAbility().getId(),
- ((SplitCard) object).getLeftHalfCard().getSpellAbility());
- }
- if (((SplitCard) object).getRightHalfCard().getSpellAbility().canChooseTarget(game, playerId)) {
- useable.put(((SplitCard) object).getRightHalfCard().getSpellAbility().getId(),
- ((SplitCard) object).getRightHalfCard().getSpellAbility());
- }
- return useable;
- case SPLIT_AFTERMATH:
- if (zone == Zone.GRAVEYARD) {
- if (((SplitCard) object).getRightHalfCard().getSpellAbility().canChooseTarget(game, playerId)) {
- useable.put(((SplitCard) object).getRightHalfCard().getSpellAbility().getId(),
- ((SplitCard) object).getRightHalfCard().getSpellAbility());
- }
- } else {
- if (((SplitCard) object).getLeftHalfCard().getSpellAbility().canChooseTarget(game, playerId)) {
- useable.put(((SplitCard) object).getLeftHalfCard().getSpellAbility().getId(),
- ((SplitCard) object).getLeftHalfCard().getSpellAbility());
- }
- }
- return useable;
- default:
- if (spellAbility.spellCanBeActivatedRegularlyNow(playerId, game)) {
- useable.put(spellAbility.getId(), spellAbility);
- }
- }
- }
- }
- return useable;
- }
-
- @Override
- public LinkedHashMap getPlayableActivatedAbilities(MageObject object, Zone zone, Game game) {
- LinkedHashMap useable = new LinkedHashMap<>();
- // stack abilities - can't activate anything
- // spell ability - can activate additional abilities (example: "Lightning Storm")
- if (object instanceof StackAbility || object == null) {
- return useable;
- }
- boolean previousState = game.inCheckPlayableState();
- game.setCheckPlayableState(true);
- try {
- // collect and filter playable activated abilities
- // GUI: user clicks on card, but it must activate ability from ANY card's parts (main, left, right)
- Set needIds = CardUtil.getObjectParts(object);
-
- // workaround to find all abilities first and filter it for one object
- List allPlayable = getPlayable(game, true, zone, false);
- for (ActivatedAbility ability : allPlayable) {
- if (needIds.contains(ability.getSourceId())) {
- useable.putIfAbsent(ability.getId(), ability);
- }
- }
- } finally {
- game.setCheckPlayableState(previousState);
- }
- return useable;
- }
-
- protected LinkedHashMap getUseableManaAbilities(MageObject object, Zone zone, Game game) {
- LinkedHashMap useable = new LinkedHashMap<>();
- boolean canUse = !(object instanceof Permanent) || ((Permanent) object).canUseActivatedAbilities(game);
- for (ActivatedManaAbilityImpl ability : object.getAbilities().getActivatedManaAbilities(zone)) {
- if (canUse || ability.getAbilityType() == AbilityType.SPECIAL_ACTION) {
- if (ability.canActivate(playerId, game).canActivate()) {
- useable.put(ability.getId(), ability);
- }
- }
- }
- return useable;
- }
-
- @Override
- public int getLandsPlayed() {
- return landsPlayed;
- }
-
- @Override
- public boolean canPlayLand() {
- //20091005 - 114.2a
- return landsPlayed < landsPerTurn;
- }
-
- protected boolean isActivePlayer(Game game) {
- return game.isActivePlayer(this.playerId);
- }
-
- @Override
- public void shuffleLibrary(Ability source, Game game) {
- if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SHUFFLE_LIBRARY, playerId, source, playerId))) {
- this.library.shuffle();
- if (!game.isSimulation()) {
- game.informPlayers(getLogName() + "'s library is shuffled" + CardUtil.getSourceLogName(game, source));
- }
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SHUFFLED, playerId, source, playerId));
- }
- }
-
- @Override
- public void revealCards(Ability source, Cards cards, Game game) {
- revealCards(source, null, cards, game, true);
- }
-
- @Override
- public void revealCards(String titleSuffix, Cards cards, Game game) {
- revealCards(titleSuffix, cards, game, true);
- }
-
- @Override
- public void revealCards(String titleSuffix, Cards cards, Game game, boolean postToLog) {
- revealCards(null, titleSuffix, cards, game, postToLog);
- }
-
- @Override
- public void revealCards(Ability source, String titleSuffix, Cards cards, Game game) {
- revealCards(source, titleSuffix, cards, game, true);
- }
-
- @Override
- public void revealCards(Ability source, String titleSuffix, Cards cards, Game game, boolean postToLog) {
- if (cards == null || cards.isEmpty()) {
- return;
- }
- if (postToLog) {
- game.getState().getRevealed().add(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards);
- } else {
- game.getState().getRevealed().update(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards);
- }
- if (postToLog && !game.isSimulation()) {
- StringBuilder sb = new StringBuilder(getLogName()).append(" reveals ");
- int current = 0, last = cards.size();
- for (Card card : cards.getCards(game)) {
- current++;
- sb.append(GameLog.getColoredObjectName(card));
- if (current < last) {
- sb.append(", ");
- }
- }
- sb.append(CardUtil.getSourceLogName(game, source));
- game.informPlayers(sb.toString());
- }
- }
-
- @Override
- public void lookAtCards(String titleSuffix, Card card, Game game) {
- game.getState().getLookedAt(this.playerId).add(titleSuffix, card);
- game.fireUpdatePlayersEvent();
- }
-
- @Override
- public void lookAtCards(String titleSuffix, Cards cards, Game game) {
- this.lookAtCards(null, titleSuffix, cards, game);
- }
-
- @Override
- public void lookAtCards(Ability source, String titleSuffix, Cards cards, Game game) {
- game.getState().getLookedAt(this.playerId).add(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards);
- game.fireUpdatePlayersEvent();
- }
-
- @Override
- public void phasing(Game game) {
- //20091005 - 502.1
- List phasedOut = game.getBattlefield().getPhasedOut(game, playerId);
- for (Permanent permanent : game.getBattlefield().getPhasedIn(game, playerId)) {
- // 502.15i When a permanent phases out, any local enchantments or Equipment
- // attached to that permanent phase out at the same time. This alternate way of
- // phasing out is known as phasing out "indirectly." An enchantment or Equipment
- // that phased out indirectly won't phase in by itself, but instead phases in
- // along with the card it's attached to.
- Permanent attachedTo = game.getPermanent(permanent.getAttachedTo());
- if (!(attachedTo != null && attachedTo.isControlledBy(this.getId()))) {
- permanent.phaseOut(game, false);
- }
- }
- for (Permanent permanent : phasedOut) {
- if (!permanent.isPhasedOutIndirectly()) {
- permanent.phaseIn(game);
- }
- }
- }
-
- @Override
- public void untap(Game game) {
- // create list of all "notMoreThan" effects to track which one are consumed
- Map>, Integer> notMoreThanEffectsUsage = new HashMap<>();
- for (Entry> restrictionEffect
- : game.getContinuousEffects().getApplicableRestrictionUntapNotMoreThanEffects(this, game).entrySet()) {
- notMoreThanEffectsUsage.put(restrictionEffect, restrictionEffect.getKey().getNumber());
- }
-
- if (!notMoreThanEffectsUsage.isEmpty()) {
- // create list of all permanents that can be untapped generally
- List canBeUntapped = new ArrayList<>();
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
- boolean untap = true;
- for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
- untap &= effect.canBeUntapped(permanent, null, game, true);
- }
- if (untap) {
- canBeUntapped.add(permanent);
- }
- }
- // selected permanents to untap
- List selectedToUntap = new ArrayList<>();
-
- // player can cancel the selection of an effect to use a preferred order of restriction effects
- boolean playerCanceledSelection;
- do {
- playerCanceledSelection = false;
- // select permanents to untap to consume the "notMoreThan" effects
- for (Map.Entry>, Integer> handledEntry : notMoreThanEffectsUsage.entrySet()) {
- // select a permanent to untap for this entry
- int numberToUntap = handledEntry.getValue();
- if (numberToUntap > 0) {
-
- List leftForUntap = getPermanentsThatCanBeUntapped(game,
- canBeUntapped,
- handledEntry.getKey().getKey(),
- notMoreThanEffectsUsage);
-
- FilterControlledPermanent filter = handledEntry.getKey().getKey().getFilter().copy();
- String message = filter.getMessage();
- // omit already from other untap effects selected permanents
- for (Permanent permanent : selectedToUntap) {
- filter.add(Predicates.not(new PermanentIdPredicate(permanent.getId())));
- }
- // while targets left and there is still allowed to untap
- while (canRespond() && !leftForUntap.isEmpty() && numberToUntap > 0) {
- // player has to select the permanent they want to untap for this restriction
- Ability ability = handledEntry.getKey().getValue().iterator().next();
- if (ability != null) {
- StringBuilder sb = new StringBuilder(message).append(" to untap").append(" (").append(Math.min(leftForUntap.size(),
- numberToUntap)).append(" in total");
- MageObject effectSource = game.getObject(ability.getSourceId());
- if (effectSource != null) {
- sb.append(" from ").append(effectSource.getLogName());
- }
- sb.append(')');
- filter.setMessage(sb.toString());
- Target target = new TargetPermanent(1, 1, filter, true);
- if (!this.chooseTarget(Outcome.Untap, target, ability, game)) {
- // player canceled, go on with the next effect (if no other effect available, this effect will be active again)
- playerCanceledSelection = true;
- break;
- }
- Permanent selectedPermanent = game.getPermanent(target.getFirstTarget());
- if (leftForUntap.contains(selectedPermanent)) {
- selectedToUntap.add(selectedPermanent);
- numberToUntap--;
- // don't allow to select same permanent twice
- filter.add(Predicates.not(new PermanentIdPredicate(selectedPermanent.getId())));
- // reduce available untap numbers from other "UntapNotMoreThan" effects if selected permanent applies to their filter too
- for (Entry>, Integer> notMoreThanEffect : notMoreThanEffectsUsage.entrySet()) {
- if (notMoreThanEffect.getValue() > 0
- && notMoreThanEffect.getKey().getKey().getFilter().match(selectedPermanent, game)) {
- notMoreThanEffect.setValue(notMoreThanEffect.getValue() - 1);
- }
- }
- // update the left for untap list
- leftForUntap = getPermanentsThatCanBeUntapped(game,
- canBeUntapped,
- handledEntry.getKey().getKey(),
- notMoreThanEffectsUsage);
- // remove already selected permanents
- for (Permanent permanent : selectedToUntap) {
- leftForUntap.remove(permanent);
- }
-
- } else {
- // player selected an permanent that is restricted by another effect, disallow it (so AI can select another one)
- filter.add(Predicates.not(new PermanentIdPredicate(selectedPermanent.getId())));
- if (this.isHuman() && !game.isSimulation()) {
- game.informPlayer(this, "This permanent can't be untapped because of other restricting effect.");
- }
- }
- }
- }
- }
- }
-
- } while (canRespond() && playerCanceledSelection);
-
- if (!game.isSimulation()) {
- // show in log which permanents were selected to untap
- for (Permanent permanent : selectedToUntap) {
- game.informPlayers(this.getLogName() + " untapped " + permanent.getLogName());
- }
- }
- // untap if permanent is not concerned by notMoreThan effects or is included in the selectedToUntapList
- for (Permanent permanent : canBeUntapped) {
- boolean doUntap = true;
- if (!selectedToUntap.contains(permanent)) {
- // if the permanent is covered by one of the restriction effects, don't untap it
- for (Entry>, Integer> notMoreThanEffect : notMoreThanEffectsUsage.entrySet()) {
- if (notMoreThanEffect.getKey().getKey().getFilter().match(permanent, game)) {
- doUntap = false;
- break;
- }
- }
- }
- if (permanent != null && doUntap) {
- permanent.untap(game);
- }
-
- }
-
- } else {
- //20091005 - 502.2
-
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
- boolean untap = true;
- for (RestrictionEffect effect : game.getContinuousEffects().getApplicableRestrictionEffects(permanent, game).keySet()) {
- untap &= effect.canBeUntapped(permanent, null, game, true);
- }
- if (untap) {
- permanent.untap(game);
- }
- }
- }
- }
-
- private List getPermanentsThatCanBeUntapped(Game game, List canBeUntapped, RestrictionUntapNotMoreThanEffect handledEffect, Map>, Integer> notMoreThanEffectsUsage) {
- List leftForUntap = new ArrayList<>();
- // select permanents that can still be untapped
- for (Permanent permanent : canBeUntapped) {
- if (handledEffect.getFilter().match(permanent, game)) { // matches the restricted permanents of handled entry
- boolean canBeSelected = true;
- // check if the permanent is restricted by another restriction that has left no permanent
- for (Entry>, Integer> notMoreThanEffect : notMoreThanEffectsUsage.entrySet()) {
- if (notMoreThanEffect.getKey().getKey().getFilter().match(permanent, game)
- && notMoreThanEffect.getValue() == 0) {
- canBeSelected = false;
- break;
- }
- }
- if (canBeSelected) {
- leftForUntap.add(permanent);
- }
- }
- }
- return leftForUntap;
- }
-
- @Override
- public UUID getId() {
- return playerId;
- }
-
- @Override
- public Cards getHand() {
- return hand;
- }
-
- @Override
- public Graveyard getGraveyard() {
- return graveyard;
- }
-
- @Override
- public ManaPool getManaPool() {
- return this.manaPool;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public String getLogName() {
- return GameLog.getColoredPlayerName(name);
- }
-
- @Override
- public boolean isHuman() {
- return human;
- }
-
- @Override
- public Library getLibrary() {
- return library;
- }
-
- @Override
- public Cards getSideboard() {
- return sideboard;
- }
-
- @Override
- public int getLife() {
- return life;
- }
-
- @Override
- public void initLife(int life) {
- this.life = life;
- }
-
- @Override
- public void setLife(int life, Game game, Ability source) {
- // rule 118.5
- if (life > this.life) {
- gainLife(life - this.life, game, source);
- } else if (life < this.life) {
- loseLife(this.life - life, game, source, false);
- }
- }
-
- @Override
- public void setLifeTotalCanChange(boolean lifeTotalCanChange) {
- this.canGainLife = lifeTotalCanChange;
- this.canLoseLife = lifeTotalCanChange;
- }
-
- @Override
- public boolean isLifeTotalCanChange() {
- return canGainLife || canLoseLife;
- }
-
- @Override
- public List getAlternativeSourceCosts() {
- return alternativeSourceCosts;
- }
-
- @Override
- public boolean isCanLoseLife() {
- return canLoseLife;
- }
-
- @Override
- public void setCanLoseLife(boolean canLoseLife) {
- this.canLoseLife = canLoseLife;
- }
-
- @Override
- public int loseLife(int amount, Game game, Ability source, boolean atCombat, UUID attackerId) {
- if (!canLoseLife || !this.isInGame()) {
- return 0;
- }
- GameEvent event = new GameEvent(GameEvent.EventType.LOSE_LIFE,
- playerId, source, playerId, amount, atCombat);
- if (!game.replaceEvent(event)) {
- this.life = CardUtil.overflowDec(this.life, event.getAmount());
- if (!game.isSimulation()) {
- UUID needId = attackerId;
- if (needId == null) {
- needId = source == null ? null : source.getSourceId();
- }
- game.informPlayers(this.getLogName() + " loses " + event.getAmount() + " life"
- + (atCombat ? " at combat" : "") + CardUtil.getSourceLogName(game, " from ", needId, "", ""));
- }
- if (amount > 0) {
- game.fireEvent(new GameEvent(GameEvent.EventType.LOST_LIFE,
- playerId, source, playerId, amount, atCombat));
- }
- return amount;
- }
- return 0;
- }
-
- @Override
- public int loseLife(int amount, Game game, Ability source, boolean atCombat) {
- return loseLife(amount, game, source, atCombat, null);
- }
-
- @Override
- public boolean isCanGainLife() {
- return canGainLife;
- }
-
- @Override
- public void setCanGainLife(boolean canGainLife) {
- this.canGainLife = canGainLife;
- }
-
- @Override
- public int gainLife(int amount, Game game, Ability source) {
- if (!canGainLife || amount <= 0) {
- return 0;
- }
- GameEvent event = new GameEvent(GameEvent.EventType.GAIN_LIFE,
- playerId, source, playerId, amount, false);
- if (!game.replaceEvent(event)) {
- // TODO: lock life at Integer.MAX_VALUE if reached, until it's set to a different amount
- // (https://magic.wizards.com/en/articles/archive/news/unstable-faqawaslfaqpaftidawabiajtbt-2017-12-06 - "infinite" life total stays infinite no matter how much is gained or lost)
- // this.life += event.getAmount();
- this.life = CardUtil.overflowInc(this.life, event.getAmount());
- if (!game.isSimulation()) {
- game.informPlayers(this.getLogName() + " gains " + event.getAmount() + " life" + CardUtil.getSourceLogName(game, source));
- }
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.GAINED_LIFE,
- playerId, source, playerId, event.getAmount()));
- return event.getAmount();
- }
- return 0;
- }
-
- @Override
- public void exchangeLife(Player player, Ability source, Game game) {
- int lifePlayer1 = getLife();
- int lifePlayer2 = player.getLife();
- if ((lifePlayer1 != lifePlayer2 && this.isLifeTotalCanChange() && player.isLifeTotalCanChange())
- && (lifePlayer1 >= lifePlayer2 || (this.isCanGainLife() && player.isCanLoseLife()))
- && (lifePlayer1 <= lifePlayer2 || (this.isCanLoseLife() && player.isCanGainLife()))) {
- this.setLife(lifePlayer2, game, source);
- player.setLife(lifePlayer1, game, source);
- }
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game) {
- return doDamage(damage, attackerId, source, game, false, true, null);
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable) {
- return doDamage(damage, attackerId, source, game, combatDamage, preventable, null);
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable, List appliedEffects) {
- return doDamage(damage, attackerId, source, game, combatDamage, preventable, appliedEffects);
- }
-
- private int doDamage(int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable, List appliedEffects) {
- if (!this.isInGame()) {
- return 0;
- }
-
- if (damage < 1) {
- return 0;
- }
- if (!canDamage(game.getObject(attackerId), game)) {
- MageObject sourceObject = game.getObject(attackerId);
- game.informPlayers(damage + " damage "
- + (sourceObject == null ? "" : "from " + sourceObject.getLogName())
- + " to " + getLogName()
- + (damage > 1 ? " were" : "was") + " prevented because of protection");
- return 0;
- }
- DamageEvent event = new DamagePlayerEvent(playerId, attackerId, playerId, damage, preventable, combatDamage);
- event.setAppliedEffects(appliedEffects);
- if (game.replaceEvent(event)) {
- return 0;
- }
- int actualDamage = event.getAmount();
- if (actualDamage < 1) {
- return 0;
- }
- UUID sourceControllerId = null;
- Abilities sourceAbilities = null;
- MageObject attacker = game.getPermanentOrLKIBattlefield(attackerId);
- if (attacker == null) {
- StackObject stackObject = game.getStack().getStackObject(attackerId);
- if (stackObject != null) {
- attacker = stackObject.getStackAbility().getSourceObject(game);
- } else {
- attacker = game.getObject(attackerId);
- }
- if (attacker instanceof Spell) {
- sourceAbilities = ((Spell) attacker).getAbilities(game);
- sourceControllerId = ((Spell) attacker).getControllerId();
- } else if (attacker instanceof Card) {
- sourceAbilities = ((Card) attacker).getAbilities(game);
- sourceControllerId = ((Card) attacker).getOwnerId();
- } else if (attacker instanceof CommandObject) {
- sourceControllerId = ((CommandObject) attacker).getControllerId();
- sourceAbilities = attacker.getAbilities();
- }
- } else {
- sourceAbilities = ((Permanent) attacker).getAbilities(game);
- sourceControllerId = ((Permanent) attacker).getControllerId();
- }
- if (event.isAsThoughInfect() || (sourceAbilities != null && sourceAbilities.containsKey(InfectAbility.getInstance().getId()))) {
- addCounters(CounterType.POISON.createInstance(actualDamage), sourceControllerId, source, game);
- } else {
- GameEvent damageToLifeLossEvent = new GameEvent(GameEvent.EventType.DAMAGE_CAUSES_LIFE_LOSS,
- playerId, source, playerId, actualDamage, combatDamage);
- if (!game.replaceEvent(damageToLifeLossEvent)) {
- this.loseLife(damageToLifeLossEvent.getAmount(), game, source, combatDamage, attackerId);
- }
- }
- if (sourceAbilities != null && sourceAbilities.containsKey(LifelinkAbility.getInstance().getId())) {
- if (combatDamage) {
- game.getPermanent(attackerId).markLifelink(actualDamage);
- } else {
- Player player = game.getPlayer(sourceControllerId);
- player.gainLife(actualDamage, game, source);
- }
- }
- // Unstable ability - Earl of Squirrel
- if (sourceAbilities != null && sourceAbilities.containsKey(SquirrellinkAbility.getInstance().getId())) {
- Player player = game.getPlayer(sourceControllerId);
- new SquirrelToken().putOntoBattlefield(actualDamage, game, source, player.getId());
- }
- DamagedEvent damagedEvent = new DamagedPlayerEvent(playerId, attackerId, playerId, actualDamage, combatDamage);
- game.fireEvent(damagedEvent);
- game.getState().addSimultaneousDamage(damagedEvent, game);
- return actualDamage;
- }
-
- @Override
- public boolean addCounters(Counter counter, UUID playerAddingCounters, Ability source, Game game) {
- boolean returnCode = true;
- GameEvent addingAllEvent = GameEvent.getEvent(
- GameEvent.EventType.ADD_COUNTERS, playerId, source,
- playerAddingCounters, counter.getName(), counter.getCount()
- );
- if (!game.replaceEvent(addingAllEvent)) {
- int amount = addingAllEvent.getAmount();
- int finalAmount = amount;
- boolean isEffectFlag = addingAllEvent.getFlag();
- for (int i = 0; i < amount; i++) {
- Counter eventCounter = counter.copy();
- eventCounter.remove(eventCounter.getCount() - 1);
- GameEvent addingOneEvent = GameEvent.getEvent(
- GameEvent.EventType.ADD_COUNTER, playerId, source,
- playerAddingCounters, counter.getName(), 1
- );
- addingOneEvent.setFlag(isEffectFlag);
- if (!game.replaceEvent(addingOneEvent)) {
- getCounters().addCounter(eventCounter);
- GameEvent addedOneEvent = GameEvent.getEvent(
- GameEvent.EventType.COUNTER_ADDED, playerId, source,
- playerAddingCounters, counter.getName(), 1
- );
- addedOneEvent.setFlag(addingOneEvent.getFlag());
- game.fireEvent(addedOneEvent);
- } else {
- finalAmount--;
- returnCode = false;
- }
- }
- if (finalAmount > 0) {
- GameEvent addedAllEvent = GameEvent.getEvent(
- GameEvent.EventType.COUNTERS_ADDED, playerId, source,
- playerAddingCounters, counter.getName(), amount
- );
- addedAllEvent.setFlag(addingAllEvent.getFlag());
- game.fireEvent(addedAllEvent);
- }
- } else {
- returnCode = false;
- }
- return returnCode;
- }
-
- @Override
- public void removeCounters(String name, int amount, Ability source, Game game) {
- int finalAmount = 0;
- for (int i = 0; i < amount; i++) {
- if (!counters.removeCounter(name, 1)) {
- break;
- }
- GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTER_REMOVED,
- getId(), source, (source == null ? null : source.getControllerId()));
- event.setData(name);
- event.setAmount(1);
- game.fireEvent(event);
- finalAmount++;
- }
- GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTERS_REMOVED,
- getId(), source, (source == null ? null : source.getControllerId()));
- event.setData(name);
- event.setAmount(finalAmount);
- game.fireEvent(event);
- }
-
- protected boolean canDamage(MageObject source, Game game) {
- for (ProtectionAbility ability : abilities.getProtectionAbilities()) {
- if (!ability.canTarget(source, game)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public Abilities getAbilities() {
- return this.abilities;
- }
-
- @Override
- public void addAbility(Ability ability) {
- ability.setSourceId(playerId);
- this.abilities.add(ability);
- }
-
- @Override
- public int getLandsPerTurn() {
- return this.landsPerTurn;
- }
-
- @Override
- public void setLandsPerTurn(int landsPerTurn) {
- this.landsPerTurn = landsPerTurn;
- }
-
- @Override
- public int getLoyaltyUsePerTurn() {
- return this.loyaltyUsePerTurn;
- }
-
- @Override
- public void setLoyaltyUsePerTurn(int loyaltyUsePerTurn) {
- this.loyaltyUsePerTurn = loyaltyUsePerTurn;
- }
-
- @Override
- public int getMaxHandSize() {
- return maxHandSize;
- }
-
- @Override
- public void setMaxHandSize(int maxHandSize) {
- this.maxHandSize = maxHandSize;
- }
-
- @Override
- public void setMaxAttackedBy(int maxAttackedBy) {
- this.maxAttackedBy = maxAttackedBy;
- }
-
- @Override
- public int getMaxAttackedBy() {
- return maxAttackedBy;
- }
-
- @Override
- public void setResponseString(String responseString) {
- }
-
- @Override
- public void setResponseManaType(UUID manaTypePlayerId, ManaType responseManaType) {
- }
-
- @Override
- public void setResponseUUID(UUID responseUUID) {
- }
-
- @Override
- public void setResponseBoolean(Boolean responseBoolean) {
- }
-
- @Override
- public void setResponseInteger(Integer responseInteger) {
- }
-
- @Override
- public boolean isPassed() {
- return passed;
- }
-
- @Override
- public void pass(Game game) {
- this.passed = true;
- resetStoredBookmark(game);
- }
-
- @Override
- public void resetPassed() {
- this.passed = this.loses || this.hasLeft();
- }
-
- @Override
- public void resetPlayerPassedActions() {
- this.passed = false;
- this.passedTurn = false;
- this.passedTurnSkipStack = false;
- this.passedUntilEndOfTurn = false;
- this.passedUntilNextMain = false;
- this.passedUntilStackResolved = false;
- this.dateLastAddedToStack = null;
- this.passedUntilEndStepBeforeMyTurn = false;
- this.skippedAtLeastOnce = false;
- this.passedAllTurns = false;
- this.justActivatedType = null;
- }
-
- @Override
- public void quit(Game game) {
- quit = true;
- this.concede(game);
- logger.debug(getName() + " quits the match.");
- game.informPlayers(getLogName() + " quits the match.");
- }
-
- @Override
- public void timerTimeout(Game game) {
- quit = true;
- timerTimeout = true;
- this.concede(game);
- game.informPlayers(getLogName() + " has run out of time, losing the match.");
- }
-
- @Override
- public void idleTimeout(Game game) {
- quit = true;
- idleTimeout = true;
- this.concede(game);
- game.informPlayers(getLogName() + " was idle for too long, losing the Match.");
- }
-
- @Override
- public void concede(Game game) {
- game.setConcedingPlayer(playerId);
- lost(game);
-// this.left = true;
- }
-
- @Override
- public void sendPlayerAction(PlayerAction playerAction, Game game, Object data) {
- switch (playerAction) {
- case PASS_PRIORITY_UNTIL_MY_NEXT_TURN: // F9
- resetPlayerPassedActions();
- passedAllTurns = true;
- this.skip();
- break;
- case PASS_PRIORITY_UNTIL_TURN_END_STEP: // F5
- resetPlayerPassedActions();
- passedUntilEndOfTurn = true;
- skippedAtLeastOnce = PhaseStep.END_TURN != game.getTurn().getStepType();
- this.skip();
- break;
- case PASS_PRIORITY_UNTIL_NEXT_TURN: // F4
- resetPlayerPassedActions();
- passedTurn = true;
- this.skip();
- break;
- case PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK: // F6
- resetPlayerPassedActions();
- passedTurnSkipStack = true;
- this.skip();
- break;
- case PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE: //F7
- resetPlayerPassedActions();
- passedUntilNextMain = true;
- skippedAtLeastOnce = !(game.getTurn().getStepType() == PhaseStep.POSTCOMBAT_MAIN
- || game.getTurn().getStepType() == PhaseStep.PRECOMBAT_MAIN);
- this.skip();
- break;
- case PASS_PRIORITY_UNTIL_STACK_RESOLVED: // Default F10 - Skips until the current stack is resolved
- if (!game.getStack().isEmpty()) { // If stack is empty do nothing
- resetPlayerPassedActions();
- passedUntilStackResolved = true;
- dateLastAddedToStack = game.getStack().getDateLastAdded();
- this.skip();
- }
- break;
- case PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN: //F11
- resetPlayerPassedActions();
- passedUntilEndStepBeforeMyTurn = true;
- this.skip();
- break;
- case PASS_PRIORITY_CANCEL_ALL_ACTIONS:
- resetPlayerPassedActions();
- break;
- case PERMISSION_REQUESTS_ALLOWED_OFF:
- userData.setAllowRequestShowHandCards(false);
- break;
- case PERMISSION_REQUESTS_ALLOWED_ON:
- userData.setAllowRequestShowHandCards(true);
- userData.resetRequestedHandPlayersList(game.getId()); // users can send request again
- break;
- }
- logger.trace("PASS Priority: " + playerAction);
- }
-
- @Override
- public void leave() {
- this.passed = true;
- this.loses = true;
- this.left = true;
- this.abort();
- //20100423 - 800.4a
- this.hand.clear();
- this.graveyard.clear();
- this.library.clear();
- }
-
- @Override
- public boolean hasLeft() {
- return this.left;
- }
-
- @Override
- public void lost(Game game) {
- if (canLose(game)) {
- lostForced(game);
- }
- }
-
- @Override
- public void lostForced(Game game) {
- logger.debug(this.getName() + " has lost gameId: " + game.getId());
- //20100423 - 603.9
- if (!this.wins) {
- this.loses = true;
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST, null, null, playerId));
- game.informPlayers(this.getLogName() + " has lost the game.");
- } else {
- logger.debug(this.getName() + " has already won - stop lost");
- }
- // for draw - first all players that have lost have to be set to lost
- if (!hasLeft()) {
- logger.debug("Game over playerId: " + playerId);
- game.setConcedingPlayer(playerId);
- }
- }
-
- @Override
- public boolean canLose(Game game) {
- return hasLeft() // If a player concedes or has left the match they lose also if effect would say otherwise
- || !game.replaceEvent(new GameEvent(GameEvent.EventType.LOSES, null, null, playerId));
- }
-
- @Override
- public void won(Game game) {
- boolean opponentInGame = false;
- for (UUID opponentId : game.getOpponents(playerId)) {
- Player opponent = game.getPlayer(opponentId);
-
- if (opponent != null && opponent.isInGame()) {
- opponentInGame = true;
- break;
- }
- }
- if (!opponentInGame
- || // if no more opponent is in game the wins event may no longer be replaced
- !game.replaceEvent(new GameEvent(GameEvent.EventType.WINS, null, null, playerId))) {
- logger.debug("player won -> start: " + this.getName());
- if (!this.loses) {
- //20130501 - 800.7, 801.16
- // all opponents in range loose the game
- for (UUID opponentId : game.getOpponents(playerId)) {
- Player opponent = game.getPlayer(opponentId);
- if (opponent != null && !opponent.hasLost()) {
- logger.debug("player won -> calling opponent lost: "
- + this.getName() + " opponent: " + opponent.getName());
- opponent.lostForced(game);
- }
- }
- // if no more opponents alive (independant from range), you win and the game ends
- int opponentsAlive = 0;
- for (UUID playerIdToCheck : game.getPlayerList()) {
- if (game.isOpponent(this, playerIdToCheck)) { // Check without range
- Player opponent = game.getPlayer(playerIdToCheck);
- if (opponent != null && !opponent.hasLost()) {
- opponentsAlive++;
- }
- }
- }
- if (opponentsAlive == 0 && !hasWon()) {
- logger.debug("player won -> No more opponents alive game won: " + this.getName());
- game.informPlayers(this.getLogName() + " has won the game");
- this.wins = true;
- game.end();
- }
- } else {
- logger.debug("player won -> but already lost before or other players still alive: " + this.getName());
- }
- }
- }
-
- @Override
- public void drew(Game game) {
- if (!hasLost()) {
- this.draws = true;
- game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DRAW_PLAYER, null, null, playerId));
- game.informPlayers("For " + this.getLogName() + " the game is a draw.");
- game.setConcedingPlayer(playerId);
- }
- }
-
- @Override
- public boolean hasLost() {
- return this.loses;
- }
-
- @Override
- public boolean isInGame() {
- return !hasQuit() && !hasLost() && !hasWon() && !hasDrew() && !hasLeft();
- }
-
- @Override
- public boolean canRespond() { // abort is checked here to get out of player requests (as example: after disconnect)
- return isInGame() && !abort;
- }
-
- @Override
- public boolean hasWon() {
- return !this.loses && this.wins;
- }
-
- @Override
- public boolean hasDrew() {
- return this.draws;
- }
-
- @Override
- public void declareAttacker(UUID attackerId, UUID defenderId, Game game, boolean allowUndo) {
- if (allowUndo) {
- setStoredBookmark(game.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda
- }
- Permanent attacker = game.getPermanent(attackerId);
- if (attacker != null
- && attacker.canAttack(defenderId, game)
- && attacker.isControlledBy(playerId)) {
- if (!game.getCombat().declareAttacker(attackerId, defenderId, playerId, game)) {
- game.undo(playerId);
- }
- }
- }
-
- @Override
- public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game) {
- declareBlocker(defenderId, blockerId, attackerId, game, true);
- }
-
- @Override
- public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game, boolean allowUndo) {
- if (isHuman() && allowUndo) {
- setStoredBookmark(game.bookmarkState());
- }
- Permanent blocker = game.getPermanent(blockerId);
- CombatGroup group = game.getCombat().findGroup(attackerId);
- if (blocker != null && group != null && group.canBlock(blocker, game)) {
- group.addBlocker(blockerId, playerId, game);
- game.getCombat().addBlockingGroup(blockerId, attackerId, playerId, game);
- } else if (this.isHuman() && !game.isSimulation()) {
- game.informPlayer(this, "You can't block this creature.");
- }
- }
-
- @Override
- public boolean searchLibrary(TargetCardInLibrary target, Ability source, Game game) {
- return searchLibrary(target, source, game, playerId);
- }
-
- @Override
- public boolean searchLibrary(TargetCardInLibrary target, Ability source, Game game, UUID targetPlayerId) {
- //20091005 - 701.14c
-
- // searching control can be intercepted by another player, see Opposition Agent
- SearchLibraryEvent searchEvent = new SearchLibraryEvent(targetPlayerId, source, playerId, Integer.MAX_VALUE);
- if (game.replaceEvent(searchEvent)) {
- return false;
- }
-
- Player targetPlayer = game.getPlayer(targetPlayerId);
- Player searchingPlayer = this;
- Player searchingController = game.getPlayer(searchEvent.getSearchingControllerId());
- if (targetPlayer == null || searchingController == null) {
- return false;
- }
-
- String searchInfo = searchingPlayer.getLogName();
- if (!searchingPlayer.getId().equals(searchingController.getId())) {
- searchInfo = searchInfo + " under control of " + searchingPlayer.getLogName();
- }
- if (targetPlayer.getId().equals(searchingPlayer.getId())) {
- searchInfo = searchInfo + " searches their library";
- } else {
- searchInfo = searchInfo + " searches the library of " + targetPlayer.getLogName();
- }
-
- if (!game.isSimulation()) {
- game.informPlayers(searchInfo + CardUtil.getSourceLogName(game, source));
- }
-
- // https://www.reddit.com/r/magicTCG/comments/jj8gh9/opposition_agent_and_panglacial_wurm_interaction/
- // You must take full player control while searching, e.g. you can cast opponent's cards by Panglacial Wurm effect:
- // * While you’re searching your library, you may cast Panglacial Wurm from your library.
- // So use here same code as Word of Command
- // P.S. no needs in searchingController, but it helps with unit tests, see TakeControlWhileSearchingLibraryTest
- boolean takeControl = false;
- if (!searchingPlayer.getId().equals(searchingController.getId())) {
- CardUtil.takeControlUnderPlayerStart(game, searchingController, searchingPlayer, true);
- takeControl = true;
- }
-
- Library searchingLibrary = targetPlayer.getLibrary();
- TargetCardInLibrary newTarget = target.copy();
- int count;
- int librarySearchLimit = searchEvent.getAmount();
- List cardsFromTop = null;
- do {
- // TODO: prevent shuffling from moving the visualized cards
- if (librarySearchLimit == Integer.MAX_VALUE) {
- count = searchingLibrary.count(target.getFilter(), game);
- } else {
- if (cardsFromTop == null) {
- cardsFromTop = new ArrayList<>(searchingLibrary.getTopCards(game, librarySearchLimit));
- } else {
- cardsFromTop.retainAll(searchingLibrary.getCards(game));
- }
- newTarget.setCardLimit(Math.min(librarySearchLimit, cardsFromTop.size()));
- count = Math.min(searchingLibrary.count(target.getFilter(), game), librarySearchLimit);
- }
-
- if (count < target.getNumberOfTargets()) {
- newTarget.setMinNumberOfTargets(count);
- }
-
- // handling Panglacial Wurm - cast cards while searching from own library
- if (targetPlayer.getId().equals(searchingPlayer.getId())) {
- if (handleCastableCardsWhileLibrarySearching(library, game, targetPlayer)) {
- // clear all choices to start from scratch (casted cards must be removed from library)
- newTarget.clearChosen();
- continue;
- }
- }
-
- if (newTarget.choose(Outcome.Neutral, searchingController.getId(), targetPlayer.getId(), game)) {
- target.getTargets().clear();
- for (UUID targetId : newTarget.getTargets()) {
- target.add(targetId, game);
- }
- }
-
- // END SEARCH
- if (takeControl) {
- CardUtil.takeControlUnderPlayerEnd(game, searchingController, searchingPlayer);
- game.informPlayers("Control of " + searchingPlayer.getLogName() + " is back" + CardUtil.getSourceLogName(game, source));
- }
-
- LibrarySearchedEvent searchedEvent = new LibrarySearchedEvent(targetPlayer.getId(), source, searchingPlayer.getId(), target);
- if (!game.replaceEvent(searchedEvent)) {
- game.fireEvent(searchedEvent);
- }
- break;
- } while (true);
-
- return true;
- }
-
- @Override
- public boolean seekCard(FilterCard filter, Ability source, Game game) {
- Set cards = this.getLibrary()
- .getCards(game)
- .stream()
- .filter(card -> filter.match(card, source.getSourceId(), getId(), game))
- .collect(Collectors.toSet());
- Card card = RandomUtil.randomFromCollection(cards);
- if (card == null) {
- return false;
- }
- game.informPlayers(this.getLogName() + " seeks a card from their library");
- this.moveCards(card, Zone.HAND, source, game);
- return true;
- }
-
- @Override
- public void lookAtAllLibraries(Ability source, Game game) {
- for (UUID playerId : game.getState().getPlayersInRange(this.getId(), game)) {
- Player player = game.getPlayer(playerId);
- String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s ";
- playerName += "library";
- Cards cardsInLibrary = new CardsImpl(player.getLibrary().getTopCards(game, player.getLibrary().size()));
- lookAtCards(playerName, cardsInLibrary, game);
- }
- }
-
- private boolean handleCastableCardsWhileLibrarySearching(Library library, Game game, Player targetPlayer) {
- // must return true after cast try (to restart searching process without casted cards)
- // uses for handling Panglacial Wurm:
- // * While you're searching your library, you may cast Panglacial Wurm from your library.
-
- List castableCards = library.getCards(game).stream()
- .filter(card -> card.getAbilities(game).containsClass(WhileSearchingPlayFromLibraryAbility.class))
- .map(MageItem::getId)
- .collect(Collectors.toList());
- if (castableCards.size() == 0) {
- return false;
- }
-
- // only humans can use it
- if (targetPlayer.isComputer()) {
- return false;
- }
-
- if (!targetPlayer.chooseUse(Outcome.AIDontUseIt, "There are " + castableCards.size() + " cards you can cast while searching your library. Cast any of them?", null, game)) {
- return false;
- }
-
- boolean casted = false;
- TargetCard targetCard = new TargetCard(0, 1, Zone.LIBRARY, StaticFilters.FILTER_CARD);
- targetCard.setTargetName("card to cast from library");
- targetCard.setNotTarget(true);
- while (castableCards.size() > 0) {
- targetCard.clearChosen();
- if (!targetPlayer.choose(Outcome.AIDontUseIt, new CardsImpl(castableCards), targetCard, game)) {
- break;
- }
-
- Card card = game.getCard(targetCard.getFirstTarget());
- if (card == null) {
- break;
- }
-
- // AI NOTICE: if you want AI implement here then remove selected card from castable after each
- // choice (otherwise you catch infinite freeze on uncastable use case)
- // casting selected card
- // TODO: fix costs (why is Panglacial Wurm automatically accepting payment?)
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), Boolean.TRUE);
- targetPlayer.cast(targetPlayer.chooseAbilityForCast(card, game, false), game, false, null);
- game.getState().setValue("PlayFromNotOwnHandZone" + card.getId(), null);
- castableCards.remove(card.getId());
- casted = true;
- }
- return casted;
- }
-
- /**
- * @param source
- * @param game
- * @param winnable
- * @return if winnable, true if player won the toss, if not winnable, true
- * for heads and false for tails
- */
- @Override
- public boolean flipCoin(Ability source, Game game, boolean winnable) {
- boolean chosen = false;
- if (winnable) {
- chosen = this.chooseUse(Outcome.Benefit, "Heads or tails?", "", "Heads", "Tails", source, game);
- game.informPlayers(getLogName() + " chose " + CardUtil.booleanToFlipName(chosen));
- }
- boolean result = this.flipCoinResult(game);
- FlipCoinEvent event = new FlipCoinEvent(playerId, source, result, chosen, winnable);
- game.replaceEvent(event);
- game.informPlayers(getLogName() + " flipped " + CardUtil.booleanToFlipName(event.getResult())
- + CardUtil.getSourceLogName(game, source));
- if (event.getFlipCount() > 1) {
- boolean canChooseHeads = event.getResult();
- boolean canChooseTails = !event.getResult();
- for (int i = 1; i < event.getFlipCount(); i++) {
- boolean tempFlip = this.flipCoinResult(game);
- canChooseHeads = canChooseHeads || tempFlip;
- canChooseTails = canChooseTails || !tempFlip;
- game.informPlayers(getLogName() + " flipped " + CardUtil.booleanToFlipName(tempFlip));
- }
- if (canChooseHeads && canChooseTails) {
- event.setResult(chooseUse(Outcome.Benefit, "Choose which flip to keep",
- (event.isWinnable() ? "(You called " + event.getChosenName() + ")" : null),
- "Heads", "Tails", source, game
- ));
- } else {
- event.setResult(canChooseHeads);
- }
- game.informPlayers(getLogName() + " chose to keep " + CardUtil.booleanToFlipName(event.getResult()));
- }
- if (event.isWinnable()) {
- game.informPlayers(getLogName() + " " + (event.getResult() == event.getChosen() ? "won" : "lost") + " the flip"
- + CardUtil.getSourceLogName(game, source));
- }
- game.fireEvent(event.createFlippedEvent());
- if (event.isWinnable()) {
- return event.getResult() == event.getChosen();
- }
- return event.getResult();
- }
-
- /**
- * Return result for next flip coint try (can be contolled in tests)
- *
- * @return
- */
- @Override
- public boolean flipCoinResult(Game game) {
- return RandomUtil.nextBoolean();
- }
-
- private static final class RollDieResult {
-
- // 706.2.
- // After the roll, the number indicated on the top face of the die before any modifiers is
- // the natural result. The instruction may include modifiers to the roll which add to or
- // subtract from the natural result. Modifiers may also come from other sources. After
- // considering all applicable modifiers, the final number is the result of the die roll.
- private final int naturalResult;
- private final int modifier;
- private final PlanarDieRollResult planarResult;
-
- RollDieResult(int naturalResult, int modifier, PlanarDieRollResult planarResult) {
- this.naturalResult = naturalResult;
- this.modifier = modifier;
- this.planarResult = planarResult;
- }
-
- public int getResult() {
- return this.naturalResult + this.modifier;
- }
-
- public PlanarDieRollResult getPlanarResult() {
- return this.planarResult;
- }
- }
-
- @Override
- public int rollDieResult(int sides, Game game) {
- return RandomUtil.nextInt(sides) + 1;
- }
-
- /**
- * Roll single die. Support both die types: planar and numerical.
- *
- * @param outcome
- * @param game
- * @param source
- * @param rollDieType
- * @param sidesAmount
- * @param chaosSidesAmount
- * @param planarSidesAmount
- * @param rollsAmount
- * @return
- */
- private Object rollDieInner(Outcome outcome, Game game, Ability source, RollDieType rollDieType,
- int sidesAmount, int chaosSidesAmount, int planarSidesAmount, int rollsAmount) {
- if (rollsAmount == 1) {
- return rollDieInnerWithReplacement(game, source, rollDieType, sidesAmount, chaosSidesAmount, planarSidesAmount);
- }
- Set