From 91a3d9a6a2ce01d5fc76c19b352d067c218ea799 Mon Sep 17 00:00:00 2001 From: Justin Herlehy Date: Wed, 21 Dec 2016 02:33:58 -0500 Subject: [PATCH 1/7] [AER] Heart of Kiran As the alternate crew cost payment ability is just a simple activated ability with a different wording, it is implemented here as an anonymous inner class to override the getRule() method rather than generate large amounts of boilerplate code to get the same effect with a full class. --- Mage.Sets/src/mage/cards/h/HeartOfKiran.java | 93 ++++++++++++++++++++ Mage.Sets/src/mage/sets/AetherRevolt.java | 1 + 2 files changed, 94 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HeartOfKiran.java diff --git a/Mage.Sets/src/mage/cards/h/HeartOfKiran.java b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java new file mode 100644 index 00000000000..b652e73559f --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.h; + +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.RemoveCounterCost; +import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledPlaneswalkerPermanent; +import mage.target.common.TargetControlledPermanent; + +import java.util.UUID; + +/** + * @author JRHerlehy + */ +public class HeartOfKiran extends CardImpl { + + private static final FilterControlledPlaneswalkerPermanent filter = new FilterControlledPlaneswalkerPermanent("planeswalker you control"); + + public HeartOfKiran(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + this.supertype.add("Legendary"); + this.subtype.add("Vehicle"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Crew 3 + this.addAbility(new CrewAbility(3)); + + // You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost. + Cost cost = new RemoveCounterCost(new TargetControlledPermanent(filter), CounterType.LOYALTY, 1); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeSourceEffect(CardType.CREATURE, Duration.EndOfTurn), cost) { + @Override + public String getRule() { + return "You may remove a loyalty counter from a planeswalker you control rather than pay {this}'s crew cost."; + } + }; + this.addAbility(ability); + } + + public HeartOfKiran(final HeartOfKiran card) { + super(card); + } + + @Override + public HeartOfKiran copy() { + return new HeartOfKiran(this); + } +} diff --git a/Mage.Sets/src/mage/sets/AetherRevolt.java b/Mage.Sets/src/mage/sets/AetherRevolt.java index 1a4864be2d4..ce57ddc72b8 100644 --- a/Mage.Sets/src/mage/sets/AetherRevolt.java +++ b/Mage.Sets/src/mage/sets/AetherRevolt.java @@ -69,6 +69,7 @@ public class AetherRevolt extends ExpansionSet { cards.add(new SetCardInfo("Consulate Crackdown", 11, Rarity.RARE, mage.cards.c.ConsulateCrackdown.class)); cards.add(new SetCardInfo("Dark Intimations", 128, Rarity.RARE, mage.cards.d.DarkIntimations.class)); cards.add(new SetCardInfo("Disallow", 31, Rarity.RARE, mage.cards.d.Disallow.class)); + cards.add(new SetCardInfo("Heart of Kiran", 153, Rarity.MYTHIC, mage.cards.h.HeartOfKiran.class)); cards.add(new SetCardInfo("Oath of Ajani", 131, Rarity.RARE, mage.cards.o.OathOfAjani.class)); cards.add(new SetCardInfo("Pia's Revolution", 91, Rarity.RARE, mage.cards.p.PiasRevolution.class)); cards.add(new SetCardInfo("Quicksmith Rebel", 93, Rarity.RARE, mage.cards.q.QuicksmithRebel.class)); From 4ef339d521e009d4960759c5ab6494963bfafb01 Mon Sep 17 00:00:00 2001 From: Justin Herlehy Date: Wed, 21 Dec 2016 23:07:55 -0500 Subject: [PATCH 2/7] [AER] Heart of Kiran Fixed the Alternate Crew Cost to push the correct game events for crewing a vehicle and the vehicle being crewed. --- Mage.Sets/src/mage/cards/h/HeartOfKiran.java | 65 ++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HeartOfKiran.java b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java index b652e73559f..dca01ade0a3 100644 --- a/Mage.Sets/src/mage/cards/h/HeartOfKiran.java +++ b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java @@ -31,7 +31,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.Cost; -import mage.abilities.costs.common.RemoveCounterCost; +import mage.abilities.costs.CostImpl; import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect; import mage.abilities.keyword.CrewAbility; import mage.abilities.keyword.FlyingAbility; @@ -40,9 +40,14 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.Outcome; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.common.FilterControlledPlaneswalkerPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.Target; import mage.target.common.TargetControlledPermanent; import java.util.UUID; @@ -52,8 +57,6 @@ import java.util.UUID; */ public class HeartOfKiran extends CardImpl { - private static final FilterControlledPlaneswalkerPermanent filter = new FilterControlledPlaneswalkerPermanent("planeswalker you control"); - public HeartOfKiran(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); @@ -72,7 +75,7 @@ public class HeartOfKiran extends CardImpl { this.addAbility(new CrewAbility(3)); // You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost. - Cost cost = new RemoveCounterCost(new TargetControlledPermanent(filter), CounterType.LOYALTY, 1); + Cost cost = new HeartOfKiranAlternateCrewCost(CounterType.LOYALTY, 1); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeSourceEffect(CardType.CREATURE, Duration.EndOfTurn), cost) { @Override public String getRule() { @@ -91,3 +94,57 @@ public class HeartOfKiran extends CardImpl { return new HeartOfKiran(this); } } + +class HeartOfKiranAlternateCrewCost extends CostImpl { + + private CounterType counterTypeToRemove; + private int countersToRemove; + + private static final FilterControlledPlaneswalkerPermanent filter = new FilterControlledPlaneswalkerPermanent("planeswalker you control"); + + public HeartOfKiranAlternateCrewCost(CounterType counterTypeToRemove, int countersToRemove) { + this.counterTypeToRemove = counterTypeToRemove; + this.countersToRemove = countersToRemove; + } + + public HeartOfKiranAlternateCrewCost(final HeartOfKiranAlternateCrewCost cost) { + super(cost); + this.counterTypeToRemove = cost.counterTypeToRemove; + this.countersToRemove = cost.countersToRemove; + } + + @Override + public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { + paid = false; + + Target target = new TargetControlledPermanent(1, 1, filter, true); + + if (target.choose(Outcome.Benefit, controllerId, sourceId, game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + int originalLoyalty = permanent.getCounters(game).getCount(counterTypeToRemove); + + GameEvent event = new GameEvent(GameEvent.EventType.CREW_VEHICLE, target.getFirstTarget(), sourceId, controllerId); + if (!game.replaceEvent(event)) { + permanent.removeCounters(counterTypeToRemove.createInstance(), game); + } + + paid = permanent.getCounters(game).getCount(counterTypeToRemove) < originalLoyalty; + + if (paid) { + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREWED_VEHICLE, target.getFirstTarget(), sourceId, controllerId)); + } + } + + return paid; + } + + @Override + public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) { + return game.getBattlefield().getAllActivePermanents(filter, game).size() > 0; + } + + @Override + public HeartOfKiranAlternateCrewCost copy() { + return new HeartOfKiranAlternateCrewCost(this); + } +} From c2ef2b1f4795f4e69cdeac3850ba7cacf93c8cf1 Mon Sep 17 00:00:00 2001 From: Styxo Date: Thu, 22 Dec 2016 08:05:22 +0100 Subject: [PATCH 3/7] [CN2] Added Deadly Designs and Fang of the Pack --- Mage.Sets/src/mage/cards/d/DeadlyDesigns.java | 143 ++++++ Mage.Sets/src/mage/cards/f/FangOfThePack.java | 81 +++ .../src/mage/sets/ConspiracyTakeTheCrown.java | 484 +++++++++--------- .../main/java/mage/counters/CounterType.java | 1 + 4 files changed, 468 insertions(+), 241 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DeadlyDesigns.java create mode 100644 Mage.Sets/src/mage/cards/f/FangOfThePack.java diff --git a/Mage.Sets/src/mage/cards/d/DeadlyDesigns.java b/Mage.Sets/src/mage/cards/d/DeadlyDesigns.java new file mode 100644 index 00000000000..adcffed33b7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadlyDesigns.java @@ -0,0 +1,143 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.d; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.StateTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.InfoEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Styxo + */ +public class DeadlyDesigns extends CardImpl { + + public DeadlyDesigns(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + + // {2}: Put a plot counter on Deadly Designs. Any player may activate this ability. + SimpleActivatedAbility activatedAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.PLOT.createInstance()), new GenericManaCost(2)); + activatedAbility.setMayActivate(TargetController.ANY); + activatedAbility.addEffect(new InfoEffect("Any player may activate this ability")); + this.addAbility(activatedAbility); + + // When there are five or more plot counters on Deadly Designs, sacrifice it. If you do, destroy up to two target creatures. + StateTriggeredAbility triggerredAbility = new DeadlyDesignsTriggerAbility(); + triggerredAbility.addTarget(new TargetCreaturePermanent(0, 2)); + this.addAbility(triggerredAbility); + } + + public DeadlyDesigns(final DeadlyDesigns card) { + super(card); + } + + @Override + public DeadlyDesigns copy() { + return new DeadlyDesigns(this); + } +} + +class DeadlyDesignsTriggerAbility extends StateTriggeredAbility { + + public DeadlyDesignsTriggerAbility() { + super(Zone.BATTLEFIELD, new DeadlyDesignsEffect()); + } + + public DeadlyDesignsTriggerAbility(final DeadlyDesignsTriggerAbility ability) { + super(ability); + } + + @Override + public DeadlyDesignsTriggerAbility copy() { + return new DeadlyDesignsTriggerAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent permanent = game.getPermanent(getSourceId()); + return permanent != null && permanent.getCounters(game).getCount(CounterType.PLOT) > 4; + } + + @Override + public String getRule() { + return "When there are five or more plot counters on {this}, sacrifice it. If you do, destroy up to two target creatures"; + } +} + +class DeadlyDesignsEffect extends SacrificeSourceEffect { + + private boolean sacrificed = false; + + public DeadlyDesignsEffect() { + super(); + } + + public DeadlyDesignsEffect(final DeadlyDesignsEffect effect) { + super(effect); + this.sacrificed = effect.sacrificed; + } + + @Override + public DeadlyDesignsEffect copy() { + return new DeadlyDesignsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + sacrificed = super.apply(game, source); + if (sacrificed) { + Permanent toDestroy; + for (UUID target : getTargetPointer().getTargets(game, source)) { + toDestroy = game.getPermanent(target); + if (toDestroy != null) { + toDestroy.destroy(source.getId(), game, false); + } + } + } + return sacrificed; + } + + public boolean isSacrificed() { + return sacrificed; + } +} diff --git a/Mage.Sets/src/mage/cards/f/FangOfThePack.java b/Mage.Sets/src/mage/cards/f/FangOfThePack.java new file mode 100644 index 00000000000..83ac7a025d5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FangOfThePack.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.MeleeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author Styxo + */ +public class FangOfThePack extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another target creature you control"); + + static { + filter.add(new AnotherPredicate()); + } + + public FangOfThePack(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}"); + + this.subtype.add("Wolf"); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Melee + this.addAbility(new MeleeAbility()); + + // At the beginning of combat on your turn, another target creature you control gains melee until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(new MeleeAbility(), Duration.EndOfTurn), TargetController.YOU, false); + ability.addTarget(new TargetControlledCreaturePermanent(filter)); + this.addAbility(ability); + } + + public FangOfThePack(final FangOfThePack card) { + super(card); + } + + @Override + public FangOfThePack copy() { + return new FangOfThePack(this); + } +} diff --git a/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java b/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java index cfec1c9f36e..234f7d95aff 100644 --- a/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java +++ b/Mage.Sets/src/mage/sets/ConspiracyTakeTheCrown.java @@ -1,241 +1,243 @@ -/* -* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, are -* permitted provided that the following conditions are met: -* -* 1. Redistributions of source code must retain the above copyright notice, this list of -* conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright notice, this list -* of conditions and the following disclaimer in the documentation and/or other materials -* provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -* The views and conclusions contained in the software and documentation are those of the -* authors and should not be interpreted as representing official policies, either expressed -* or implied, of BetaSteward_at_googlemail.com. -*/ - -package mage.sets; - -import mage.cards.ExpansionSet; -import mage.constants.SetType; -import mage.constants.Rarity; - -/** - * - * @author fireshoes - */ - -public class ConspiracyTakeTheCrown extends ExpansionSet { - - private static final ConspiracyTakeTheCrown fINSTANCE = new ConspiracyTakeTheCrown(); - - public static ConspiracyTakeTheCrown getInstance() { - return fINSTANCE; - } - - private ConspiracyTakeTheCrown() { - super("Conspiracy: Take the Crown", "CN2", ExpansionSet.buildDate(2016, 8, 26), SetType.SUPPLEMENTAL); - this.blockName = "Conspiracy"; - this.hasBasicLands = false; - this.hasBoosters = true; - this.numBoosterLands = 0; - this.numBoosterCommon = 11; - this.numBoosterUncommon = 3; - this.numBoosterRare = 1; - this.ratioBoosterMythic = 8; - cards.add(new SetCardInfo("Absorb Vis", 126, Rarity.COMMON, mage.cards.a.AbsorbVis.class)); - cards.add(new SetCardInfo("Adriana, Captain of the Guard", 73, Rarity.RARE, mage.cards.a.AdrianaCaptainOfTheGuard.class)); - cards.add(new SetCardInfo("Affa Guard Hound", 81, Rarity.UNCOMMON, mage.cards.a.AffaGuardHound.class)); - cards.add(new SetCardInfo("Akroan Hoplite", 197, Rarity.UNCOMMON, mage.cards.a.AkroanHoplite.class)); - cards.add(new SetCardInfo("Altar's Reap", 127, Rarity.COMMON, mage.cards.a.AltarsReap.class)); - cards.add(new SetCardInfo("Ascended Lawmage", 198, Rarity.UNCOMMON, mage.cards.a.AscendedLawmage.class)); - cards.add(new SetCardInfo("Avatar of Woe", 128, Rarity.MYTHIC, mage.cards.a.AvatarOfWoe.class)); - cards.add(new SetCardInfo("Beast Within", 174, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); - cards.add(new SetCardInfo("Berserk", 175, Rarity.MYTHIC, mage.cards.b.Berserk.class)); - cards.add(new SetCardInfo("Birds of Paradise", 176, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); - cards.add(new SetCardInfo("Blood-Toll Harpy", 129, Rarity.COMMON, mage.cards.b.BloodTollHarpy.class)); - cards.add(new SetCardInfo("Bonds of Quicksilver", 102, Rarity.COMMON, mage.cards.b.BondsOfQuicksilver.class)); - cards.add(new SetCardInfo("Borderland Explorer", 61, Rarity.COMMON, mage.cards.b.BorderlandExplorer.class)); - cards.add(new SetCardInfo("Bronze Sable", 208, Rarity.COMMON, mage.cards.b.BronzeSable.class)); - cards.add(new SetCardInfo("Brushstrider", 177, Rarity.UNCOMMON, mage.cards.b.Brushstrider.class)); - cards.add(new SetCardInfo("Burgeoning", 178, Rarity.RARE, mage.cards.b.Burgeoning.class)); - cards.add(new SetCardInfo("Burn Away", 151, Rarity.UNCOMMON, mage.cards.b.BurnAway.class)); - cards.add(new SetCardInfo("Burning Wish", 152, Rarity.RARE, mage.cards.b.BurningWish.class)); - cards.add(new SetCardInfo("Caller of Gales", 103, Rarity.COMMON, mage.cards.c.CallerOfGales.class)); - cards.add(new SetCardInfo("Canal Courier", 28, Rarity.COMMON, mage.cards.c.CanalCourier.class)); - cards.add(new SetCardInfo("Capital Punishment", 40, Rarity.RARE, mage.cards.c.CapitalPunishment.class)); - cards.add(new SetCardInfo("Carnage Gladiator", 199, Rarity.UNCOMMON, mage.cards.c.CarnageGladiator.class)); - cards.add(new SetCardInfo("Charmbreaker Devils", 153, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class)); - cards.add(new SetCardInfo("Child of Night", 130, Rarity.COMMON, mage.cards.c.ChildOfNight.class)); - cards.add(new SetCardInfo("Cloaked Siren", 104, Rarity.COMMON, mage.cards.c.CloakedSiren.class)); - cards.add(new SetCardInfo("Coiling Oracle", 200, Rarity.UNCOMMON, mage.cards.c.CoilingOracle.class)); - cards.add(new SetCardInfo("Coordinated Assault", 154, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class)); - cards.add(new SetCardInfo("Copperhorn Scout", 179, Rarity.COMMON, mage.cards.c.CopperhornScout.class)); - cards.add(new SetCardInfo("Covenant of Minds", 105, Rarity.RARE, mage.cards.c.CovenantOfMinds.class)); - cards.add(new SetCardInfo("Crown-Hunter Hireling", 50, Rarity.COMMON, mage.cards.c.CrownHunterHireling.class)); - cards.add(new SetCardInfo("Custodi Lich", 41, Rarity.RARE, mage.cards.c.CustodiLich.class)); - cards.add(new SetCardInfo("Daretti, Ingenious Iconoclast", 74, Rarity.MYTHIC, mage.cards.d.DarettiIngeniousIconoclast.class)); - cards.add(new SetCardInfo("Death Wind", 131, Rarity.COMMON, mage.cards.d.DeathWind.class)); - cards.add(new SetCardInfo("Deceiver Exarch", 106, Rarity.UNCOMMON, mage.cards.d.DeceiverExarch.class)); - cards.add(new SetCardInfo("Deputized Protester", 51, Rarity.COMMON, mage.cards.d.DeputizedProtester.class)); - cards.add(new SetCardInfo("Desertion", 107, Rarity.RARE, mage.cards.d.Desertion.class)); - cards.add(new SetCardInfo("Diabolic Tutor", 132, Rarity.UNCOMMON, mage.cards.d.DiabolicTutor.class)); - cards.add(new SetCardInfo("Disenchant", 82, Rarity.COMMON, mage.cards.d.Disenchant.class)); - cards.add(new SetCardInfo("Dismiss", 108, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); - cards.add(new SetCardInfo("Divination", 109, Rarity.COMMON, mage.cards.d.Divination.class)); - cards.add(new SetCardInfo("Domesticated Hydra", 63, Rarity.UNCOMMON, mage.cards.d.DomesticatedHydra.class)); - cards.add(new SetCardInfo("Doomed Traveler", 83, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); - cards.add(new SetCardInfo("Dragonlair Spider", 201, Rarity.RARE, mage.cards.d.DragonlairSpider.class)); - cards.add(new SetCardInfo("Dread Statuary", 217, Rarity.UNCOMMON, mage.cards.d.DreadStatuary.class)); - cards.add(new SetCardInfo("Driver of the Dead", 133, Rarity.COMMON, mage.cards.d.DriverOfTheDead.class)); - cards.add(new SetCardInfo("Duskmantle Seer", 202, Rarity.RARE, mage.cards.d.DuskmantleSeer.class)); - cards.add(new SetCardInfo("Ember Beast", 155, Rarity.COMMON, mage.cards.e.EmberBeast.class)); - cards.add(new SetCardInfo("Entourage of Trest", 64, Rarity.COMMON, mage.cards.e.EntourageOfTrest.class)); - cards.add(new SetCardInfo("Evolving Wilds", 218, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); - cards.add(new SetCardInfo("Exotic Orchard", 219, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); - cards.add(new SetCardInfo("Explosive Vegetation", 180, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); - cards.add(new SetCardInfo("Expropriate", 30, Rarity.MYTHIC, mage.cards.e.Expropriate.class)); - cards.add(new SetCardInfo("Fade into Antiquity", 181, Rarity.COMMON, mage.cards.f.FadeIntoAntiquity.class)); - cards.add(new SetCardInfo("Faith's Reward", 84, Rarity.RARE, mage.cards.f.FaithsReward.class)); - cards.add(new SetCardInfo("Farbog Boneflinger", 134, Rarity.UNCOMMON, mage.cards.f.FarbogBoneflinger.class)); - cards.add(new SetCardInfo("Festergloom", 135, Rarity.COMMON, mage.cards.f.Festergloom.class)); - cards.add(new SetCardInfo("Fiery Fall", 156, Rarity.COMMON, mage.cards.f.FieryFall.class)); - cards.add(new SetCardInfo("Flame Slash", 157, Rarity.COMMON, mage.cards.f.FlameSlash.class)); - cards.add(new SetCardInfo("Fleeting Distraction", 110, Rarity.COMMON, mage.cards.f.FleetingDistraction.class)); - cards.add(new SetCardInfo("Fleshbag Marauder", 136, Rarity.UNCOMMON, mage.cards.f.FleshbagMarauder.class)); - cards.add(new SetCardInfo("Followed Footsteps", 111, Rarity.RARE, mage.cards.f.FollowedFootsteps.class)); - cards.add(new SetCardInfo("Forgotten Ancient", 182, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); - cards.add(new SetCardInfo("Gang of Devils", 158, Rarity.UNCOMMON, mage.cards.g.GangOfDevils.class)); - cards.add(new SetCardInfo("Garrulous Sycophant", 43, Rarity.COMMON, mage.cards.g.GarrulousSycophant.class)); - cards.add(new SetCardInfo("Ghostly Possession", 85, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); - cards.add(new SetCardInfo("Ghostly Prison", 86, Rarity.UNCOMMON, mage.cards.g.GhostlyPrison.class)); - cards.add(new SetCardInfo("Gleam of Resistance", 87, Rarity.COMMON, mage.cards.g.GleamOfResistance.class)); - cards.add(new SetCardInfo("Goblin Balloon Brigade", 159, Rarity.COMMON, mage.cards.g.GoblinBalloonBrigade.class)); - cards.add(new SetCardInfo("Goblin Tunneler", 160, Rarity.COMMON, mage.cards.g.GoblinTunneler.class)); - cards.add(new SetCardInfo("Gods Willing", 88, Rarity.COMMON, mage.cards.g.GodsWilling.class)); - cards.add(new SetCardInfo("Gratuitous Violence", 161, Rarity.RARE, mage.cards.g.GratuitousViolence.class)); - cards.add(new SetCardInfo("Gruul War Chant", 203, Rarity.UNCOMMON, mage.cards.g.GruulWarChant.class)); - cards.add(new SetCardInfo("Guardian of the Gateless", 89, Rarity.UNCOMMON, mage.cards.g.GuardianOfTheGateless.class)); - cards.add(new SetCardInfo("Guttersnipe", 162, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class)); - cards.add(new SetCardInfo("Guul Draz Specter", 137, Rarity.RARE, mage.cards.g.GuulDrazSpecter.class)); - cards.add(new SetCardInfo("Hail of Arrows", 90, Rarity.UNCOMMON, mage.cards.h.HailOfArrows.class)); - cards.add(new SetCardInfo("Hallowed Burial", 91, Rarity.RARE, mage.cards.h.HallowedBurial.class)); - cards.add(new SetCardInfo("Hamletback Goliath", 163, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); - cards.add(new SetCardInfo("Harvester of Souls", 138, Rarity.RARE, mage.cards.h.HarvesterOfSouls.class)); - cards.add(new SetCardInfo("Havengul Vampire", 164, Rarity.UNCOMMON, mage.cards.h.HavengulVampire.class)); - cards.add(new SetCardInfo("Hedron Matrix", 209, Rarity.RARE, mage.cards.h.HedronMatrix.class)); - cards.add(new SetCardInfo("Hexplate Golem", 210, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); - cards.add(new SetCardInfo("Hollowhenge Spirit", 92, Rarity.UNCOMMON, mage.cards.h.HollowhengeSpirit.class)); - cards.add(new SetCardInfo("Horn of Greed", 211, Rarity.RARE, mage.cards.h.HornOfGreed.class)); - cards.add(new SetCardInfo("Hundred-Handed One", 93, Rarity.RARE, mage.cards.h.HundredHandedOne.class)); - cards.add(new SetCardInfo("Hurly-Burly", 165, Rarity.COMMON, mage.cards.h.HurlyBurly.class)); - cards.add(new SetCardInfo("Ill-Tempered Cyclops", 166, Rarity.COMMON, mage.cards.i.IllTemperedCyclops.class)); - cards.add(new SetCardInfo("Infest", 139, Rarity.UNCOMMON, mage.cards.i.Infest.class)); - cards.add(new SetCardInfo("Inquisition of Kozilek", 140, Rarity.RARE, mage.cards.i.InquisitionOfKozilek.class)); - cards.add(new SetCardInfo("Into the Void", 112, Rarity.UNCOMMON, mage.cards.i.IntoTheVoid.class)); - cards.add(new SetCardInfo("Irresistible Prey", 183, Rarity.UNCOMMON, mage.cards.i.IrresistiblePrey.class)); - cards.add(new SetCardInfo("Juniper Order Ranger", 204, Rarity.UNCOMMON, mage.cards.j.JuniperOrderRanger.class)); - cards.add(new SetCardInfo("Kami of the Crescent Moon", 113, Rarity.RARE, mage.cards.k.KamiOfTheCrescentMoon.class)); - cards.add(new SetCardInfo("Kaya, Ghost Assassin", 75, Rarity.MYTHIC, mage.cards.k.KayaGhostAssassin.class)); - cards.add(new SetCardInfo("Keeper of Keys", 34, Rarity.RARE, mage.cards.k.KeeperOfKeys.class)); - cards.add(new SetCardInfo("Keepsake Gorgon", 141, Rarity.UNCOMMON, mage.cards.k.KeepsakeGorgon.class)); - cards.add(new SetCardInfo("Kill Shot", 94, Rarity.COMMON, mage.cards.k.KillShot.class)); - cards.add(new SetCardInfo("Kiln Fiend", 167, Rarity.COMMON, mage.cards.k.KilnFiend.class)); - cards.add(new SetCardInfo("Kitesail", 212, Rarity.COMMON, mage.cards.k.Kitesail.class)); - cards.add(new SetCardInfo("Knights of the Black Rose", 76, Rarity.UNCOMMON, mage.cards.k.KnightsOfTheBlackRose.class)); - cards.add(new SetCardInfo("Lace with Moonglove", 184, Rarity.COMMON, mage.cards.l.LaceWithMoonglove.class)); - cards.add(new SetCardInfo("Lay of the Land", 185, Rarity.COMMON, mage.cards.l.LayOfTheLand.class)); - cards.add(new SetCardInfo("Leovold, Emissary of Trest", 77, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); - cards.add(new SetCardInfo("Lieutenants of the Guard", 16, Rarity.COMMON, mage.cards.l.LieutenantsOfTheGuard.class)); - cards.add(new SetCardInfo("Manaplasm", 186, Rarity.UNCOMMON, mage.cards.m.Manaplasm.class)); - cards.add(new SetCardInfo("Marchesa's Decree", 44, Rarity.UNCOMMON, mage.cards.m.MarchesasDecree.class)); - cards.add(new SetCardInfo("Menagerie Liberator", 67, Rarity.COMMON, mage.cards.m.MenagerieLiberator.class)); - cards.add(new SetCardInfo("Merfolk Looter", 114, Rarity.UNCOMMON, mage.cards.m.MerfolkLooter.class)); - cards.add(new SetCardInfo("Merfolk Skyscout", 115, Rarity.UNCOMMON, mage.cards.m.MerfolkSkyscout.class)); - cards.add(new SetCardInfo("Messenger Jays", 35, Rarity.COMMON, mage.cards.m.MessengerJays.class)); - cards.add(new SetCardInfo("Mnemonic Wall", 116, Rarity.COMMON, mage.cards.m.MnemonicWall.class)); - cards.add(new SetCardInfo("Murder", 143, Rarity.COMMON, mage.cards.m.Murder.class)); - cards.add(new SetCardInfo("Negate", 117, Rarity.COMMON, mage.cards.n.Negate.class)); - cards.add(new SetCardInfo("Nessian Asp", 187, Rarity.COMMON, mage.cards.n.NessianAsp.class)); - cards.add(new SetCardInfo("Netcaster Spider", 188, Rarity.COMMON, mage.cards.n.NetcasterSpider.class)); - cards.add(new SetCardInfo("Ogre Sentry", 168, Rarity.COMMON, mage.cards.o.OgreSentry.class)); - cards.add(new SetCardInfo("Omenspeaker", 118, Rarity.COMMON, mage.cards.o.Omenspeaker.class)); - cards.add(new SetCardInfo("Opaline Unicorn", 213, Rarity.COMMON, mage.cards.o.OpalineUnicorn.class)); - cards.add(new SetCardInfo("Orchard Elemental", 68, Rarity.COMMON, mage.cards.o.OrchardElemental.class)); - cards.add(new SetCardInfo("Overrun", 189, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); - cards.add(new SetCardInfo("Palace Jailer", 18, Rarity.UNCOMMON, mage.cards.p.PalaceJailer.class)); - cards.add(new SetCardInfo("Palace Sentinels", 19, Rarity.COMMON, mage.cards.p.PalaceSentinels.class)); - cards.add(new SetCardInfo("Pariah", 95, Rarity.RARE, mage.cards.p.Pariah.class)); - cards.add(new SetCardInfo("Pharika's Mender", 205, Rarity.UNCOMMON, mage.cards.p.PharikasMender.class)); - cards.add(new SetCardInfo("Phyrexian Arena", 144, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); - cards.add(new SetCardInfo("Platinum Angel", 214, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class)); - cards.add(new SetCardInfo("Plummet", 190, Rarity.COMMON, mage.cards.p.Plummet.class)); - cards.add(new SetCardInfo("Prey Upon", 191, Rarity.COMMON, mage.cards.p.PreyUpon.class)); - cards.add(new SetCardInfo("Protector of the Crown", 21, Rarity.RARE, mage.cards.p.ProtectorOfTheCrown.class)); - cards.add(new SetCardInfo("Psychosis Crawler", 215, Rarity.RARE, mage.cards.p.PsychosisCrawler.class)); - cards.add(new SetCardInfo("Public Execution", 145, Rarity.UNCOMMON, mage.cards.p.PublicExecution.class)); - cards.add(new SetCardInfo("Queen Marchesa", 78, Rarity.MYTHIC, mage.cards.q.QueenMarchesa.class)); - cards.add(new SetCardInfo("Raise Dead", 146, Rarity.COMMON, mage.cards.r.RaiseDead.class)); - cards.add(new SetCardInfo("Raise the Alarm", 96, Rarity.COMMON, mage.cards.r.RaiseTheAlarm.class)); - cards.add(new SetCardInfo("Ravenous Leucrocota", 192, Rarity.COMMON, mage.cards.r.RavenousLeucrocota.class)); - cards.add(new SetCardInfo("Recruiter of the Guard", 22, Rarity.RARE, mage.cards.r.RecruiterOfTheGuard.class)); - cards.add(new SetCardInfo("Regal Behemoth", 69, Rarity.RARE, mage.cards.r.RegalBehemoth.class)); - cards.add(new SetCardInfo("Repulse", 119, Rarity.COMMON, mage.cards.r.Repulse.class)); - cards.add(new SetCardInfo("Reviving Dose", 97, Rarity.COMMON, mage.cards.r.RevivingDose.class)); - cards.add(new SetCardInfo("Rogue's Passage", 220, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); - cards.add(new SetCardInfo("Runed Servitor", 216, Rarity.UNCOMMON, mage.cards.r.RunedServitor.class)); - cards.add(new SetCardInfo("Sanctum Prelate", 23, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); - cards.add(new SetCardInfo("Sangromancer", 147, Rarity.RARE, mage.cards.s.Sangromancer.class)); - cards.add(new SetCardInfo("Selvala's Stampede", 71, Rarity.RARE, mage.cards.s.SelvalasStampede.class)); - cards.add(new SetCardInfo("Selvala, Heart of the Wilds", 70, Rarity.MYTHIC, mage.cards.s.SelvalaHeartOfTheWilds.class)); - cards.add(new SetCardInfo("Serum Visions", 120, Rarity.UNCOMMON, mage.cards.s.SerumVisions.class)); - cards.add(new SetCardInfo("Shambling Goblin", 148, Rarity.COMMON, mage.cards.s.ShamblingGoblin.class)); - cards.add(new SetCardInfo("Shimmering Grotto", 221, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class)); - cards.add(new SetCardInfo("Shipwreck Singer", 206, Rarity.UNCOMMON, mage.cards.s.ShipwreckSinger.class)); - cards.add(new SetCardInfo("Show and Tell", 121, Rarity.MYTHIC, mage.cards.s.ShowAndTell.class)); - cards.add(new SetCardInfo("Sinuous Vermin", 46, Rarity.COMMON, mage.cards.s.SinuousVermin.class)); - cards.add(new SetCardInfo("Skittering Crustacean", 36, Rarity.COMMON, mage.cards.s.SkitteringCrustacean.class)); - cards.add(new SetCardInfo("Skyline Despot", 57, Rarity.RARE, mage.cards.s.SkylineDespot.class)); - cards.add(new SetCardInfo("Spectral Grasp", 24, Rarity.UNCOMMON, mage.cards.s.SpectralGrasp.class)); - cards.add(new SetCardInfo("Sphinx of Magosi", 122, Rarity.RARE, mage.cards.s.SphinxOfMagosi.class)); - cards.add(new SetCardInfo("Spirit of the Hearth", 98, Rarity.RARE, mage.cards.s.SpiritOfTheHearth.class)); - cards.add(new SetCardInfo("Splitting Slime", 72, Rarity.RARE, mage.cards.s.SplittingSlime.class)); - cards.add(new SetCardInfo("Stoneshock Giant", 169, Rarity.UNCOMMON, mage.cards.s.StoneshockGiant.class)); - cards.add(new SetCardInfo("Stormchaser Chimera", 207, Rarity.UNCOMMON, mage.cards.s.StormchaserChimera.class)); - cards.add(new SetCardInfo("Strength in Numbers", 193, Rarity.COMMON, mage.cards.s.StrengthInNumbers.class)); - cards.add(new SetCardInfo("Stromkirk Patrol", 149, Rarity.COMMON, mage.cards.s.StromkirkPatrol.class)); - cards.add(new SetCardInfo("Stunt Double", 38, Rarity.RARE, mage.cards.s.StuntDouble.class)); - cards.add(new SetCardInfo("Subterranean Tremors", 58, Rarity.MYTHIC, mage.cards.s.SubterraneanTremors.class)); - cards.add(new SetCardInfo("Sulfurous Blast", 170, Rarity.UNCOMMON, mage.cards.s.SulfurousBlast.class)); - cards.add(new SetCardInfo("Sylvan Bounty", 194, Rarity.COMMON, mage.cards.s.SylvanBounty.class)); - cards.add(new SetCardInfo("Thorn of the Black Rose", 48, Rarity.COMMON, mage.cards.t.ThornOfTheBlackRose.class)); - cards.add(new SetCardInfo("Throne Warden", 25, Rarity.COMMON, mage.cards.t.ThroneWarden.class)); - cards.add(new SetCardInfo("Throne of the High City", 80, Rarity.RARE, mage.cards.t.ThroneOfTheHighCity.class)); - cards.add(new SetCardInfo("Tormenting Voice", 171, Rarity.COMMON, mage.cards.t.TormentingVoice.class)); - cards.add(new SetCardInfo("Traumatic Visions", 123, Rarity.COMMON, mage.cards.t.TraumaticVisions.class)); - cards.add(new SetCardInfo("Trumpet Blast", 172, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); - cards.add(new SetCardInfo("Twin Bolt", 173, Rarity.COMMON, mage.cards.t.TwinBolt.class)); - cards.add(new SetCardInfo("Unnerve", 150, Rarity.COMMON, mage.cards.u.Unnerve.class)); - cards.add(new SetCardInfo("Vaporkin", 124, Rarity.COMMON, mage.cards.v.Vaporkin.class)); - cards.add(new SetCardInfo("Vertigo Spawn", 125, Rarity.UNCOMMON, mage.cards.v.VertigoSpawn.class)); - cards.add(new SetCardInfo("Voyaging Satyr", 195, Rarity.COMMON, mage.cards.v.VoyagingSatyr.class)); - cards.add(new SetCardInfo("Wild Griffin", 99, Rarity.COMMON, mage.cards.w.WildGriffin.class)); - cards.add(new SetCardInfo("Wild Pair", 196, Rarity.RARE, mage.cards.w.WildPair.class)); - cards.add(new SetCardInfo("Windborne Charge", 100, Rarity.UNCOMMON, mage.cards.w.WindborneCharge.class)); - cards.add(new SetCardInfo("Wings of the Guard", 26, Rarity.COMMON, mage.cards.w.WingsOfTheGuard.class)); - cards.add(new SetCardInfo("Zealous Strike", 101, Rarity.COMMON, mage.cards.z.ZealousStrike.class)); - } - -} +/* +* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, are +* permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, this list of +* conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, this list +* of conditions and the following disclaimer in the documentation and/or other materials +* provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* The views and conclusions contained in the software and documentation are those of the +* authors and should not be interpreted as representing official policies, either expressed +* or implied, of BetaSteward_at_googlemail.com. +*/ + +package mage.sets; + +import mage.cards.ExpansionSet; +import mage.constants.SetType; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ + +public class ConspiracyTakeTheCrown extends ExpansionSet { + + private static final ConspiracyTakeTheCrown fINSTANCE = new ConspiracyTakeTheCrown(); + + public static ConspiracyTakeTheCrown getInstance() { + return fINSTANCE; + } + + private ConspiracyTakeTheCrown() { + super("Conspiracy: Take the Crown", "CN2", ExpansionSet.buildDate(2016, 8, 26), SetType.SUPPLEMENTAL); + this.blockName = "Conspiracy"; + this.hasBasicLands = false; + this.hasBoosters = true; + this.numBoosterLands = 0; + this.numBoosterCommon = 11; + this.numBoosterUncommon = 3; + this.numBoosterRare = 1; + this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Absorb Vis", 126, Rarity.COMMON, mage.cards.a.AbsorbVis.class)); + cards.add(new SetCardInfo("Adriana, Captain of the Guard", 73, Rarity.RARE, mage.cards.a.AdrianaCaptainOfTheGuard.class)); + cards.add(new SetCardInfo("Affa Guard Hound", 81, Rarity.UNCOMMON, mage.cards.a.AffaGuardHound.class)); + cards.add(new SetCardInfo("Akroan Hoplite", 197, Rarity.UNCOMMON, mage.cards.a.AkroanHoplite.class)); + cards.add(new SetCardInfo("Altar's Reap", 127, Rarity.COMMON, mage.cards.a.AltarsReap.class)); + cards.add(new SetCardInfo("Ascended Lawmage", 198, Rarity.UNCOMMON, mage.cards.a.AscendedLawmage.class)); + cards.add(new SetCardInfo("Avatar of Woe", 128, Rarity.MYTHIC, mage.cards.a.AvatarOfWoe.class)); + cards.add(new SetCardInfo("Beast Within", 174, Rarity.UNCOMMON, mage.cards.b.BeastWithin.class)); + cards.add(new SetCardInfo("Berserk", 175, Rarity.MYTHIC, mage.cards.b.Berserk.class)); + cards.add(new SetCardInfo("Birds of Paradise", 176, Rarity.RARE, mage.cards.b.BirdsOfParadise.class)); + cards.add(new SetCardInfo("Blood-Toll Harpy", 129, Rarity.COMMON, mage.cards.b.BloodTollHarpy.class)); + cards.add(new SetCardInfo("Bonds of Quicksilver", 102, Rarity.COMMON, mage.cards.b.BondsOfQuicksilver.class)); + cards.add(new SetCardInfo("Borderland Explorer", 61, Rarity.COMMON, mage.cards.b.BorderlandExplorer.class)); + cards.add(new SetCardInfo("Bronze Sable", 208, Rarity.COMMON, mage.cards.b.BronzeSable.class)); + cards.add(new SetCardInfo("Brushstrider", 177, Rarity.UNCOMMON, mage.cards.b.Brushstrider.class)); + cards.add(new SetCardInfo("Burgeoning", 178, Rarity.RARE, mage.cards.b.Burgeoning.class)); + cards.add(new SetCardInfo("Burn Away", 151, Rarity.UNCOMMON, mage.cards.b.BurnAway.class)); + cards.add(new SetCardInfo("Burning Wish", 152, Rarity.RARE, mage.cards.b.BurningWish.class)); + cards.add(new SetCardInfo("Caller of Gales", 103, Rarity.COMMON, mage.cards.c.CallerOfGales.class)); + cards.add(new SetCardInfo("Canal Courier", 28, Rarity.COMMON, mage.cards.c.CanalCourier.class)); + cards.add(new SetCardInfo("Capital Punishment", 40, Rarity.RARE, mage.cards.c.CapitalPunishment.class)); + cards.add(new SetCardInfo("Carnage Gladiator", 199, Rarity.UNCOMMON, mage.cards.c.CarnageGladiator.class)); + cards.add(new SetCardInfo("Charmbreaker Devils", 153, Rarity.RARE, mage.cards.c.CharmbreakerDevils.class)); + cards.add(new SetCardInfo("Child of Night", 130, Rarity.COMMON, mage.cards.c.ChildOfNight.class)); + cards.add(new SetCardInfo("Cloaked Siren", 104, Rarity.COMMON, mage.cards.c.CloakedSiren.class)); + cards.add(new SetCardInfo("Coiling Oracle", 200, Rarity.UNCOMMON, mage.cards.c.CoilingOracle.class)); + cards.add(new SetCardInfo("Coordinated Assault", 154, Rarity.UNCOMMON, mage.cards.c.CoordinatedAssault.class)); + cards.add(new SetCardInfo("Copperhorn Scout", 179, Rarity.COMMON, mage.cards.c.CopperhornScout.class)); + cards.add(new SetCardInfo("Covenant of Minds", 105, Rarity.RARE, mage.cards.c.CovenantOfMinds.class)); + cards.add(new SetCardInfo("Crown-Hunter Hireling", 50, Rarity.COMMON, mage.cards.c.CrownHunterHireling.class)); + cards.add(new SetCardInfo("Custodi Lich", 41, Rarity.RARE, mage.cards.c.CustodiLich.class)); + cards.add(new SetCardInfo("Daretti, Ingenious Iconoclast", 74, Rarity.MYTHIC, mage.cards.d.DarettiIngeniousIconoclast.class)); + cards.add(new SetCardInfo("Deadly Designs", 42, Rarity.UNCOMMON, mage.cards.d.DeadlyDesigns.class)); + cards.add(new SetCardInfo("Death Wind", 131, Rarity.COMMON, mage.cards.d.DeathWind.class)); + cards.add(new SetCardInfo("Deceiver Exarch", 106, Rarity.UNCOMMON, mage.cards.d.DeceiverExarch.class)); + cards.add(new SetCardInfo("Deputized Protester", 51, Rarity.COMMON, mage.cards.d.DeputizedProtester.class)); + cards.add(new SetCardInfo("Desertion", 107, Rarity.RARE, mage.cards.d.Desertion.class)); + cards.add(new SetCardInfo("Diabolic Tutor", 132, Rarity.UNCOMMON, mage.cards.d.DiabolicTutor.class)); + cards.add(new SetCardInfo("Disenchant", 82, Rarity.COMMON, mage.cards.d.Disenchant.class)); + cards.add(new SetCardInfo("Dismiss", 108, Rarity.UNCOMMON, mage.cards.d.Dismiss.class)); + cards.add(new SetCardInfo("Divination", 109, Rarity.COMMON, mage.cards.d.Divination.class)); + cards.add(new SetCardInfo("Domesticated Hydra", 63, Rarity.UNCOMMON, mage.cards.d.DomesticatedHydra.class)); + cards.add(new SetCardInfo("Doomed Traveler", 83, Rarity.COMMON, mage.cards.d.DoomedTraveler.class)); + cards.add(new SetCardInfo("Dragonlair Spider", 201, Rarity.RARE, mage.cards.d.DragonlairSpider.class)); + cards.add(new SetCardInfo("Dread Statuary", 217, Rarity.UNCOMMON, mage.cards.d.DreadStatuary.class)); + cards.add(new SetCardInfo("Driver of the Dead", 133, Rarity.COMMON, mage.cards.d.DriverOfTheDead.class)); + cards.add(new SetCardInfo("Duskmantle Seer", 202, Rarity.RARE, mage.cards.d.DuskmantleSeer.class)); + cards.add(new SetCardInfo("Ember Beast", 155, Rarity.COMMON, mage.cards.e.EmberBeast.class)); + cards.add(new SetCardInfo("Entourage of Trest", 64, Rarity.COMMON, mage.cards.e.EntourageOfTrest.class)); + cards.add(new SetCardInfo("Evolving Wilds", 218, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); + cards.add(new SetCardInfo("Exotic Orchard", 219, Rarity.RARE, mage.cards.e.ExoticOrchard.class)); + cards.add(new SetCardInfo("Explosive Vegetation", 180, Rarity.UNCOMMON, mage.cards.e.ExplosiveVegetation.class)); + cards.add(new SetCardInfo("Expropriate", 30, Rarity.MYTHIC, mage.cards.e.Expropriate.class)); + cards.add(new SetCardInfo("Fade into Antiquity", 181, Rarity.COMMON, mage.cards.f.FadeIntoAntiquity.class)); + cards.add(new SetCardInfo("Faith's Reward", 84, Rarity.RARE, mage.cards.f.FaithsReward.class)); + cards.add(new SetCardInfo("Fang of the Pack", 65, Rarity.UNCOMMON, mage.cards.f.FangOfThePack.class)); + cards.add(new SetCardInfo("Farbog Boneflinger", 134, Rarity.UNCOMMON, mage.cards.f.FarbogBoneflinger.class)); + cards.add(new SetCardInfo("Festergloom", 135, Rarity.COMMON, mage.cards.f.Festergloom.class)); + cards.add(new SetCardInfo("Fiery Fall", 156, Rarity.COMMON, mage.cards.f.FieryFall.class)); + cards.add(new SetCardInfo("Flame Slash", 157, Rarity.COMMON, mage.cards.f.FlameSlash.class)); + cards.add(new SetCardInfo("Fleeting Distraction", 110, Rarity.COMMON, mage.cards.f.FleetingDistraction.class)); + cards.add(new SetCardInfo("Fleshbag Marauder", 136, Rarity.UNCOMMON, mage.cards.f.FleshbagMarauder.class)); + cards.add(new SetCardInfo("Followed Footsteps", 111, Rarity.RARE, mage.cards.f.FollowedFootsteps.class)); + cards.add(new SetCardInfo("Forgotten Ancient", 182, Rarity.RARE, mage.cards.f.ForgottenAncient.class)); + cards.add(new SetCardInfo("Gang of Devils", 158, Rarity.UNCOMMON, mage.cards.g.GangOfDevils.class)); + cards.add(new SetCardInfo("Garrulous Sycophant", 43, Rarity.COMMON, mage.cards.g.GarrulousSycophant.class)); + cards.add(new SetCardInfo("Ghostly Possession", 85, Rarity.COMMON, mage.cards.g.GhostlyPossession.class)); + cards.add(new SetCardInfo("Ghostly Prison", 86, Rarity.UNCOMMON, mage.cards.g.GhostlyPrison.class)); + cards.add(new SetCardInfo("Gleam of Resistance", 87, Rarity.COMMON, mage.cards.g.GleamOfResistance.class)); + cards.add(new SetCardInfo("Goblin Balloon Brigade", 159, Rarity.COMMON, mage.cards.g.GoblinBalloonBrigade.class)); + cards.add(new SetCardInfo("Goblin Tunneler", 160, Rarity.COMMON, mage.cards.g.GoblinTunneler.class)); + cards.add(new SetCardInfo("Gods Willing", 88, Rarity.COMMON, mage.cards.g.GodsWilling.class)); + cards.add(new SetCardInfo("Gratuitous Violence", 161, Rarity.RARE, mage.cards.g.GratuitousViolence.class)); + cards.add(new SetCardInfo("Gruul War Chant", 203, Rarity.UNCOMMON, mage.cards.g.GruulWarChant.class)); + cards.add(new SetCardInfo("Guardian of the Gateless", 89, Rarity.UNCOMMON, mage.cards.g.GuardianOfTheGateless.class)); + cards.add(new SetCardInfo("Guttersnipe", 162, Rarity.UNCOMMON, mage.cards.g.Guttersnipe.class)); + cards.add(new SetCardInfo("Guul Draz Specter", 137, Rarity.RARE, mage.cards.g.GuulDrazSpecter.class)); + cards.add(new SetCardInfo("Hail of Arrows", 90, Rarity.UNCOMMON, mage.cards.h.HailOfArrows.class)); + cards.add(new SetCardInfo("Hallowed Burial", 91, Rarity.RARE, mage.cards.h.HallowedBurial.class)); + cards.add(new SetCardInfo("Hamletback Goliath", 163, Rarity.RARE, mage.cards.h.HamletbackGoliath.class)); + cards.add(new SetCardInfo("Harvester of Souls", 138, Rarity.RARE, mage.cards.h.HarvesterOfSouls.class)); + cards.add(new SetCardInfo("Havengul Vampire", 164, Rarity.UNCOMMON, mage.cards.h.HavengulVampire.class)); + cards.add(new SetCardInfo("Hedron Matrix", 209, Rarity.RARE, mage.cards.h.HedronMatrix.class)); + cards.add(new SetCardInfo("Hexplate Golem", 210, Rarity.COMMON, mage.cards.h.HexplateGolem.class)); + cards.add(new SetCardInfo("Hollowhenge Spirit", 92, Rarity.UNCOMMON, mage.cards.h.HollowhengeSpirit.class)); + cards.add(new SetCardInfo("Horn of Greed", 211, Rarity.RARE, mage.cards.h.HornOfGreed.class)); + cards.add(new SetCardInfo("Hundred-Handed One", 93, Rarity.RARE, mage.cards.h.HundredHandedOne.class)); + cards.add(new SetCardInfo("Hurly-Burly", 165, Rarity.COMMON, mage.cards.h.HurlyBurly.class)); + cards.add(new SetCardInfo("Ill-Tempered Cyclops", 166, Rarity.COMMON, mage.cards.i.IllTemperedCyclops.class)); + cards.add(new SetCardInfo("Infest", 139, Rarity.UNCOMMON, mage.cards.i.Infest.class)); + cards.add(new SetCardInfo("Inquisition of Kozilek", 140, Rarity.RARE, mage.cards.i.InquisitionOfKozilek.class)); + cards.add(new SetCardInfo("Into the Void", 112, Rarity.UNCOMMON, mage.cards.i.IntoTheVoid.class)); + cards.add(new SetCardInfo("Irresistible Prey", 183, Rarity.UNCOMMON, mage.cards.i.IrresistiblePrey.class)); + cards.add(new SetCardInfo("Juniper Order Ranger", 204, Rarity.UNCOMMON, mage.cards.j.JuniperOrderRanger.class)); + cards.add(new SetCardInfo("Kami of the Crescent Moon", 113, Rarity.RARE, mage.cards.k.KamiOfTheCrescentMoon.class)); + cards.add(new SetCardInfo("Kaya, Ghost Assassin", 75, Rarity.MYTHIC, mage.cards.k.KayaGhostAssassin.class)); + cards.add(new SetCardInfo("Keeper of Keys", 34, Rarity.RARE, mage.cards.k.KeeperOfKeys.class)); + cards.add(new SetCardInfo("Keepsake Gorgon", 141, Rarity.UNCOMMON, mage.cards.k.KeepsakeGorgon.class)); + cards.add(new SetCardInfo("Kill Shot", 94, Rarity.COMMON, mage.cards.k.KillShot.class)); + cards.add(new SetCardInfo("Kiln Fiend", 167, Rarity.COMMON, mage.cards.k.KilnFiend.class)); + cards.add(new SetCardInfo("Kitesail", 212, Rarity.COMMON, mage.cards.k.Kitesail.class)); + cards.add(new SetCardInfo("Knights of the Black Rose", 76, Rarity.UNCOMMON, mage.cards.k.KnightsOfTheBlackRose.class)); + cards.add(new SetCardInfo("Lace with Moonglove", 184, Rarity.COMMON, mage.cards.l.LaceWithMoonglove.class)); + cards.add(new SetCardInfo("Lay of the Land", 185, Rarity.COMMON, mage.cards.l.LayOfTheLand.class)); + cards.add(new SetCardInfo("Leovold, Emissary of Trest", 77, Rarity.MYTHIC, mage.cards.l.LeovoldEmissaryOfTrest.class)); + cards.add(new SetCardInfo("Lieutenants of the Guard", 16, Rarity.COMMON, mage.cards.l.LieutenantsOfTheGuard.class)); + cards.add(new SetCardInfo("Manaplasm", 186, Rarity.UNCOMMON, mage.cards.m.Manaplasm.class)); + cards.add(new SetCardInfo("Marchesa's Decree", 44, Rarity.UNCOMMON, mage.cards.m.MarchesasDecree.class)); + cards.add(new SetCardInfo("Menagerie Liberator", 67, Rarity.COMMON, mage.cards.m.MenagerieLiberator.class)); + cards.add(new SetCardInfo("Merfolk Looter", 114, Rarity.UNCOMMON, mage.cards.m.MerfolkLooter.class)); + cards.add(new SetCardInfo("Merfolk Skyscout", 115, Rarity.UNCOMMON, mage.cards.m.MerfolkSkyscout.class)); + cards.add(new SetCardInfo("Messenger Jays", 35, Rarity.COMMON, mage.cards.m.MessengerJays.class)); + cards.add(new SetCardInfo("Mnemonic Wall", 116, Rarity.COMMON, mage.cards.m.MnemonicWall.class)); + cards.add(new SetCardInfo("Murder", 143, Rarity.COMMON, mage.cards.m.Murder.class)); + cards.add(new SetCardInfo("Negate", 117, Rarity.COMMON, mage.cards.n.Negate.class)); + cards.add(new SetCardInfo("Nessian Asp", 187, Rarity.COMMON, mage.cards.n.NessianAsp.class)); + cards.add(new SetCardInfo("Netcaster Spider", 188, Rarity.COMMON, mage.cards.n.NetcasterSpider.class)); + cards.add(new SetCardInfo("Ogre Sentry", 168, Rarity.COMMON, mage.cards.o.OgreSentry.class)); + cards.add(new SetCardInfo("Omenspeaker", 118, Rarity.COMMON, mage.cards.o.Omenspeaker.class)); + cards.add(new SetCardInfo("Opaline Unicorn", 213, Rarity.COMMON, mage.cards.o.OpalineUnicorn.class)); + cards.add(new SetCardInfo("Orchard Elemental", 68, Rarity.COMMON, mage.cards.o.OrchardElemental.class)); + cards.add(new SetCardInfo("Overrun", 189, Rarity.UNCOMMON, mage.cards.o.Overrun.class)); + cards.add(new SetCardInfo("Palace Jailer", 18, Rarity.UNCOMMON, mage.cards.p.PalaceJailer.class)); + cards.add(new SetCardInfo("Palace Sentinels", 19, Rarity.COMMON, mage.cards.p.PalaceSentinels.class)); + cards.add(new SetCardInfo("Pariah", 95, Rarity.RARE, mage.cards.p.Pariah.class)); + cards.add(new SetCardInfo("Pharika's Mender", 205, Rarity.UNCOMMON, mage.cards.p.PharikasMender.class)); + cards.add(new SetCardInfo("Phyrexian Arena", 144, Rarity.RARE, mage.cards.p.PhyrexianArena.class)); + cards.add(new SetCardInfo("Platinum Angel", 214, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class)); + cards.add(new SetCardInfo("Plummet", 190, Rarity.COMMON, mage.cards.p.Plummet.class)); + cards.add(new SetCardInfo("Prey Upon", 191, Rarity.COMMON, mage.cards.p.PreyUpon.class)); + cards.add(new SetCardInfo("Protector of the Crown", 21, Rarity.RARE, mage.cards.p.ProtectorOfTheCrown.class)); + cards.add(new SetCardInfo("Psychosis Crawler", 215, Rarity.RARE, mage.cards.p.PsychosisCrawler.class)); + cards.add(new SetCardInfo("Public Execution", 145, Rarity.UNCOMMON, mage.cards.p.PublicExecution.class)); + cards.add(new SetCardInfo("Queen Marchesa", 78, Rarity.MYTHIC, mage.cards.q.QueenMarchesa.class)); + cards.add(new SetCardInfo("Raise Dead", 146, Rarity.COMMON, mage.cards.r.RaiseDead.class)); + cards.add(new SetCardInfo("Raise the Alarm", 96, Rarity.COMMON, mage.cards.r.RaiseTheAlarm.class)); + cards.add(new SetCardInfo("Ravenous Leucrocota", 192, Rarity.COMMON, mage.cards.r.RavenousLeucrocota.class)); + cards.add(new SetCardInfo("Recruiter of the Guard", 22, Rarity.RARE, mage.cards.r.RecruiterOfTheGuard.class)); + cards.add(new SetCardInfo("Regal Behemoth", 69, Rarity.RARE, mage.cards.r.RegalBehemoth.class)); + cards.add(new SetCardInfo("Repulse", 119, Rarity.COMMON, mage.cards.r.Repulse.class)); + cards.add(new SetCardInfo("Reviving Dose", 97, Rarity.COMMON, mage.cards.r.RevivingDose.class)); + cards.add(new SetCardInfo("Rogue's Passage", 220, Rarity.UNCOMMON, mage.cards.r.RoguesPassage.class)); + cards.add(new SetCardInfo("Runed Servitor", 216, Rarity.UNCOMMON, mage.cards.r.RunedServitor.class)); + cards.add(new SetCardInfo("Sanctum Prelate", 23, Rarity.MYTHIC, mage.cards.s.SanctumPrelate.class)); + cards.add(new SetCardInfo("Sangromancer", 147, Rarity.RARE, mage.cards.s.Sangromancer.class)); + cards.add(new SetCardInfo("Selvala's Stampede", 71, Rarity.RARE, mage.cards.s.SelvalasStampede.class)); + cards.add(new SetCardInfo("Selvala, Heart of the Wilds", 70, Rarity.MYTHIC, mage.cards.s.SelvalaHeartOfTheWilds.class)); + cards.add(new SetCardInfo("Serum Visions", 120, Rarity.UNCOMMON, mage.cards.s.SerumVisions.class)); + cards.add(new SetCardInfo("Shambling Goblin", 148, Rarity.COMMON, mage.cards.s.ShamblingGoblin.class)); + cards.add(new SetCardInfo("Shimmering Grotto", 221, Rarity.COMMON, mage.cards.s.ShimmeringGrotto.class)); + cards.add(new SetCardInfo("Shipwreck Singer", 206, Rarity.UNCOMMON, mage.cards.s.ShipwreckSinger.class)); + cards.add(new SetCardInfo("Show and Tell", 121, Rarity.MYTHIC, mage.cards.s.ShowAndTell.class)); + cards.add(new SetCardInfo("Sinuous Vermin", 46, Rarity.COMMON, mage.cards.s.SinuousVermin.class)); + cards.add(new SetCardInfo("Skittering Crustacean", 36, Rarity.COMMON, mage.cards.s.SkitteringCrustacean.class)); + cards.add(new SetCardInfo("Skyline Despot", 57, Rarity.RARE, mage.cards.s.SkylineDespot.class)); + cards.add(new SetCardInfo("Spectral Grasp", 24, Rarity.UNCOMMON, mage.cards.s.SpectralGrasp.class)); + cards.add(new SetCardInfo("Sphinx of Magosi", 122, Rarity.RARE, mage.cards.s.SphinxOfMagosi.class)); + cards.add(new SetCardInfo("Spirit of the Hearth", 98, Rarity.RARE, mage.cards.s.SpiritOfTheHearth.class)); + cards.add(new SetCardInfo("Splitting Slime", 72, Rarity.RARE, mage.cards.s.SplittingSlime.class)); + cards.add(new SetCardInfo("Stoneshock Giant", 169, Rarity.UNCOMMON, mage.cards.s.StoneshockGiant.class)); + cards.add(new SetCardInfo("Stormchaser Chimera", 207, Rarity.UNCOMMON, mage.cards.s.StormchaserChimera.class)); + cards.add(new SetCardInfo("Strength in Numbers", 193, Rarity.COMMON, mage.cards.s.StrengthInNumbers.class)); + cards.add(new SetCardInfo("Stromkirk Patrol", 149, Rarity.COMMON, mage.cards.s.StromkirkPatrol.class)); + cards.add(new SetCardInfo("Stunt Double", 38, Rarity.RARE, mage.cards.s.StuntDouble.class)); + cards.add(new SetCardInfo("Subterranean Tremors", 58, Rarity.MYTHIC, mage.cards.s.SubterraneanTremors.class)); + cards.add(new SetCardInfo("Sulfurous Blast", 170, Rarity.UNCOMMON, mage.cards.s.SulfurousBlast.class)); + cards.add(new SetCardInfo("Sylvan Bounty", 194, Rarity.COMMON, mage.cards.s.SylvanBounty.class)); + cards.add(new SetCardInfo("Thorn of the Black Rose", 48, Rarity.COMMON, mage.cards.t.ThornOfTheBlackRose.class)); + cards.add(new SetCardInfo("Throne Warden", 25, Rarity.COMMON, mage.cards.t.ThroneWarden.class)); + cards.add(new SetCardInfo("Throne of the High City", 80, Rarity.RARE, mage.cards.t.ThroneOfTheHighCity.class)); + cards.add(new SetCardInfo("Tormenting Voice", 171, Rarity.COMMON, mage.cards.t.TormentingVoice.class)); + cards.add(new SetCardInfo("Traumatic Visions", 123, Rarity.COMMON, mage.cards.t.TraumaticVisions.class)); + cards.add(new SetCardInfo("Trumpet Blast", 172, Rarity.COMMON, mage.cards.t.TrumpetBlast.class)); + cards.add(new SetCardInfo("Twin Bolt", 173, Rarity.COMMON, mage.cards.t.TwinBolt.class)); + cards.add(new SetCardInfo("Unnerve", 150, Rarity.COMMON, mage.cards.u.Unnerve.class)); + cards.add(new SetCardInfo("Vaporkin", 124, Rarity.COMMON, mage.cards.v.Vaporkin.class)); + cards.add(new SetCardInfo("Vertigo Spawn", 125, Rarity.UNCOMMON, mage.cards.v.VertigoSpawn.class)); + cards.add(new SetCardInfo("Voyaging Satyr", 195, Rarity.COMMON, mage.cards.v.VoyagingSatyr.class)); + cards.add(new SetCardInfo("Wild Griffin", 99, Rarity.COMMON, mage.cards.w.WildGriffin.class)); + cards.add(new SetCardInfo("Wild Pair", 196, Rarity.RARE, mage.cards.w.WildPair.class)); + cards.add(new SetCardInfo("Windborne Charge", 100, Rarity.UNCOMMON, mage.cards.w.WindborneCharge.class)); + cards.add(new SetCardInfo("Wings of the Guard", 26, Rarity.COMMON, mage.cards.w.WingsOfTheGuard.class)); + cards.add(new SetCardInfo("Zealous Strike", 101, Rarity.COMMON, mage.cards.z.ZealousStrike.class)); + } + +} diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index d546c2b875b..f429bd35fff 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -93,6 +93,7 @@ public enum CounterType { PETAL("petal"), PETRIFICATION("petrification"), PLAGUE("plague"), + PLOT("plot"), POLYP("polyp"), POISON("poison"), PRESSURE("pressure"), From 4f81babdfa8b0ba715762847ccc8864cc51a4da4 Mon Sep 17 00:00:00 2001 From: vraskulin Date: Thu, 22 Dec 2016 18:36:40 +0300 Subject: [PATCH 4/7] Concurrency perfomance boost Parallel execution. Speed increased from 50% (avg in all methods) to 500% (checkForNewCards method) --- .../plugins/card/images/DownloadPictures.java | 127 +++++++++--------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index e086d32cf4e..c76e2498f49 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -22,6 +22,7 @@ import java.nio.file.AccessDeniedException; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; @@ -235,18 +236,20 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } public static boolean checkForNewCards(List allCards) { - TFile file; - for (CardInfo card : allCards) { - if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) { - CardDownloadData url = new CardDownloadData(card.getName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); - file = new TFile(CardImageUtils.generateImagePath(url)); - if (!file.exists()) { - return true; + AtomicBoolean missedCardTFiles = new AtomicBoolean(); + allCards.parallelStream().forEach(card -> { + if (!missedCardTFiles.get()) { + if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) { + CardDownloadData url = new CardDownloadData(card.getName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), + 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); + TFile file = new TFile(CardImageUtils.generateImagePath(url)); + if (!file.exists()) { + missedCardTFiles.set(true); + } } } - } - return false; + }); + return missedCardTFiles.get(); } private void updateCardsToDownload() { @@ -291,7 +294,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab /** * read all card names and urls */ - ArrayList allCardsUrls = new ArrayList<>(); + List allCardsUrls = Collections.synchronizedList(new ArrayList<>()); HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); /** @@ -309,47 +312,47 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab try { offlineMode = true; - for (CardInfo card : allCards) { - if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty() - && !ignoreUrls.contains(card.getSetCode())) { - String cardName = card.getName(); - boolean isType2 = type2SetsFilter.contains(card.getSetCode()); - CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); - if (url.getUsesVariousArt()) { - url.setDownloadName(createDownloadName(card)); - } + allCards.parallelStream().forEach(card -> { + if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty() + && !ignoreUrls.contains(card.getSetCode())) { + String cardName = card.getName(); + boolean isType2 = type2SetsFilter.contains(card.getSetCode()); + CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); + if (url.getUsesVariousArt()) { + url.setDownloadName(createDownloadName(card)); + } - url.setFlipCard(card.isFlipCard()); - url.setSplitCard(card.isSplitCard()); - url.setType2(isType2); + url.setFlipCard(card.isFlipCard()); + url.setSplitCard(card.isSplitCard()); + url.setType2(isType2); - allCardsUrls.add(url); - if (card.isDoubleFaced()) { - if (card.getSecondSideName() == null || card.getSecondSideName().trim().isEmpty()) { - throw new IllegalStateException("Second side card can't have empty name."); - } - url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); - url.setType2(isType2); - allCardsUrls.add(url); - } - if (card.isFlipCard()) { - if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { - throw new IllegalStateException("Flipped card can't have empty name."); - } - url = new CardDownloadData(card.getFlipCardName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); - url.setFlipCard(true); - url.setFlippedSide(true); - url.setType2(isType2); - allCardsUrls.add(url); - } - } else if (card.getCardNumber().isEmpty() || "0".equals(card.getCardNumber())) { - System.err.println("There was a critical error!"); - logger.error("Card has no collector ID and won't be sent to client: " + card); - } else if (card.getSetCode().isEmpty()) { - System.err.println("There was a critical error!"); - logger.error("Card has no set name and won't be sent to client:" + card); - } - } + allCardsUrls.add(url); + if (card.isDoubleFaced()) { + if (card.getSecondSideName() == null || card.getSecondSideName().trim().isEmpty()) { + throw new IllegalStateException("Second side card can't have empty name."); + } + url = new CardDownloadData(card.getSecondSideName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), true); + url.setType2(isType2); + allCardsUrls.add(url); + } + if (card.isFlipCard()) { + if (card.getFlipCardName() == null || card.getFlipCardName().trim().isEmpty()) { + throw new IllegalStateException("Flipped card can't have empty name."); + } + url = new CardDownloadData(card.getFlipCardName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); + url.setFlipCard(true); + url.setFlippedSide(true); + url.setType2(isType2); + allCardsUrls.add(url); + } + } else if (card.getCardNumber().isEmpty() || "0".equals(card.getCardNumber())) { + System.err.println("There was a critical error!"); + logger.error("Card has no collector ID and won't be sent to client: " + card); + } else if (card.getSetCode().isEmpty()) { + System.err.println("There was a critical error!"); + logger.error("Card has no set name and won't be sent to client:" + card); + } + }); allCardsUrls.addAll(getTokenCardUrls()); } catch (Exception e) { logger.error(e); @@ -651,7 +654,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab boolean useTempFile = false; int responseCode = 0; URLConnection httpConn = null; - + if (temporaryFile != null && temporaryFile.length() > 100) { useTempFile = true; } else { @@ -661,7 +664,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab httpConn.connect(); responseCode = ((HttpURLConnection) httpConn).getResponseCode(); } - + if (responseCode == 200 || useTempFile) { if (!useTempFile) { try (BufferedInputStream in = new BufferedInputStream(((HttpURLConnection) httpConn).getInputStream())) { @@ -741,21 +744,21 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab httpConn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch"); httpConn.setRequestProperty("Accept-Language", "en-US,en;q=0.8"); - httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36"); + httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"); break; // ff case 1: httpConn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate"); httpConn.setRequestProperty("Accept-Language", "en-US;q=0.5,en;q=0.3"); - httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0"); + httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0"); break; // ie case 2: httpConn.setRequestProperty("Accept", "text/html, application/xhtml+xml, */*"); httpConn.setRequestProperty("Accept-Encoding", "gzip, deflate"); httpConn.setRequestProperty("Accept-Language", "en-US"); - httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"); + httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko"); break; } } @@ -789,14 +792,16 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab bar.setString(String.format("%d of %d cards finished! Please wait! [%.1f Mb]", card, count, mb)); } else { - Iterator cardsIterator = DownloadPictures.this.cards.iterator(); - while (cardsIterator.hasNext()) { - CardDownloadData cardDownloadData = cardsIterator.next(); + List remainingCards = Collections.synchronizedList(new ArrayList<>()); + DownloadPictures.this.cards.parallelStream().forEach(cardDownloadData -> { TFile file = new TFile(CardImageUtils.generateImagePath(cardDownloadData)); - if (file.exists()) { - cardsIterator.remove(); + if (!file.exists()) { + remainingCards.add(cardDownloadData); } - } + }); + + DownloadPictures.this.cards = new ArrayList<>(remainingCards); + count = DownloadPictures.this.cards.size(); if (count == 0) { From 8ba22ad7e26d651674ac54bf4b543c8055c86847 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 22 Dec 2016 23:50:02 +0100 Subject: [PATCH 5/7] * Fixed that selecting no target players let fizzle the spell (e.g. Wheel and Deal). --- .../main/java/mage/target/TargetPlayer.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Mage/src/main/java/mage/target/TargetPlayer.java b/Mage/src/main/java/mage/target/TargetPlayer.java index 3d962a9d902..3c69dc28716 100644 --- a/Mage/src/main/java/mage/target/TargetPlayer.java +++ b/Mage/src/main/java/mage/target/TargetPlayer.java @@ -24,20 +24,18 @@ * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. -*/ - + */ package mage.target; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.filter.FilterPlayer; import mage.game.Game; import mage.players.Player; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com @@ -77,8 +75,8 @@ public class TargetPlayer extends TargetImpl { } /** - * Checks if there are enough {@link Player} that can be chosen. Should only be used - * for Ability targets since this checks for protection, shroud etc. + * Checks if there are enough {@link Player} that can be chosen. Should only + * be used for Ability targets since this checks for protection, shroud etc. * * @param sourceId - the target event source * @param sourceControllerId - controller of the target event source @@ -89,7 +87,7 @@ public class TargetPlayer extends TargetImpl { public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { int count = 0; MageObject targetSource = game.getObject(sourceId); - for (UUID playerId: game.getState().getPlayersInRange(sourceControllerId, game)) { + for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) { if (player.canBeTargetedBy(targetSource, sourceControllerId, game)) { @@ -104,8 +102,9 @@ public class TargetPlayer extends TargetImpl { } /** - * Checks if there are enough {@link Player} that can be selected. Should not be used - * for Ability targets since this does not check for protection, shroud etc. + * Checks if there are enough {@link Player} that can be selected. Should + * not be used for Ability targets since this does not check for protection, + * shroud etc. * * @param sourceControllerId - controller of the select event * @param game @@ -114,7 +113,7 @@ public class TargetPlayer extends TargetImpl { @Override public boolean canChoose(UUID sourceControllerId, Game game) { int count = 0; - for (UUID playerId: game.getState().getPlayersInRange(sourceControllerId, game)) { + for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, game)) { count++; @@ -130,7 +129,7 @@ public class TargetPlayer extends TargetImpl { public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { Set possibleTargets = new HashSet<>(); MageObject targetSource = game.getObject(sourceId); - for (UUID playerId: game.getState().getPlayersInRange(sourceControllerId, game)) { + for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, sourceId, sourceControllerId, game)) { if (isNotTarget() || player.canBeTargetedBy(targetSource, sourceControllerId, game)) { @@ -144,7 +143,7 @@ public class TargetPlayer extends TargetImpl { @Override public Set possibleTargets(UUID sourceControllerId, Game game) { Set possibleTargets = new HashSet<>(); - for (UUID playerId: game.getState().getPlayersInRange(sourceControllerId, game)) { + for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) { Player player = game.getPlayer(playerId); if (player != null && !player.hasLeft() && filter.match(player, game)) { possibleTargets.add(playerId); @@ -156,7 +155,10 @@ public class TargetPlayer extends TargetImpl { @Override public boolean isLegal(Ability source, Game game) { //20101001 - 608.2b - for (UUID playerId: targets.keySet()) { + if (getNumberOfTargets() == 0 && targets.isEmpty()) { + return true; // 0 targets selected is valid + } + for (UUID playerId : targets.keySet()) { if (canTarget(playerId, source, game)) { return true; } @@ -195,7 +197,7 @@ public class TargetPlayer extends TargetImpl { @Override public String getTargetedName(Game game) { StringBuilder sb = new StringBuilder(); - for (UUID targetId: getTargets()) { + for (UUID targetId : getTargets()) { Player player = game.getPlayer(targetId); if (player != null) { sb.append(player.getLogName()).append(" "); From e5a5911c6ebcb24f38ec883024902bcc44678b33 Mon Sep 17 00:00:00 2001 From: "ludwig.hirth" Date: Fri, 23 Dec 2016 12:29:33 +0100 Subject: [PATCH 6/7] * Sacred Ground - Fixed that the Sacred Ground effect did also move the land if it was removed from graveyard since the ability triggered. --- Mage.Sets/src/mage/cards/s/SacredGround.java | 7 +-- .../test/cards/triggers/SacredGroundTest.java | 63 +++++++++++++++---- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/SacredGround.java b/Mage.Sets/src/mage/cards/s/SacredGround.java index fbee5573c32..53acd31aa77 100644 --- a/Mage.Sets/src/mage/cards/s/SacredGround.java +++ b/Mage.Sets/src/mage/cards/s/SacredGround.java @@ -48,8 +48,7 @@ import mage.target.targetpointer.FixedTarget; public class SacredGround extends CardImpl { public SacredGround(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); // Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, return that card to the battlefield. this.addAbility(new SacredGroundTriggeredAbility()); @@ -92,7 +91,7 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl { if (Zone.BATTLEFIELD.equals(zce.getFromZone()) && Zone.GRAVEYARD.equals(zce.getToZone())) { Permanent targetPermanent = zce.getTarget(); if (targetPermanent.getCardType().contains(CardType.LAND) && targetPermanent.getControllerId().equals(getControllerId())) { - getEffects().get(0).setTargetPointer(new FixedTarget(targetPermanent.getId())); + getEffects().get(0).setTargetPointer(new FixedTarget(targetPermanent.getId(), game.getState().getZoneChangeCounter(targetPermanent.getId()))); return true; } } @@ -104,4 +103,4 @@ class SacredGroundTriggeredAbility extends TriggeredAbilityImpl { public String getRule() { return "Whenever a spell or ability an opponent controls causes a land to be put into your graveyard from the battlefield, " + super.getRule(); } -} \ No newline at end of file +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SacredGroundTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SacredGroundTest.java index 6c6ce282b88..1fa82368c50 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SacredGroundTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/SacredGroundTest.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package org.mage.test.cards.triggers; import mage.constants.PhaseStep; @@ -40,10 +39,9 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class SacredGroundTest extends CardTestPlayerBase { /** - * Sacred Ground {1}{W} - * Enchantment - * Whenever a spell or ability an opponent controls causes a land to be put into your - * graveyard from the battlefield, return that card to the battlefield. + * Sacred Ground {1}{W} Enchantment Whenever a spell or ability an opponent + * controls causes a land to be put into your graveyard from the + * battlefield, return that card to the battlefield. * * * Destroyed land returns to battlefield @@ -76,10 +74,9 @@ public class SacredGroundTest extends CardTestPlayerBase { } /** - * Sacred Ground {1}{W} - * Enchantment - * Whenever a spell or ability an opponent controls causes a land to be put into your - * graveyard from the battlefield, return that card to the battlefield. + * Sacred Ground {1}{W} Enchantment Whenever a spell or ability an opponent + * controls causes a land to be put into your graveyard from the + * battlefield, return that card to the battlefield. * * * Destroyed land returns to battlefield @@ -111,10 +108,9 @@ public class SacredGroundTest extends CardTestPlayerBase { } /** - * Sacred Ground {1}{W} - * Enchantment - * Whenever a spell or ability an opponent controls causes a land to be put into your - * graveyard from the battlefield, return that card to the battlefield. + * Sacred Ground {1}{W} Enchantment Whenever a spell or ability an opponent + * controls causes a land to be put into your graveyard from the + * battlefield, return that card to the battlefield. * * * Destroyed land returns to battlefield @@ -144,4 +140,45 @@ public class SacredGroundTest extends CardTestPlayerBase { assertLife(playerB, 24); // + 2 * 2 life from Kabira Crossroads } + /** + * I was playing against Sacred Ground. I Molten Rained oponents land and + * responded Sacred Ground trigger by exiling it with Surgical Extraction. + * Then after that resolved, Sacred Ground ability put the land from exile + * onto the battfield! Fix this, please + */ + @Test + public void testWithSurgicalExtraction() { + addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + + // Destroy target land. + // If that land was nonbasic, Molten Rain deals 2 damage to the land's controller. + addCard(Zone.HAND, playerA, "Molten Rain");// Instant {1}{R}{R} + // Choose target card in a graveyard other than a basic land card. Search its owner's graveyard, + // hand, and library for any number of cards with the same name as that card and exile them. + // Then that player shuffles his or her library. + addCard(Zone.HAND, playerA, "Surgical Extraction"); // Instant {BP} + + addCard(Zone.BATTLEFIELD, playerB, "Caves of Koilos", 1); + /** + * Whenever a spell or ability an opponent controls causes a land to be + * put into your graveyard from the battlefield, return that card to the + * battlefield. + */ + addCard(Zone.BATTLEFIELD, playerB, "Sacred Ground"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Molten Rain", "Caves of Koilos"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Surgical Extraction", "Caves of Koilos"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, "Molten Rain", 1); + assertGraveyardCount(playerA, "Surgical Extraction", 1); + assertExileCount("Caves of Koilos", 1); + + assertLife(playerA, 20); + assertLife(playerB, 18); + } + } From ec4e50ece4b5fd3a2a520b11907c2fe8ac366ffb Mon Sep 17 00:00:00 2001 From: "ludwig.hirth" Date: Fri, 23 Dec 2016 15:04:09 +0100 Subject: [PATCH 7/7] Added test. --- .../mage/test/cards/rules/CantDrawTest.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/rules/CantDrawTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantDrawTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantDrawTest.java new file mode 100644 index 00000000000..dcf058b2554 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantDrawTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.rules; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class CantDrawTest extends CardTestPlayerBase { + + /** + * Leovold, Emissary of Trest does not stop Sylvan Library from drawing + * extra cards. + */ + @Test + public void testCardsNotDrawnFromLibraryEffect() { + // Each opponent can't draw more than one card each turn. + // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card. + addCard(Zone.BATTLEFIELD, playerB, "Leovold, Emissary of Trest"); + + // At the beginning of your draw step, you may draw two additional cards. + // If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. + addCard(Zone.BATTLEFIELD, playerA, "Sylvan Library", 1); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, 0); + + assertHandCount(playerA, 1); // only one card drawn at start of turn 3 + assertLife(playerA, 16); // pay 4 life for the card dawn normally (no other cards drawn) + + } + + @Test + public void testCardsNotDrawnFromLibraryEffectNoUse() { + // Each opponent can't draw more than one card each turn. + // Whenever you or a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card. + addCard(Zone.BATTLEFIELD, playerB, "Leovold, Emissary of Trest"); + + // At the beginning of your draw step, you may draw two additional cards. + // If you do, choose two cards in your hand drawn this turn. For each of those cards, pay 4 life or put the card on top of your library. + addCard(Zone.BATTLEFIELD, playerA, "Sylvan Library", 1); + + setChoice(playerA, "No"); + + setStopAt(3, PhaseStep.BEGIN_COMBAT); + execute(); + + assertGraveyardCount(playerA, 0); + + assertHandCount(playerA, 1); // only one card drawn at start of turn 3 + assertLife(playerA, 20); // not used no damage + + } + +}