From 48f4b575bd2c7369ec75990b2c109c79d8059881 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 13:17:25 -0400 Subject: [PATCH 001/100] Implemented Bellowing Aegisaur --- .../src/mage/cards/b/BellowingAegisaur.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BellowingAegisaur.java diff --git a/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java new file mode 100644 index 0000000000..c0c4bbdf4a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BellowingAegisaur.java @@ -0,0 +1,78 @@ +/* + * 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.b; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersAllEffect; +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.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class BellowingAegisaur extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each other creature you control"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new AnotherPredicate()); + } + + public BellowingAegisaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new AddCountersAllEffect(CounterType.P1P1.createInstance(), filter), false, true); + this.addAbility(ability); + } + + public BellowingAegisaur(final BellowingAegisaur card) { + super(card); + } + + @Override + public BellowingAegisaur copy() { + return new BellowingAegisaur(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index d849235944..cc7221b15d 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -32,6 +32,7 @@ public class Ixalan extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); From aa78e8bfa8511585987b546c46a5ddf9cd97e563 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 17:07:00 -0400 Subject: [PATCH 002/100] Implemented Militant Dinosaur --- .../src/mage/cards/m/MilitantDinosaur.java | 114 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 115 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MilitantDinosaur.java diff --git a/Mage.Sets/src/mage/cards/m/MilitantDinosaur.java b/Mage.Sets/src/mage/cards/m/MilitantDinosaur.java new file mode 100644 index 0000000000..dae2c232ca --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MilitantDinosaur.java @@ -0,0 +1,114 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; + +/** + * + * @author TheElk801 + */ +public class MilitantDinosaur extends CardImpl { + + public MilitantDinosaur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Each creature you control assigns combat damage equal to its toughness rather than its power. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MilitantDinosaurCombatDamageRuleEffect())); + } + + public MilitantDinosaur(final MilitantDinosaur card) { + super(card); + } + + @Override + public MilitantDinosaur copy() { + return new MilitantDinosaur(this); + } +} + +class MilitantDinosaurCombatDamageRuleEffect extends ContinuousEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public MilitantDinosaurCombatDamageRuleEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Each creature you control assigns combat damage equal to its toughness rather than its power"; + } + + public MilitantDinosaurCombatDamageRuleEffect(final MilitantDinosaurCombatDamageRuleEffect effect) { + super(effect); + } + + @Override + public MilitantDinosaurCombatDamageRuleEffect copy() { + return new MilitantDinosaurCombatDamageRuleEffect(this); + } + + @Override + public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { + // Change the rule + game.getCombat().setUseToughnessForDamage(true); + game.getCombat().addUseToughnessForDamageFilter(filter); + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean hasLayer(Layer layer) { + return layer == Layer.RulesEffects; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index cc7221b15d..cb5cf61195 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -54,6 +54,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Kumena's Omenspeaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasOmenspeaker.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); + cards.add(new SetCardInfo("Militant Dinosaur", 218, Rarity.UNCOMMON, mage.cards.m.MilitantDinosaur.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); From cd91c9516d7736f3ead8a37ca30aa1cfb464ac7d Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 2 Sep 2017 20:36:12 -0400 Subject: [PATCH 003/100] Implemented Deathless Ancient --- .../src/mage/cards/d/DeathlessAncient.java | 84 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 85 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeathlessAncient.java diff --git a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java new file mode 100644 index 0000000000..ef9e413d9e --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java @@ -0,0 +1,84 @@ +/* + * 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.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapTargetCost; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.TappedPredicate; +import mage.target.common.TargetControlledPermanent; + +/** + * + * @author caldover + */ +public class DeathlessAncient extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("untapped Vampires you control"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + } + + public DeathlessAncient(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + + this.subtype.add("Vampire"); + this.subtype.add("Knight"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand. + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, false)))); + + } + + public DeathlessAncient(final DeathlessAncient card) { + super(card); + } + + @Override + public DeathlessAncient copy() { + return new DeathlessAncient(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b375fd392f..9e0ebd26ed 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -39,6 +39,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); + cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); From 53db9dadbb497fe129460dbf4721c48cec8cc47a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 22:03:16 -0400 Subject: [PATCH 004/100] Implemented Twilight Legion Battleship --- .../cards/t/TwilightLegionBattleship.java | 67 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java diff --git a/Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java b/Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java new file mode 100644 index 0000000000..c223f21fd7 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java @@ -0,0 +1,67 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.VigilanceAbility; +import mage.abilities.keyword.CrewAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class TwilightLegionBattleship extends CardImpl { + + public TwilightLegionBattleship(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); + + this.subtype.add("Vehicle"); + this.power = new MageInt(4); + this.toughness = new MageInt(6); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // Crew 2 + this.addAbility(new CrewAbility(2)); + + } + + public TwilightLegionBattleship(final TwilightLegionBattleship card) { + super(card); + } + + @Override + public TwilightLegionBattleship copy() { + return new TwilightLegionBattleship(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index cb5cf61195..26ee5149e4 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -74,6 +74,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); + cards.add(new SetCardInfo("Twilight Legion Battleship", 236, Rarity.UNCOMMON, mage.cards.t.TwilightLegionBattleship.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); From 985328a22862eb8c9b3071db066ae97832abff6a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 22:07:15 -0400 Subject: [PATCH 005/100] . From 7a18726a40224fa8891b2ff2fd81f2b92abf2f0e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 22:18:56 -0400 Subject: [PATCH 006/100] . --- .../mage/cards/j/JaceIngeniousMindMage.java | 79 ------------------- 1 file changed, 79 deletions(-) delete mode 100644 Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java diff --git a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java deleted file mode 100644 index e68594b18b..0000000000 --- a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.j; - -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; -import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.UntapAllControllerEffect; -import mage.abilities.effects.common.continuous.GainControlTargetEffect; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.SuperType; -import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; -import mage.target.common.TargetCreaturePermanent; - -/** - * - * @author TheElk801 - */ -public class JaceIngeniousMindMage extends CardImpl { - - public JaceIngeniousMindMage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{U}{U}"); - - addSuperType(SuperType.LEGENDARY); - this.subtype.add("Jace"); - - this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); - - // +1: Draw a card. - this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1)); - - // +1: Untap all creatures you control. - this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(FILTER_PERMANENT_CREATURES), 1)); - - // -9: Gain control of up to three target creatures. - Ability ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.Custom), -9); - ability.addTarget(new TargetCreaturePermanent(0, 3)); - this.addAbility(ability); - } - - public JaceIngeniousMindMage(final JaceIngeniousMindMage card) { - super(card); - } - - @Override - public JaceIngeniousMindMage copy() { - return new JaceIngeniousMindMage(this); - } -} From faa4dd2fe3350cbe2d91dcda13be9d6691d2c302 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 2 Sep 2017 22:19:32 -0400 Subject: [PATCH 007/100] . --- .../mage/cards/j/JaceIngeniousMindMage.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java diff --git a/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java new file mode 100644 index 0000000000..e68594b18b --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JaceIngeniousMindMage.java @@ -0,0 +1,79 @@ +/* + * 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.j; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.UntapAllControllerEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SuperType; +import static mage.filter.StaticFilters.FILTER_PERMANENT_CREATURES; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class JaceIngeniousMindMage extends CardImpl { + + public JaceIngeniousMindMage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{U}{U}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Jace"); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5)); + + // +1: Draw a card. + this.addAbility(new LoyaltyAbility(new DrawCardSourceControllerEffect(1), 1)); + + // +1: Untap all creatures you control. + this.addAbility(new LoyaltyAbility(new UntapAllControllerEffect(FILTER_PERMANENT_CREATURES), 1)); + + // -9: Gain control of up to three target creatures. + Ability ability = new LoyaltyAbility(new GainControlTargetEffect(Duration.Custom), -9); + ability.addTarget(new TargetCreaturePermanent(0, 3)); + this.addAbility(ability); + } + + public JaceIngeniousMindMage(final JaceIngeniousMindMage card) { + super(card); + } + + @Override + public JaceIngeniousMindMage copy() { + return new JaceIngeniousMindMage(this); + } +} From 518bae18df9736746695c58e1169cf53ea21887b Mon Sep 17 00:00:00 2001 From: TacomenX Date: Mon, 4 Sep 2017 01:29:20 -0500 Subject: [PATCH 008/100] [XLN] Deeproot Waters + Merfolk Hexproof Token --- .../src/mage/cards/d/DeeprootWaters.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../permanent/token/MerfolkHexproofToken.java | 32 +++++++++ 3 files changed, 102 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DeeprootWaters.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java diff --git a/Mage.Sets/src/mage/cards/d/DeeprootWaters.java b/Mage.Sets/src/mage/cards/d/DeeprootWaters.java new file mode 100644 index 0000000000..063076f49b --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeeprootWaters.java @@ -0,0 +1,69 @@ +/* + * 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.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterSpell; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.permanent.token.MerfolkHexproofToken; + +/** + * + * @author TacomenX + */ +public class DeeprootWaters extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a Merfolk spell"); + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + public DeeprootWaters(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + + + // Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof. + this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new MerfolkHexproofToken(), 1, true, false), filter, false)); + } + + public DeeprootWaters(final DeeprootWaters card) { + super(card); + } + + @Override + public DeeprootWaters copy() { + return new DeeprootWaters(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f6ee6ca705..87dfc0603f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -41,6 +41,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); + cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java b/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java new file mode 100644 index 0000000000..84503c437e --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/MerfolkHexproofToken.java @@ -0,0 +1,32 @@ +/* + * 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.game.permanent.token; + +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.HexproofAbility; +import mage.constants.CardType; + +/** + * + * @author TacomenX + */ + +public class MerfolkHexproofToken extends Token { + + + + public MerfolkHexproofToken() { + super("Merfolk", "1/1 blue Merfolk creature token with hexproof"); + this.cardType.add(CardType.CREATURE); + this.subtype.add("Merfolk"); + this.color = ObjectColor.BLUE; + this.power = new MageInt(1); + this.toughness = new MageInt(1); + this.addAbility(HexproofAbility.getInstance()); + } + +} \ No newline at end of file From 3fa142cc0be9d3c352834d41317d952e7e62d769 Mon Sep 17 00:00:00 2001 From: TacomenX Date: Mon, 4 Sep 2017 09:45:20 -0500 Subject: [PATCH 009/100] Deeproot Waters + Merfolk Hexproof Token --- Mage.Sets/src/mage/cards/d/DeeprootWaters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DeeprootWaters.java b/Mage.Sets/src/mage/cards/d/DeeprootWaters.java index 063076f49b..f1c3aa6b8f 100644 --- a/Mage.Sets/src/mage/cards/d/DeeprootWaters.java +++ b/Mage.Sets/src/mage/cards/d/DeeprootWaters.java @@ -55,7 +55,7 @@ public class DeeprootWaters extends CardImpl { // Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof. - this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new MerfolkHexproofToken(), 1, true, false), filter, false)); + this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new MerfolkHexproofToken()), filter, false)); } public DeeprootWaters(final DeeprootWaters card) { From 669190486dba1d8be68a1757311af67cec855da9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 11:35:37 -0400 Subject: [PATCH 010/100] Implemented Admiral Beckett Brass --- .../src/mage/cards/a/AdmiralBeckettBrass.java | 178 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 179 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java diff --git a/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java new file mode 100644 index 0000000000..019db58bcb --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AdmiralBeckettBrass.java @@ -0,0 +1,178 @@ +/* + * 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.a; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.Predicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetNonlandPermanent; +import mage.watchers.Watcher; + +/** + * + * @author TheElk801 + */ +public class AdmiralBeckettBrass extends CardImpl { + + private final UUID originalId; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other Pirates you control"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public AdmiralBeckettBrass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Other Pirates you control get +1/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true))); + + // At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn. + Ability ability = new BeginningOfEndStepTriggeredAbility(new GainControlTargetEffect(Duration.Custom), TargetController.YOU, false); + ability.addTarget(new TargetNonlandPermanent()); + originalId = ability.getOriginalId(); + this.addAbility(ability, new DamagedByPiratesWatcher()); + } + + public AdmiralBeckettBrass(final AdmiralBeckettBrass card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability.getOriginalId().equals(originalId)) { + ability.getTargets().clear(); + FilterNonlandPermanent playerFilter = new FilterNonlandPermanent("nonland permanent controlled by a player who was dealt combat damage by three or more Pirates this turn"); + playerFilter.add(new ControllerDealtDamageByPiratesPredicate()); + TargetNonlandPermanent target = new TargetNonlandPermanent(1, 1, playerFilter, true); + ability.addTarget(target); + } + } + + @Override + public AdmiralBeckettBrass copy() { + return new AdmiralBeckettBrass(this); + } +} + +class DamagedByPiratesWatcher extends Watcher { + + private final Map> damageSourceIds = new HashMap<>(); + + public DamagedByPiratesWatcher() { + super(DamagedByPiratesWatcher.class.getSimpleName(), WatcherScope.GAME); + } + + public DamagedByPiratesWatcher(final DamagedByPiratesWatcher watcher) { + super(watcher); + for (UUID playerId : watcher.damageSourceIds.keySet()) { + Set creatures = new HashSet<>(); + creatures.addAll(watcher.damageSourceIds.get(playerId)); + this.damageSourceIds.put(playerId, creatures); + } + } + + @Override + public DamagedByPiratesWatcher copy() { + return new DamagedByPiratesWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getFlag()) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null && creature.getSubtype(game).contains(SubType.PIRATE)) { + if (damageSourceIds.keySet().contains(event.getTargetId())) { + damageSourceIds.get(event.getTargetId()).add(creature.getId()); + } else { + Set creatureSet = new HashSet(); + creatureSet.add(creature.getId()); + damageSourceIds.put(event.getTargetId(), creatureSet); + } + } + } + } + + public boolean damagedByEnoughPirates(UUID sourceId, Game game) { + return damageSourceIds.keySet().contains(sourceId) && damageSourceIds.get(sourceId).size() > 2; + } + + @Override + public void reset() { + super.reset(); + damageSourceIds.clear(); + } +} + +class ControllerDealtDamageByPiratesPredicate implements Predicate { + + public ControllerDealtDamageByPiratesPredicate() { + } + + @Override + public boolean apply(Permanent input, Game game) { + DamagedByPiratesWatcher watcher = (DamagedByPiratesWatcher) game.getState().getWatchers().get(DamagedByPiratesWatcher.class.getSimpleName()); + if (watcher != null) { + return watcher.damagedByEnoughPirates(input.getControllerId(), game); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 26ee5149e4..8d01315f31 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -31,6 +31,7 @@ public class Ixalan extends ExpansionSet { this.numBoosterUncommon = 3; this.numBoosterRare = 1; this.ratioBoosterMythic = 8; + cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); From 26e4e2672e6acf12ccee3ab22984e8fa97234811 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 12:11:47 -0400 Subject: [PATCH 011/100] Updated Vintage restricted list --- .../Mage.Deck.Constructed/src/mage/deck/Vintage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java index c88500dbc3..94c0fcf3e3 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java @@ -94,6 +94,7 @@ public class Vintage extends Constructed { restricted.add("Memory Jar"); restricted.add("Merchant Scroll"); restricted.add("Mind's Desire"); + restricted.add("Monastery Mentory") restricted.add("Mox Emerald"); restricted.add("Mox Jet"); restricted.add("Mox Pearl"); @@ -104,6 +105,7 @@ public class Vintage extends Constructed { restricted.add("Ponder"); restricted.add("Sol Ring"); restricted.add("Strip Mine"); + restricted.add("Thorn of Amethyst") restricted.add("Time Vault"); restricted.add("Time Walk"); restricted.add("Timetwister"); @@ -114,7 +116,6 @@ public class Vintage extends Constructed { restricted.add("Vampiric Tutor"); restricted.add("Wheel of Fortune"); restricted.add("Windfall"); - restricted.add("Yawgmoth's Bargain"); restricted.add("Yawgmoth's Will"); } From 16ae822a5f014aaca71313c5344716893a86b7ca Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 15:53:27 -0400 Subject: [PATCH 012/100] fixed XLN card names --- .../{KumenasOmenspeaker.java => KumenasSpeaker.java} | 12 ++++++------ ...litantDinosaur.java => BelligerentBrontodon.java} | 10 +++++----- ...ionBattleship.java => DuskLegionDreadnought.java} | 10 +++++----- Mage.Sets/src/mage/sets/Ixalan.java | 8 ++++---- Utils/mtg-cards-data.txt | 10 +++++----- 5 files changed, 25 insertions(+), 25 deletions(-) rename Mage.Sets/src/mage/cards/k/{KumenasOmenspeaker.java => KumenasSpeaker.java} (90%) rename Mage.Sets/src/mage/cards/m/{MilitantDinosaur.java => BelligerentBrontodon.java} (93%) rename Mage.Sets/src/mage/cards/t/{TwilightLegionBattleship.java => DuskLegionDreadnought.java} (88%) diff --git a/Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java similarity index 90% rename from Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java rename to Mage.Sets/src/mage/cards/k/KumenasSpeaker.java index 0eea31a498..a6eeff50fc 100644 --- a/Mage.Sets/src/mage/cards/k/KumenasOmenspeaker.java +++ b/Mage.Sets/src/mage/cards/k/KumenasSpeaker.java @@ -45,9 +45,9 @@ import mage.filter.predicate.permanent.AnotherPredicate; * * @author TheElk801 */ -public class KumenasOmenspeaker extends CardImpl { +public class KumenasSpeaker extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("another Merfolk or Island"); + private static final FilterPermanent filter = new FilterPermanent("another Merfolk or an Island"); static { filter.add(Predicates.or( @@ -59,7 +59,7 @@ public class KumenasOmenspeaker extends CardImpl { )); } - public KumenasOmenspeaker(UUID ownerId, CardSetInfo setInfo) { + public KumenasSpeaker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add("Merfolk"); @@ -70,12 +70,12 @@ public class KumenasOmenspeaker extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceWhileControlsEffect(filter, 1, 1))); } - public KumenasOmenspeaker(final KumenasOmenspeaker card) { + public KumenasSpeaker(final KumenasSpeaker card) { super(card); } @Override - public KumenasOmenspeaker copy() { - return new KumenasOmenspeaker(this); + public KumenasSpeaker copy() { + return new KumenasSpeaker(this); } } diff --git a/Mage.Sets/src/mage/cards/m/MilitantDinosaur.java b/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java similarity index 93% rename from Mage.Sets/src/mage/cards/m/MilitantDinosaur.java rename to Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java index dae2c232ca..21527d441b 100644 --- a/Mage.Sets/src/mage/cards/m/MilitantDinosaur.java +++ b/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java @@ -49,9 +49,9 @@ import mage.game.Game; * * @author TheElk801 */ -public class MilitantDinosaur extends CardImpl { +public class BelligerentBrontodon extends CardImpl { - public MilitantDinosaur(UUID ownerId, CardSetInfo setInfo) { + public BelligerentBrontodon(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{G}{W}"); this.subtype.add("Dinosaur"); @@ -62,13 +62,13 @@ public class MilitantDinosaur extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MilitantDinosaurCombatDamageRuleEffect())); } - public MilitantDinosaur(final MilitantDinosaur card) { + public BelligerentBrontodon(final BelligerentBrontodon card) { super(card); } @Override - public MilitantDinosaur copy() { - return new MilitantDinosaur(this); + public BelligerentBrontodon copy() { + return new BelligerentBrontodon(this); } } diff --git a/Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java b/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java similarity index 88% rename from Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java rename to Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java index c223f21fd7..3717aef2af 100644 --- a/Mage.Sets/src/mage/cards/t/TwilightLegionBattleship.java +++ b/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java @@ -39,9 +39,9 @@ import mage.constants.CardType; * * @author TheElk801 */ -public class TwilightLegionBattleship extends CardImpl { +public class DuskLegionDreadnought extends CardImpl { - public TwilightLegionBattleship(UUID ownerId, CardSetInfo setInfo) { + public DuskLegionDreadnought(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); this.subtype.add("Vehicle"); @@ -56,12 +56,12 @@ public class TwilightLegionBattleship extends CardImpl { } - public TwilightLegionBattleship(final TwilightLegionBattleship card) { + public DuskLegionDreadnought(final DuskLegionDreadnought card) { super(card); } @Override - public TwilightLegionBattleship copy() { - return new TwilightLegionBattleship(this); + public DuskLegionDreadnought copy() { + return new DuskLegionDreadnought(this); } } diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index b35385f1b9..c44f72b5c5 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -55,9 +55,9 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); - cards.add(new SetCardInfo("Kumena's Omenspeaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasOmenspeaker.class)); + cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); - cards.add(new SetCardInfo("Militant Dinosaur", 218, Rarity.UNCOMMON, mage.cards.m.MilitantDinosaur.class)); + cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); @@ -77,13 +77,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); - cards.add(new SetCardInfo("Twilight Legion Battleship", 236, Rarity.UNCOMMON, mage.cards.t.TwilightLegionBattleship.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); - cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); + cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 43b5c776ea..b99061893b 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32372,7 +32372,7 @@ Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can Deathgorge Scavenger|Ixalan|???|R|???|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you may gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| -Kumena's Omenspeaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Omenspeaker gets +1/+1 as long as you control another Merfolk or Island.| +Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| @@ -32380,16 +32380,16 @@ Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishan Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| Admiral Beckett Brass|Ixalan|217|M|{1}{U}{B}{R}|Legendary Creature - Human Pirate|3|3|Other Pirates you control get +1/+1.$At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt damage by three or more Pirates this turn.| -Militant Dinosaur|Ixalan|218|U|{5}{G}{W}|Creature - Dinosaur|4|6|Each creature you control assigns combats damage equal to its toughness rather than its power.| -Invite the Party|Ixalan|219|U|{2}{W}{B}|Sorcery|||Create three 1/1 white Vampire creature tokens with lifelink.| +Belligerent Brontodon|Ixalan|218|U|{5}{G}{W}|Creature - Dinosaur|4|6|Each creature you control assigns combats damage equal to its toughness rather than its power.| +Call to the Feast|Ixalan|219|U|{2}{W}{B}|Sorcery|||Create three 1/1 white Vampire creature tokens with lifelink.| Deadeye Plunderers|Ixalan|220|U|{3}{U}{B}|Creature - Human Pirate|3|3|Deadeye Plunderers gets +1/+1 for each artifact you control.${2}{U}{B}: Create a colorless artifact token named Treasure with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Dire Fleet Captain|Ixalan|221|U|{B}{R}|Creature - Orc Pirate|2|2|Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate.| Gishath, Sun's Avatar|Ixalan|222|M|{5}{R}{G}{W}|Legendary Creature - Dinosaur Avatar|7|6|Trample, vigilance, haste$Whenever Gishath, Sun's Avatar deals combat damage to a player, reveal that many cards from the top of your library. Put any number of Dinosaur creature cards from among them onto the battlefield and the rest on the bottom of your library in a random order.| Hostage Taker|Ixalan|223|R|{2}{U}{B}|Creature - Human Pirate|2|3|When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.| Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| -Infuriated Gladiodon|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Infuriated Gladiodon enters the battlefield, it deals 1 damage to each other creature.| +Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| -Twilight Legion Battleship|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| +Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| Pillar of Genesis|Ixalan|241|U|{2}|Artifact|||As Pillar of Genesis enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| From ea7aa8c66559ca6267f8c4bd5206097390eb9b16 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 16:17:50 -0400 Subject: [PATCH 013/100] added planeswalker deck card info --- Utils/mtg-cards-data.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index b99061893b..afd40b0b4d 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32390,7 +32390,7 @@ Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At th Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| -Pillar of Genesis|Ixalan|241|U|{2}|Artifact|||As Pillar of Genesis enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| +Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| Treasure Cove|Ixalan|250|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| @@ -32403,7 +32403,15 @@ Rootbound Crag|Ixalan|256|R||Land|||Rootbound Crag enters the battlefield tapped Sunpetal Grove|Ixalan|257|R||Land|||Sunpetal Grove enters the battlefield tapped unless you control a Forest or a Plains.${T}: Add {G} or {W} to your mana pool.| Unclaimed Territory|Ixalan|258|U||Land|||As Unclaimed Territory enters the battlefield, choose a creature type.${T}: Add {C} to your mana pool.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell of the chosen type.| Jace, Ingenious Mind-Mage|Ixalan|280|M|{4}{U}{U}|Legendary Planeswalker - Jace|||[+1]: Draw a card.$[+1]: Untap all creatures you control.$[-9]: Gain control of up to three target creatures.| +Castaway's Despair|Ixalan|281|C|{3}{U}|Enchantment - Aura|||Enchant creature$When Castaway's Despair enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| +Grasping Current|Ixalan|282|R|{4}{U}|Sorcery|||Return up to two target creature's to their owner's hand.$Search your library and/or graveyard for a card named Jace, Ingenious Mind-Mage, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| +Jace's Sentinel|Ixalan|283|U|{1}{U}|Creature - Merfolk Warrior|1|3|As long as you control a Jace planeswalker, Jace's Sentinel gets +1/+0 and can't be blocked.| +Woodland Stream|Ixalan|284|U||Land|||Woodland Stream enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.| Huatli, Dinosaur Knight|Ixalan|285|M|{4}{R}{W}|Legendary Planeswalker - Huatli|||[+2]: Put two +1/+1 counters on up to one target Dinosaur you control.$[-3]: Target Dinosaur you control deals damage equal to its power to target creature you don't control.$[-7]: Dinosaurs you control get +4/+4 until end of turn.| +Huatli's Snubhorn|Ixalan|286|C|{1}{W}|Creature - Dinosaur|2|2|Vigilance| +Huatli's Spurring|Ixalan|287|U|{R}|Instant|||Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead.| +Sun-Blessed Mount|Ixalan|288|R|{3}{R}{W}|Creature - Dinosaur|4|4|When Sun-Blessed Mount enters the battlefield, you may search your library and/or graveyard for a card named Huatli, Dinosaur Knight, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| +Stone Quarry|Ixalan|289|U||Land|||Stone Quarry enters the battlefield tapped.${T}: Add {R} or {W} to your mana pool.| Sword of Dungeons and Dragons|Unstable|1|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from Rogues and from Clerics.$Whenever equipped creature deals combat damage to a player, create a 4/4 gold Dragon creature token with flying and roll a d20. If you roll a 20, repeat this process.$Equip {2}| Jhoira of the Ghitu|Duel Decks: Mind vs. Might|1|M|{1}{U}{R}|Legendary Creature - Human Wizard|2|2|{2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend.| Beacon of Tomorrows|Duel Decks: Mind vs. Might|2|R|{6}{U}{U}|Sorcery|||Target player takes an extra turn after this one. Shuffle Beacon of Tomorrows into its owner's library.| From 9038b6943f26480596d84150effe83a4e5fca2fb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 16:41:19 -0400 Subject: [PATCH 014/100] added XLN card info --- Utils/mtg-cards-data.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index afd40b0b4d..75c206201b 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32332,12 +32332,14 @@ Ashes of the Abhorrent|Ixalan|2|R|{1}{W}|Enchantment|||Players can't cast spells Bellowing Aegisaur|Ixalan|4|U|{5}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control.| Bishop of Rebirth|Ixalan|5|R|Creature - Vampire Cleric|3|4|Vigilance$Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.| Goring Ceratops|Ixalan|13|R|Creature - Dinosaur|3|3|Double strike$Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn.| +Ixalan's Binding|Ixalan|17|U|{3}{W}|Enchantment|||When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield.$Your opponents can't cast spells with the same name as the exiled card.| Kinjalli's Sunwing|Ixalan|19|R|{2}{W}|Creature - Dinosaur|2|3|Flying$Creatures your opponents control enter the battlefield tapped.| Mavren Fein, Dusk Apostle|Ixalan|24|R|{2}{W}|Legendary Creature - Vampire Cleric|2|2|Whenever one or more nontoken Vampires you control attack, create a 1/1 white Vampire creature token with lifelink.| Priest of the Wakening Sun|Ixalan|27|R|{W}|Creature - Human Cleric|1|1|At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life.${3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library.| Sanguine Sacrament|Ixalan|33|R|{X}{W}{W}|Instant|||You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library.| Settle the Wreckage|Ixalan|34|R|{2}{W}{W}|Instant|||Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library.| Tocatli Honor Guard|Ixalan|42|R|{1}{W}|Creature - Human Soldier|1|3|Creatures entering the battlefield don't cause abilities to trigger.| +Wakening Sun's Avatar|Ixalan|44|M|{5}{W}{W}{W}|Creature - Dinosaur Avatar|7|7|When Wakening Sun's Avatar enters the battlefield, if you cast if from you hand, destroy all non-Dinosaur creatures.| Arcane Adaptation|Ixalan|46|R|{2}{U}|Enchantment|||As Arcane Adaptation enters the battlefield, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| Daring Saboteur|Ixalan|49|R|{1}{U}|Creature - Human Pirate|2|1|{2}{U}: Daring Saboteur can't be blocked this turn.$Whenever Daring Saboteur deals combat damage to a player, you may draw a card. If you do, discard a card.| Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| @@ -32386,11 +32388,15 @@ Deadeye Plunderers|Ixalan|220|U|{3}{U}{B}|Creature - Human Pirate|3|3|Deadeye Pl Dire Fleet Captain|Ixalan|221|U|{B}{R}|Creature - Orc Pirate|2|2|Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate.| Gishath, Sun's Avatar|Ixalan|222|M|{5}{R}{G}{W}|Legendary Creature - Dinosaur Avatar|7|6|Trample, vigilance, haste$Whenever Gishath, Sun's Avatar deals combat damage to a player, reveal that many cards from the top of your library. Put any number of Dinosaur creature cards from among them onto the battlefield and the rest on the bottom of your library in a random order.| Hostage Taker|Ixalan|223|R|{2}{U}{B}|Creature - Human Pirate|2|3|When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.| +Huatli, Warrior Poet|Ixalan|224|M|{3}{R}{W}|Legendary Planeswalker - Huatli|||+2: You gain life equal to the greatest power among creatures you control.$0: Create a 3/3 green Dinosaur creature token with trample.$-X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn.| Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| +Primal Amulet|Ixalan|243|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| +Primal Wellspring|Ixalan|243|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| +Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| Treasure Cove|Ixalan|250|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| @@ -32406,12 +32412,12 @@ Jace, Ingenious Mind-Mage|Ixalan|280|M|{4}{U}{U}|Legendary Planeswalker - Jace|| Castaway's Despair|Ixalan|281|C|{3}{U}|Enchantment - Aura|||Enchant creature$When Castaway's Despair enters the battlefield, tap enchanted creature.$Enchanted creature doesn't untap during its controller's untap step.| Grasping Current|Ixalan|282|R|{4}{U}|Sorcery|||Return up to two target creature's to their owner's hand.$Search your library and/or graveyard for a card named Jace, Ingenious Mind-Mage, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| Jace's Sentinel|Ixalan|283|U|{1}{U}|Creature - Merfolk Warrior|1|3|As long as you control a Jace planeswalker, Jace's Sentinel gets +1/+0 and can't be blocked.| -Woodland Stream|Ixalan|284|U||Land|||Woodland Stream enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.| +Woodland Stream|Ixalan|284|C||Land|||Woodland Stream enters the battlefield tapped.${T}: Add {G} or {U} to your mana pool.| Huatli, Dinosaur Knight|Ixalan|285|M|{4}{R}{W}|Legendary Planeswalker - Huatli|||[+2]: Put two +1/+1 counters on up to one target Dinosaur you control.$[-3]: Target Dinosaur you control deals damage equal to its power to target creature you don't control.$[-7]: Dinosaurs you control get +4/+4 until end of turn.| Huatli's Snubhorn|Ixalan|286|C|{1}{W}|Creature - Dinosaur|2|2|Vigilance| Huatli's Spurring|Ixalan|287|U|{R}|Instant|||Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead.| Sun-Blessed Mount|Ixalan|288|R|{3}{R}{W}|Creature - Dinosaur|4|4|When Sun-Blessed Mount enters the battlefield, you may search your library and/or graveyard for a card named Huatli, Dinosaur Knight, reveal it, then put it into your hand. If you searched your library this way, shuffle it.| -Stone Quarry|Ixalan|289|U||Land|||Stone Quarry enters the battlefield tapped.${T}: Add {R} or {W} to your mana pool.| +Stone Quarry|Ixalan|289|C||Land|||Stone Quarry enters the battlefield tapped.${T}: Add {R} or {W} to your mana pool.| Sword of Dungeons and Dragons|Unstable|1|M|{3}|Artifact - Equipment|||Equipped creature gets +2/+2 and has protection from Rogues and from Clerics.$Whenever equipped creature deals combat damage to a player, create a 4/4 gold Dragon creature token with flying and roll a d20. If you roll a 20, repeat this process.$Equip {2}| Jhoira of the Ghitu|Duel Decks: Mind vs. Might|1|M|{1}{U}{R}|Legendary Creature - Human Wizard|2|2|{2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend.| Beacon of Tomorrows|Duel Decks: Mind vs. Might|2|R|{6}{U}{U}|Sorcery|||Target player takes an extra turn after this one. Shuffle Beacon of Tomorrows into its owner's library.| From 1cd91b3dd0fc7ff48e0ebef1fbf5b5e0aa766555 Mon Sep 17 00:00:00 2001 From: Christian Aldover Date: Mon, 4 Sep 2017 17:14:51 -0400 Subject: [PATCH 015/100] Update DeathlessAncient.java Updated notTarget from false to true --- Mage.Sets/src/mage/cards/d/DeathlessAncient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java index ef9e413d9e..eb88cb4450 100644 --- a/Mage.Sets/src/mage/cards/d/DeathlessAncient.java +++ b/Mage.Sets/src/mage/cards/d/DeathlessAncient.java @@ -69,7 +69,7 @@ public class DeathlessAncient extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand. - this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, false)))); + this.addAbility(new SimpleActivatedAbility(Zone.GRAVEYARD, new ReturnToHandSourceEffect(), new TapTargetCost(new TargetControlledPermanent(3, 3, filter, true)))); } From d0a4e5a420f5e730679e0aff867ccb1e8ba3bd8a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 17:29:45 -0400 Subject: [PATCH 016/100] Implemented Mavren Fein and Call to the Feast --- .../src/mage/cards/c/CallToTheFeast.java | 58 +++++++++ .../mage/cards/m/MavrenFeinDuskApostle.java | 123 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + .../permanent/token/IxalanVampireToken.java | 49 +++++++ 4 files changed, 232 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CallToTheFeast.java create mode 100644 Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java diff --git a/Mage.Sets/src/mage/cards/c/CallToTheFeast.java b/Mage.Sets/src/mage/cards/c/CallToTheFeast.java new file mode 100644 index 0000000000..9408afd4ef --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CallToTheFeast.java @@ -0,0 +1,58 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class CallToTheFeast extends CardImpl { + + public CallToTheFeast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{B}"); + + // Create three 1/1 white Vampire creature tokens with lifelink. + this.getSpellAbility().addEffect(new CreateTokenEffect(new IxalanVampireToken(), 3)); + } + + public CallToTheFeast(final CallToTheFeast card) { + super(card); + } + + @Override + public CallToTheFeast copy() { + return new CallToTheFeast(this); + } +} diff --git a/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java new file mode 100644 index 0000000000..d1b2227e0e --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MavrenFeinDuskApostle.java @@ -0,0 +1,123 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.IxalanVampireToken; + +/** + * + * @author TheElk801 + */ +public class MavrenFeinDuskApostle extends CardImpl { + + public MavrenFeinDuskApostle(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Vampire"); + this.subtype.add("Cleric"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever one or more nontoken Vampires you control attack, create a 1/1 white Vampire creature token with lifelink. + this.addAbility(new MavrenFeinDuskApostleTriggeredAbility()); + } + + public MavrenFeinDuskApostle(final MavrenFeinDuskApostle card) { + super(card); + } + + @Override + public MavrenFeinDuskApostle copy() { + return new MavrenFeinDuskApostle(this); + } +} + +class MavrenFeinDuskApostleTriggeredAbility extends TriggeredAbilityImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + filter.add(Predicates.not(new TokenPredicate())); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public MavrenFeinDuskApostleTriggeredAbility() { + super(Zone.BATTLEFIELD, new CreateTokenEffect(new IxalanVampireToken()), false); + } + + public MavrenFeinDuskApostleTriggeredAbility(final MavrenFeinDuskApostleTriggeredAbility ability) { + super(ability); + } + + @Override + public MavrenFeinDuskApostleTriggeredAbility copy() { + return new MavrenFeinDuskApostleTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + for (UUID creatureId : game.getCombat().getAttackers()) { + Permanent creature = game.getPermanent(creatureId); + if (creature != null && filter.match(creature, game)) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever one or more nontoken Vampires you control attack, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c44f72b5c5..0ae39db2f8 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -37,6 +37,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); + cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); @@ -58,6 +59,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); + cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java b/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java new file mode 100644 index 0000000000..acaa977a89 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/IxalanVampireToken.java @@ -0,0 +1,49 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.LifelinkAbility; + +/** + * + * @author TheElk801 + */ +public class IxalanVampireToken extends Token { + + public IxalanVampireToken() { + super("Vampire", "1/1 white Vampire creature token with lifelink"); + cardType.add(CardType.CREATURE); + color.setWhite(true); + subtype.add("Vampire"); + power = new MageInt(1); + toughness = new MageInt(1); + addAbility(LifelinkAbility.getInstance()); + } +} From 462daa89b414d2d84f6f3678a52454394400c216 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 17:38:51 -0400 Subject: [PATCH 017/100] Implemented Sentinel Totem --- Mage.Sets/src/mage/cards/s/SentinelTotem.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 2 files changed, 71 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SentinelTotem.java diff --git a/Mage.Sets/src/mage/cards/s/SentinelTotem.java b/Mage.Sets/src/mage/cards/s/SentinelTotem.java new file mode 100644 index 0000000000..81499265ba --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SentinelTotem.java @@ -0,0 +1,69 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ExileSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ExileGraveyardAllPlayersEffect; +import mage.abilities.effects.keyword.ScryEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class SentinelTotem extends CardImpl { + + public SentinelTotem(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + // When Sentinel Totem enters the battlefield, scry 1. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(1))); + + // {T}, Exile Sentinel Totem: Exile all cards from all graveyards. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileGraveyardAllPlayersEffect(), new TapSourceCost()); + ability.addCost(new ExileSourceCost()); + this.addAbility(ability); + } + + public SentinelTotem(final SentinelTotem card) { + super(card); + } + + @Override + public SentinelTotem copy() { + return new SentinelTotem(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0ae39db2f8..1eda9afe79 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -69,6 +69,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); + cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); @@ -80,6 +81,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); From b5e803d25d4b82168c8986b5d50ae9f1428693b6 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 17:43:26 -0400 Subject: [PATCH 018/100] Implemented Pillar of Origins --- .../src/mage/cards/p/PillarOfOrigins.java | 135 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 2 files changed, 137 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PillarOfOrigins.java diff --git a/Mage.Sets/src/mage/cards/p/PillarOfOrigins.java b/Mage.Sets/src/mage/cards/p/PillarOfOrigins.java new file mode 100644 index 0000000000..6aed375d7f --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PillarOfOrigins.java @@ -0,0 +1,135 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.abilities.mana.conditional.CreatureCastManaCondition; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class PillarOfOrigins extends CardImpl { + + public PillarOfOrigins(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // As Pillar of Origins enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Benefit))); + + // {T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type. + this.addAbility(new ConditionalAnyColorManaAbility(new TapSourceCost(), 1, new PillarOfOriginsManaBuilder(), true)); + } + + public PillarOfOrigins(final PillarOfOrigins card) { + super(card); + } + + @Override + public PillarOfOrigins copy() { + return new PillarOfOrigins(this); + } +} + +class PillarOfOriginsManaBuilder extends ConditionalManaBuilder { + + SubType creatureType; + + @Override + public ConditionalManaBuilder setMana(Mana mana, Ability source, Game game) { + SubType value = (SubType) game.getState().getValue(source.getSourceId() + "_type"); + if (value != null) { + creatureType = value; + } + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + game.informPlayers(controller.getLogName() + " produces " + mana.toString() + " with " + sourceObject.getLogName() + + " (can only be spent to cast creatures of type " + creatureType + ")"); + } + return super.setMana(mana, source, game); + } + + @Override + public ConditionalMana build(Object... options) { + return new PillarOfOriginsConditionalMana(this.mana, creatureType); + } + + @Override + public String getRule() { + return "Spend this mana only to cast a creature spell of the chosen type"; + } +} + +class PillarOfOriginsConditionalMana extends ConditionalMana { + + public PillarOfOriginsConditionalMana(Mana mana, SubType creatureType) { + super(mana); + staticText = "Spend this mana only to cast a creature spell of the chosen type"; + addCondition(new PillarOfOriginsManaCondition(creatureType)); + } +} + +class PillarOfOriginsManaCondition extends CreatureCastManaCondition { + + SubType creatureType; + + PillarOfOriginsManaCondition(SubType creatureType) { + this.creatureType = creatureType; + } + + @Override + public boolean apply(Game game, Ability source, UUID originalId, Cost costToPay) { + // check: ... to cast a creature spell + if (super.apply(game, source)) { + // check: ... of the chosen type + MageObject object = game.getObject(source.getSourceId()); + if (creatureType != null && object.hasSubtype(creatureType, game)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1eda9afe79..fcfea88b1a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -61,6 +61,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); + cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); @@ -81,6 +82,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); From 010a02a272a5e51d0026043ea75b192f7ef25900 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 17:48:33 -0400 Subject: [PATCH 019/100] Implemented Dire Fleet Captain --- .../src/mage/cards/d/DireFleetCaptain.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DireFleetCaptain.java diff --git a/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java new file mode 100644 index 0000000000..1c0b87f4ff --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DireFleetCaptain.java @@ -0,0 +1,78 @@ +/* + * 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.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class DireFleetCaptain extends CardImpl { + + private static final FilterAttackingCreature filter = new FilterAttackingCreature("other attacking Pirate"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new AnotherPredicate()); + } + + public DireFleetCaptain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{R}"); + + this.subtype.add("Orc"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Dire Fleet Captain attacks, it gets +1/+1 until end of turn for each other attacking Pirate. + PermanentsOnBattlefieldCount value = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(value, value, Duration.EndOfTurn, true), false)); + } + + public DireFleetCaptain(final DireFleetCaptain card) { + super(card); + } + + @Override + public DireFleetCaptain copy() { + return new DireFleetCaptain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index fcfea88b1a..9b18cfe43a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -45,6 +45,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); cards.add(new SetCardInfo("Deeproot Waters", 51, Rarity.UNCOMMON, mage.cards.d.DeeprootWaters.class)); + cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); @@ -59,6 +60,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); + cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); From d14658e27eb85da40e1d75311e1a1f8ba10089e7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 17:58:03 -0400 Subject: [PATCH 020/100] Implemented Deadeye Plunderers --- .../src/mage/cards/d/DeadeyePlunderers.java | 86 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 8 +- 2 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java diff --git a/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java b/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java new file mode 100644 index 0000000000..6c20494978 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadeyePlunderers.java @@ -0,0 +1,86 @@ +/* + * 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.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class DeadeyePlunderers extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifact you control"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public DeadeyePlunderers(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Deadeye Plunderers gets +1/+1 for each artifact you control. + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(count, count, Duration.WhileOnBattlefield))); + + // {2}{U}{B}: Create a colorless artifact token named Treasure with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new TreasureToken()), new ManaCostsImpl("{2}{U}{B}"))); + } + + public DeadeyePlunderers(final DeadeyePlunderers card) { + super(card); + } + + @Override + public DeadeyePlunderers copy() { + return new DeadeyePlunderers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 9b18cfe43a..e67fcb819c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -34,6 +34,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); + cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); @@ -41,6 +42,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); + cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); cards.add(new SetCardInfo("Deeproot Champion", 185, Rarity.RARE, mage.cards.d.DeeprootChampion.class)); @@ -49,6 +51,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); @@ -59,8 +62,6 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); - cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); - cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); @@ -83,9 +84,6 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); cards.add(new SetCardInfo("Treasure Cove", 1250, Rarity.RARE, mage.cards.t.TreasureCove.class)); cards.add(new SetCardInfo("Treasure Map", 250, Rarity.RARE, mage.cards.t.TreasureMap.class)); - cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); - cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); - cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Unclaimed Territory", 258, Rarity.UNCOMMON, mage.cards.u.UnclaimedTerritory.class)); cards.add(new SetCardInfo("Unfriendly Fire", 172, Rarity.COMMON, mage.cards.u.UnfriendlyFire.class)); cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); From fa9516533f6a1ef66bc4f577e4377b03a60b3f19 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 18:28:52 -0400 Subject: [PATCH 021/100] Implemented Tilonallis Skinshifter --- .../mage/cards/t/TilonallisSkinshifter.java | 119 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 120 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java diff --git a/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java b/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java new file mode 100644 index 0000000000..dd30193bd3 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TilonallisSkinshifter.java @@ -0,0 +1,119 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.functions.EmptyApplyToPermanent; + +/** + * + * @author TheElk801 + */ +public class TilonallisSkinshifter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(Predicates.not(new SupertypePredicate(SuperType.LEGENDARY))); + filter.add(new AttackingPredicate()); + filter.add(new AnotherPredicate()); + } + + public TilonallisSkinshifter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(0); + this.toughness = new MageInt(1); + + // Haste + this.addAbility(HasteAbility.getInstance()); + + // Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn. + Ability ability = new AttacksTriggeredAbility(new TilonallisSkinshifterCopyEffect(), false); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public TilonallisSkinshifter(final TilonallisSkinshifter card) { + super(card); + } + + @Override + public TilonallisSkinshifter copy() { + return new TilonallisSkinshifter(this); + } +} + +class TilonallisSkinshifterCopyEffect extends OneShotEffect { + + public TilonallisSkinshifterCopyEffect() { + super(Outcome.Copy); + this.staticText = "it becomes a copy of another target nonlegendary attacking creature until end of turn"; + } + + public TilonallisSkinshifterCopyEffect(final TilonallisSkinshifterCopyEffect effect) { + super(effect); + } + + @Override + public TilonallisSkinshifterCopyEffect copy() { + return new TilonallisSkinshifterCopyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (sourcePermanent != null && copyFromPermanent != null) { + game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index e67fcb819c..ce78c73266 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -79,6 +79,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); + cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); cards.add(new SetCardInfo("Tocatli Honor Guard", 42, Rarity.RARE, mage.cards.t.TocatliHonorGuard.class)); From 9e44a1f152cb77b34d72ceed83d2890f59da604e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 21:01:55 -0400 Subject: [PATCH 022/100] Implemented Huatli, Warrior Poet --- .../src/mage/cards/h/HuatliWarriorPoet.java | 176 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../game/permanent/token/DinosaurToken.java | 50 +++++ 3 files changed, 227 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java diff --git a/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java new file mode 100644 index 0000000000..51fa9e6ecd --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java @@ -0,0 +1,176 @@ +/* + * 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 java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.LoyaltyAbility; +import mage.abilities.Mode; +import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.PayVariableLoyaltyCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.GreatestPowerAmongControlledCreaturesValue; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.combat.CantBlockTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.DinosaurToken; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanentAmount; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class HuatliWarriorPoet extends CardImpl { + + public HuatliWarriorPoet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{R}{W}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add(SubType.HUATLI); + + this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); + + // +2: You gain life equal to the greatest power among creatures you control. + this.addAbility(new LoyaltyAbility(new GainLifeEffect(new GreatestPowerAmongControlledCreaturesValue(), "You gain life equal to the greatest power among creatures you control"), 2)); + + // 0: Create a 3/3 green Dinosaur creature token with trample. + this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DinosaurToken()), 0)); + + // -X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn. + Ability ability = new LoyaltyAbility(new HuatliWarriorPoetDamageEffect(new HuatliXValue())); + ability.addTarget(new TargetCreaturePermanentAmount(new HuatliXValue())); + this.addAbility(ability); + } + + public HuatliWarriorPoet(final HuatliWarriorPoet card) { + super(card); + } + + @Override + public HuatliWarriorPoet copy() { + return new HuatliWarriorPoet(this); + } +} + +class HuatliXValue implements DynamicValue { + + private static final HuatliXValue defaultValue = new HuatliXValue(); + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + for (Cost cost : sourceAbility.getCosts()) { + if (cost instanceof PayVariableLoyaltyCost) { + return ((PayVariableLoyaltyCost) cost).getAmount(); + } + } + return 0; + } + + @Override + public DynamicValue copy() { + return defaultValue; + } + + @Override + public String getMessage() { + return ""; + } + + @Override + public String toString() { + return "X"; + } + + public static HuatliXValue getDefault() { + return defaultValue; + } +} + +class HuatliWarriorPoetDamageEffect extends OneShotEffect { + + protected DynamicValue amount; + + public HuatliWarriorPoetDamageEffect(DynamicValue amount) { + super(Outcome.Damage); + this.amount = amount; + } + + public HuatliWarriorPoetDamageEffect(final HuatliWarriorPoetDamageEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public HuatliWarriorPoetDamageEffect copy() { + return new HuatliWarriorPoetDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!source.getTargets().isEmpty()) { + Target multiTarget = source.getTargets().get(0); + for (UUID target : multiTarget.getTargets()) { + Permanent permanent = game.getPermanent(target); + if (permanent != null && permanent.damage(multiTarget.getTargetAmount(target), source.getSourceId(), game, false, true) > 0) { + ContinuousEffect effect = new CantBlockTargetEffect(Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } + } + } + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "{source} deals " + + amount.toString() + + " damage divided as you choose among any number of target " + + mode.getTargets().get(0).getTargetName() + + ". Creatures dealt damage this way can't block this turn"; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index eeafaef0e0..279e9d29ba 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -59,6 +59,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); + cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java b/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java new file mode 100644 index 0000000000..8ba4b59073 --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/DinosaurToken.java @@ -0,0 +1,50 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; + +/** + * + * @author TheElk801 + */ +public class DinosaurToken extends Token { + + public DinosaurToken() { + super("Dinosaur", "3/3 green Dinosaur creature token with trample"); + cardType.add(CardType.CREATURE); + color.setGreen(true); + subtype.add(SubType.DINOSAUR); + power = new MageInt(3); + toughness = new MageInt(3); + addAbility(TrampleAbility.getInstance()); + } +} From db9922c16967b25ae1cf0cec2a937b25613f25b4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 4 Sep 2017 21:46:38 -0400 Subject: [PATCH 023/100] Implemented Primal Amulet and Primal Wellspring --- Mage.Sets/src/mage/cards/p/PrimalAmulet.java | 123 ++++++++++++++++++ .../src/mage/cards/p/PrimalWellspring.java | 121 +++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 3 files changed, 246 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PrimalAmulet.java create mode 100644 Mage.Sets/src/mage/cards/p/PrimalWellspring.java diff --git a/Mage.Sets/src/mage/cards/p/PrimalAmulet.java b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java new file mode 100644 index 0000000000..e62c449573 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrimalAmulet.java @@ -0,0 +1,123 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author TheElk801 + */ +public class PrimalAmulet extends CardImpl { + + private static final FilterCard filter = new FilterCard("Instant and sorcery spells"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.INSTANT), + new CardTypePredicate(CardType.SORCERY) + )); + } + + public PrimalAmulet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + this.transformable = true; + this.secondSideCardClazz = PrimalWellspring.class; + + // Instant and sorcery spells you cast cost {1} less to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(filter, 1))); + + // Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it. + this.addAbility(new TransformAbility()); + this.addAbility(new SpellCastControllerTriggeredAbility(new PrimalAmuletEffect(), new FilterInstantOrSorcerySpell(), false)); + } + + public PrimalAmulet(final PrimalAmulet card) { + super(card); + } + + @Override + public PrimalAmulet copy() { + return new PrimalAmulet(this); + } +} + +class PrimalAmuletEffect extends OneShotEffect { + + PrimalAmuletEffect() { + super(Outcome.Benefit); + this.staticText = "put a charge counter on {this}. " + + "Then if there are four or more charge counters on it, " + + "you may remove those counters and transform it"; + } + + PrimalAmuletEffect(final PrimalAmuletEffect effect) { + super(effect); + } + + @Override + public PrimalAmuletEffect copy() { + return new PrimalAmuletEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && player != null) { + permanent.addCounters(CounterType.CHARGE.createInstance(), source, game); + int counters = permanent.getCounters(game).getCount(CounterType.CHARGE); + if (counters > 3 && player.chooseUse(Outcome.Benefit, "Transform this?", source, game)) { + permanent.removeCounters("charge", counters, game); + new TransformSourceEffect(true).apply(game, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/p/PrimalWellspring.java b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java new file mode 100644 index 0000000000..fc8793547e --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PrimalWellspring.java @@ -0,0 +1,121 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CopyTargetSpellEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author TheElk801 + */ +public class PrimalWellspring extends CardImpl { + + public PrimalWellspring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.nightCard = true; + + // Add one mana of any color to your mana pool. + Ability ability = new AnyColorManaAbility(); + this.addAbility(ability); + + // When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy. + Effect effect = new CopyTargetSpellEffect(); + effect.setText("copy that spell and you may choose new targets for the copy"); + this.addAbility(new PyrimalWellspringTriggeredAbility(ability.getOriginalId(), effect)); + } + + public PrimalWellspring(final PrimalWellspring card) { + super(card); + } + + @Override + public PrimalWellspring copy() { + return new PrimalWellspring(this); + } +} + +class PyrimalWellspringTriggeredAbility extends TriggeredAbilityImpl { + + private final static FilterInstantOrSorcerySpell filter = new FilterInstantOrSorcerySpell(); + + String abilityOriginalId; + + public PyrimalWellspringTriggeredAbility(UUID abilityOriginalId, Effect effect) { + super(Zone.ALL, effect, true); + this.abilityOriginalId = abilityOriginalId.toString(); + } + + public PyrimalWellspringTriggeredAbility(final PyrimalWellspringTriggeredAbility ability) { + super(ability); + this.abilityOriginalId = ability.abilityOriginalId; + } + + @Override + public PyrimalWellspringTriggeredAbility copy() { + return new PyrimalWellspringTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.MANA_PAID; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getData().equals(abilityOriginalId)) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && filter.match(spell, getSourceId(), getControllerId(), game)) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When that mana is used to cast an instant or sorcery spell, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 279e9d29ba..1926d1cf2c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -67,6 +67,8 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); + cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); + cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); From b459e590addfbe3f27a63975e8fcd8549b6b3e68 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 11:19:35 +0200 Subject: [PATCH 024/100] * Atarka, World Render - Removed accidently added kicker ability (fixes #3935). --- Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java index 19b501fc9f..b9348f249a 100644 --- a/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java +++ b/Mage.Sets/src/mage/cards/a/AtarkaWorldRender.java @@ -30,12 +30,10 @@ package mage.cards.a; import java.util.UUID; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.costs.common.TapTargetCost; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.TrampleAbility; import mage.abilities.text.TextPartSubType; import mage.cards.CardImpl; @@ -48,7 +46,6 @@ import mage.filter.predicate.permanent.TappedPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; -import mage.target.common.TargetControlledCreaturePermanent; import mage.target.targetpointer.FixedTarget; /** @@ -75,7 +72,6 @@ public class AtarkaWorldRender extends CardImpl { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Dragon you control"); filter.add(new TextPartSubtypePredicate(textPart1)); filter.add(Predicates.not(new TappedPredicate())); - this.addAbility(new KickerAbility(new TapTargetCost(new TargetControlledCreaturePermanent(1, 1, filter, true)))); this.addAbility(new AtarkaWorldRenderEffect(filter)); } From 5bef2a4eebf5c931fc19498a260feb99870662d5 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 12:00:13 +0200 Subject: [PATCH 025/100] * Powder Keg - Fixed that the destroy ability did not work. --- Mage.Sets/src/mage/cards/p/PowderKeg.java | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Mage.Sets/src/mage/cards/p/PowderKeg.java b/Mage.Sets/src/mage/cards/p/PowderKeg.java index 25dacb3504..b0a087c32b 100644 --- a/Mage.Sets/src/mage/cards/p/PowderKeg.java +++ b/Mage.Sets/src/mage/cards/p/PowderKeg.java @@ -38,10 +38,15 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.ComparisonType; import mage.constants.Outcome; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.game.permanent.Permanent; @@ -58,8 +63,8 @@ public class PowderKeg extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.FUSE.createInstance(), true), TargetController.YOU, true)); // {T}, Sacrifice Powder Keg: Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on Powder Keg. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PowderKegEffect(), new SacrificeSourceCost()); - ability.addCost(new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PowderKegEffect(), new TapSourceCost()); + ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); } @@ -77,7 +82,7 @@ class PowderKegEffect extends OneShotEffect { public PowderKegEffect() { super(Outcome.DestroyPermanent); - staticText = "Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on Powder Keg {this}"; + staticText = "Destroy each artifact and creature with converted mana cost equal to the number of fuse counters on {this}"; } public PowderKegEffect(final PowderKegEffect effect) { @@ -86,22 +91,17 @@ class PowderKegEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent p = game.getBattlefield().getPermanent(source.getSourceId()); - if (p == null) { - p = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (p == null) { - return false; - } + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (sourcePermanent == null) { + return false; } - - int count = p.getCounters(game).getCount(CounterType.FUSE); - for (Permanent perm : game.getBattlefield().getAllActivePermanents()) { - if (perm.getConvertedManaCost() == count && ((perm.isArtifact()) - || (perm.isCreature()))) { - perm.destroy(source.getSourceId(), game, false); - } + int count = sourcePermanent.getCounters(game).getCount(CounterType.FUSE); + FilterPermanent filter = new FilterPermanent(); + filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.CREATURE))); + filter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, count)); + for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + perm.destroy(source.getSourceId(), game, false); } - return true; } From cd9827300deadb0cce533c1a8ebc9d6b1e397495 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 12:00:42 +0200 Subject: [PATCH 026/100] Some minor changes. --- Mage.Server/src/main/java/mage/server/UserManager.java | 6 +++--- Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 298914c94f..2b9efb3a4d 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -196,7 +196,7 @@ public enum UserManager { Calendar calendarRemove = Calendar.getInstance(); calendarRemove.add(Calendar.MINUTE, -8); List toRemove = new ArrayList<>(); - logger.info("Start Check Expired"); + logger.debug("Start Check Expired"); ArrayList userList = new ArrayList<>(); final Lock r = lock.readLock(); r.lock(); @@ -227,7 +227,7 @@ public enum UserManager { handleException(ex); } } - logger.info("Users to remove " + toRemove.size()); + logger.debug("Users to remove " + toRemove.size()); final Lock w = lock.readLock(); w.lock(); try { @@ -237,7 +237,7 @@ public enum UserManager { } finally { w.unlock(); } - logger.info("End Check Expired"); + logger.debug("End Check Expired"); } catch (Exception ex) { handleException(ex); } diff --git a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java index 93d012fc42..261f27f1fe 100644 --- a/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java +++ b/Mage.Sets/src/mage/cards/c/CaughtInTheBrights.java @@ -64,7 +64,7 @@ public class CaughtInTheBrights extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.LoseAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); From 63dc2938359ede6f76e3dc1439c7d8d02f0b1b2f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 09:53:17 -0400 Subject: [PATCH 027/100] Added XLN spoilers --- .../src/mage/cards/h/HeadwaterSentries.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 3 + Utils/mtg-cards-data.txt | 6 ++ 3 files changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HeadwaterSentries.java diff --git a/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java b/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java new file mode 100644 index 0000000000..26b86e7e65 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HeadwaterSentries.java @@ -0,0 +1,59 @@ +/* + * 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 java.util.UUID; +import mage.MageInt; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class HeadwaterSentries extends CardImpl { + + public HeadwaterSentries(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Warrior"); + this.power = new MageInt(2); + this.toughness = new MageInt(5); + } + + public HeadwaterSentries(final HeadwaterSentries card) { + super(card); + } + + @Override + public HeadwaterSentries copy() { + return new HeadwaterSentries(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 1926d1cf2c..2b7821d642 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -57,6 +57,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); + cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); @@ -81,6 +82,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); + cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); @@ -96,5 +98,6 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); + cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 75c206201b..7deb2bdda2 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32346,10 +32346,12 @@ Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spe Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| +Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| +Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| @@ -32361,13 +32363,16 @@ Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponen Ruin Raider|Ixalan|118|R|{2}{B}|Creature - Orc Pirate|3|2|Raid — At the beginning of your end step, if you attacked with a creature this turn, reveal the top card of your library and put that card into your hand. You lose life equal to the card's converted mana cost.| Vraska's Contempt|Ixalan|129|R|{2}{B}{B}|Instant|||Exile target creature or planeswalker. You gain 2 life.| Walk the Plank|Ixalan|130|U|{B}{B}|Sorcery|||Destroy target non-Merfolk creature.| +Wanted Scoundrels|Ixalan|131|U|{1}{B}|Creature - Human Pirate|4|3|When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| Angrath's Marauders|Ixalan|132|R|{5}{R}{R}|Creature - Human Pirate|4|4|If a source you control would deal damage to a permanent or player, it deals double that damage to that permanent or player instead.| Burning Sun's Avatar|Ixalan|135|R|{3}{R}{R}{R}|Creature - Dinosaur Avatar|6|6|When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.| Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2|Haste$Whenever Captain lannery Storm attacks, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Whenever you sacrifice a Treasure, Captain Lannery Storm gets +1/+0 until end of turn.| +Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| Sun-Crowned Hunters|Ixalan|164|C|{4}{R}{R}|Creature - Dinosaur|5|4|Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent.| Sunbird's Invocation|Ixalan|165|R|{5}{R}|Enchantment|||Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order.| +Drover of the Mighty|Ixalan|167|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn.| Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to target creature or player.| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| @@ -32391,6 +32396,7 @@ Hostage Taker|Ixalan|223|R|{2}{U}{B}|Creature - Human Pirate|2|3|When Hostage Ta Huatli, Warrior Poet|Ixalan|224|M|{3}{R}{W}|Legendary Planeswalker - Huatli|||+2: You gain life equal to the greatest power among creatures you control.$0: Create a 3/3 green Dinosaur creature token with trample.$-X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn.| Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| +Shapers of Nature|Ixalan|228|U|{1}{G}{U}|Creature - Merfolk Shaman|3|3|{3}{G}: Put a +1/+1 counter on target creature.${2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| From b2496e3d7f077f42e0d85fdd55f85d98240c3a2b Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 16:19:53 +0200 Subject: [PATCH 028/100] Fixed Vintage restricted list. --- .../Mage.Deck.Constructed/src/mage/deck/Vintage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java index 94c0fcf3e3..579418d570 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java @@ -94,7 +94,7 @@ public class Vintage extends Constructed { restricted.add("Memory Jar"); restricted.add("Merchant Scroll"); restricted.add("Mind's Desire"); - restricted.add("Monastery Mentory") + restricted.add("Monastery Mentory"); restricted.add("Mox Emerald"); restricted.add("Mox Jet"); restricted.add("Mox Pearl"); @@ -105,7 +105,7 @@ public class Vintage extends Constructed { restricted.add("Ponder"); restricted.add("Sol Ring"); restricted.add("Strip Mine"); - restricted.add("Thorn of Amethyst") + restricted.add("Thorn of Amethyst"); restricted.add("Time Vault"); restricted.add("Time Walk"); restricted.add("Timetwister"); From 27ad3329b6a699e16671ca555cb2bac93ec0852e Mon Sep 17 00:00:00 2001 From: Jeff Date: Tue, 5 Sep 2017 09:20:31 -0500 Subject: [PATCH 029/100] - Fixed Vintage.java missing semi-colons. --- .../Mage.Deck.Constructed/src/mage/deck/Vintage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java index 94c0fcf3e3..579418d570 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Vintage.java @@ -94,7 +94,7 @@ public class Vintage extends Constructed { restricted.add("Memory Jar"); restricted.add("Merchant Scroll"); restricted.add("Mind's Desire"); - restricted.add("Monastery Mentory") + restricted.add("Monastery Mentory"); restricted.add("Mox Emerald"); restricted.add("Mox Jet"); restricted.add("Mox Pearl"); @@ -105,7 +105,7 @@ public class Vintage extends Constructed { restricted.add("Ponder"); restricted.add("Sol Ring"); restricted.add("Strip Mine"); - restricted.add("Thorn of Amethyst") + restricted.add("Thorn of Amethyst"); restricted.add("Time Vault"); restricted.add("Time Walk"); restricted.add("Timetwister"); From 0ce13bf676f8f7a0f9d4def87a91c0fed482686a Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 16:20:58 +0200 Subject: [PATCH 030/100] * Grenzo, Havoc Raiser - Fixed that blocked the game. --- .../src/mage/cards/g/GrenzoHavocRaiser.java | 4 ++-- .../combat/AttacksIfAbleTargetEffect.java | 4 ++-- .../common/combat/CantAttackYouEffect.java | 14 +------------- .../common/combat/GoadTargetEffect.java | 19 +++++++++++++------ 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java index bf163641dc..60786e5e2e 100644 --- a/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java +++ b/Mage.Sets/src/mage/cards/g/GrenzoHavocRaiser.java @@ -54,7 +54,7 @@ import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.ExileZone; import mage.game.Game; -import mage.game.events.DamageEvent; +import mage.game.events.DamagedEvent; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.ManaPoolItem; @@ -125,7 +125,7 @@ class GrenzoHavocRaiserTriggeredAbility extends TriggeredAbilityImpl { Player damagedPlayer = game.getPlayer(event.getPlayerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); if (damagedPlayer != null && permanent != null - && ((DamageEvent) event).isCombatDamage() + && ((DamagedEvent) event).isCombatDamage() && getControllerId().equals(permanent.getControllerId())) { FilterCreaturePermanent filter = new FilterCreaturePermanent("creature " + damagedPlayer.getLogName() + " controls"); filter.add(new ControllerIdPredicate(damagedPlayer.getId())); diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java index cc9600fb9c..6a5f2e3d90 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/AttacksIfAbleTargetEffect.java @@ -74,9 +74,9 @@ public class AttacksIfAbleTargetEffect extends RequirementEffect { return staticText; } if (this.duration == Duration.EndOfTurn) { - return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks this turn if able").toString(); + return "Target " + mode.getTargets().get(0).getTargetName() + " attacks this turn if able"; } else { - return new StringBuilder("Target ").append(mode.getTargets().get(0).getTargetName()).append(" attacks each turn if able").toString(); + return "Target " + mode.getTargets().get(0).getTargetName() + " attacks each turn if able"; } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java index 42907477df..314897ecba 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/CantAttackYouEffect.java @@ -40,15 +40,8 @@ import mage.game.permanent.Permanent; */ public class CantAttackYouEffect extends RestrictionEffect { - private boolean canAttackYouAnyway = false; - public CantAttackYouEffect(Duration duration) { - this(duration, false); - } - - public CantAttackYouEffect(Duration duration, boolean canAttackYouAnyway) { super(duration); - this.canAttackYouAnyway = canAttackYouAnyway; } public CantAttackYouEffect(final CantAttackYouEffect effect) { @@ -67,11 +60,6 @@ public class CantAttackYouEffect extends RestrictionEffect { @Override public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) { - for (UUID player : game.getOpponents(source.getId())) { - if (attacker.canAttack(player, game)) { - return false; - } - } - return !canAttackYouAnyway; + return !defenderId.equals(source.getControllerId()); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java index 8384f291b9..5b5a7b55dd 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -33,6 +33,8 @@ import mage.abilities.effects.OneShotEffect; import mage.constants.Duration; import mage.constants.Outcome; import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.targetpointer.FixedTarget; /** @@ -63,12 +65,17 @@ public class GoadTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); - effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); - game.addEffect(effect, source); - effect = new CantAttackYouEffect(Duration.UntilYourNextTurn, true); - effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); - game.addEffect(effect, source); + Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + Player controller = game.getPlayer(source.getControllerId()); + if (targetCreature != null && controller != null) { + ContinuousEffect effect = new AttacksIfAbleTargetEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); + game.addEffect(effect, source); + effect = new CantAttackYouEffect(Duration.UntilYourNextTurn); + effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); + game.addEffect(effect, source); + game.informPlayers(controller.getLogName() + " is goating " + targetCreature.getLogName()); + } return true; } } From 3af9bd894fb56a83357a00b4f2a1ce0203ad18d6 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 16:31:44 +0200 Subject: [PATCH 031/100] * Vision Charm - Fixed bug that caused exception. --- Mage.Sets/src/mage/cards/v/VisionCharm.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Mage.Sets/src/mage/cards/v/VisionCharm.java b/Mage.Sets/src/mage/cards/v/VisionCharm.java index fea2422cbe..242851a45b 100644 --- a/Mage.Sets/src/mage/cards/v/VisionCharm.java +++ b/Mage.Sets/src/mage/cards/v/VisionCharm.java @@ -102,6 +102,8 @@ class VisionCharmEffect extends ContinuousEffectImpl { public VisionCharmEffect(final VisionCharmEffect effect) { super(effect); + targetLandType = effect.targetLandType; + targetBasicLandType = effect.targetBasicLandType; } @Override @@ -120,8 +122,13 @@ class VisionCharmEffect extends ContinuousEffectImpl { choice = new ChoiceBasicLandType(); controller.choose(outcome, choice, game); targetBasicLandType = choice.getChoice(); + if (targetLandType == null || targetBasicLandType == null) { + this.discard(); + return; + } } else { this.discard(); + return; } FilterPermanent filter = new FilterLandPermanent(); filter.add(new SubtypePredicate(SubType.byDescription(targetLandType))); From 466e524d6ef461806fe7fd0dcffecab7c08531b9 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 16:39:43 +0200 Subject: [PATCH 032/100] Fixed possible exception during draft player repplacement. --- .../main/java/mage/game/draft/DraftImpl.java | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index 702ae547fe..409bc796f0 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,14 +20,14 @@ * 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.game.draft; +import java.util.*; import mage.cards.Card; import mage.cards.ExpansionSet; import mage.game.draft.DraftOptions.TimingOption; @@ -36,8 +36,6 @@ import mage.game.events.TableEvent.EventType; import mage.players.Player; import mage.players.PlayerList; -import java.util.*; - /** * * @author BetaSteward_at_googlemail.com @@ -89,9 +87,9 @@ public abstract class DraftImpl implements Draft { DraftPlayer newDraftPlayer = new DraftPlayer(newPlayer); DraftPlayer oldDraftPlayer = players.get(oldPlayer.getId()); newDraftPlayer.setBooster(oldDraftPlayer.getBooster()); - Map newPlayers = new LinkedHashMap<>(); + Map newPlayers = new LinkedHashMap<>(); synchronized (players) { - for(Map.Entry entry :players.entrySet()) { + for (Map.Entry entry : players.entrySet()) { if (entry.getKey().equals(oldPlayer.getId())) { newPlayers.put(newPlayer.getId(), newDraftPlayer); } else { @@ -99,7 +97,7 @@ public abstract class DraftImpl implements Draft { } } players.clear(); - for (Map.Entry entry: newPlayers.entrySet()) { + for (Map.Entry entry : newPlayers.entrySet()) { players.put(entry.getKey(), entry.getValue()); } } @@ -109,7 +107,7 @@ public abstract class DraftImpl implements Draft { currentId = newPlayer.getId(); } table.clear(); - for(UUID playerId : players.keySet()) { + for (UUID playerId : players.keySet()) { table.add(playerId); } @@ -117,7 +115,9 @@ public abstract class DraftImpl implements Draft { } if (oldDraftPlayer.isPicking()) { newDraftPlayer.setPicking(); - newDraftPlayer.getPlayer().pickCard(newDraftPlayer.getBooster(), newDraftPlayer.getDeck(), this); + if (!newDraftPlayer.getBooster().isEmpty()) { + newDraftPlayer.getPlayer().pickCard(newDraftPlayer.getBooster(), newDraftPlayer.getDeck(), this); + } } return true; } @@ -143,7 +143,7 @@ public abstract class DraftImpl implements Draft { /** * Number of boosters that each player gets in this draft - * + * * @return */ @Override @@ -151,7 +151,6 @@ public abstract class DraftImpl implements Draft { return numberBoosters; } - @Override public List getSets() { return sets; @@ -219,10 +218,9 @@ public abstract class DraftImpl implements Draft { } } - protected void openBooster() { if (boosterNum < numberBoosters) { - for (DraftPlayer player: players.values()) { + for (DraftPlayer player : players.values()) { if (draftCube != null) { player.setBooster(draftCube.createBooster()); } else { @@ -237,25 +235,26 @@ public abstract class DraftImpl implements Draft { protected boolean pickCards() { cardNum++; - for (DraftPlayer player: players.values()) { + for (DraftPlayer player : players.values()) { if (player.getBooster().isEmpty()) { return false; } player.setPicking(); player.getPlayer().pickCard(player.getBooster(), player.getDeck(), this); } - synchronized(this) { + synchronized (this) { while (!donePicking()) { try { this.wait(); - } catch (InterruptedException ex) { } + } catch (InterruptedException ex) { + } } } return true; } protected boolean donePicking() { - if(isAbort()) { + if (isAbort()) { return true; } return players.values() @@ -304,14 +303,14 @@ public abstract class DraftImpl implements Draft { public boolean addPick(UUID playerId, UUID cardId, Set hiddenCards) { DraftPlayer player = players.get(playerId); if (player.isPicking()) { - for (Card card: player.booster) { + for (Card card : player.booster) { if (card.getId().equals(cardId)) { player.addPick(card, hiddenCards); player.booster.remove(card); break; } } - synchronized(this) { + synchronized (this) { this.notifyAll(); } } @@ -341,7 +340,7 @@ public abstract class DraftImpl implements Draft { @Override public void resetBufferedCards() { Set setsDone = new HashSet<>(); - for(ExpansionSet set: sets) { + for (ExpansionSet set : sets) { if (!setsDone.contains(set)) { set.removeSavedCards(); setsDone.add(set); @@ -350,5 +349,4 @@ public abstract class DraftImpl implements Draft { } - } From d5284ae226601b843ea0143e7c9bb80331623c51 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 16:58:06 +0200 Subject: [PATCH 033/100] Fixed that some user data was not cleared as a user was disconnected. --- Mage.Server/src/main/java/mage/server/User.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 985b8fc708..e1f0abd8fd 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -388,7 +388,7 @@ public class User { } else { // Table is missing after connection was lost during sideboard. // Means other players were removed or conceded the game? - logger.error("sideboarding id not found : " + entry.getKey()); + logger.debug(getName() + " reconnects during sideboarding but tableId not found: " + entry.getKey()); } } ServerMessagesUtil.instance.incReconnects(); @@ -450,12 +450,14 @@ public class User { TournamentManager.instance.quit(tournamentId, userId); } userTournaments.clear(); + constructing.clear(); logger.trace("REMOVE " + userName + " Tables " + tables.size()); for (Entry entry : tables.entrySet()) { logger.debug("-- leave tableId: " + entry.getValue().getId()); TableManager.instance.leaveTable(userId, entry.getValue().getId()); } tables.clear(); + sideboarding.clear(); logger.trace("REMOVE " + userName + " Game sessions: " + gameSessions.size()); for (GameSessionPlayer gameSessionPlayer : gameSessions.values()) { logger.debug("-- kill game session of gameId: " + gameSessionPlayer.getGameId()); From 1fe26f14090df7c98af80f825247fd9a4b4c8016 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 5 Sep 2017 11:33:43 -0400 Subject: [PATCH 034/100] Implemented Goring Ceratops --- .../src/mage/cards/g/GoringCeratops.java | 74 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 75 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoringCeratops.java diff --git a/Mage.Sets/src/mage/cards/g/GoringCeratops.java b/Mage.Sets/src/mage/cards/g/GoringCeratops.java new file mode 100644 index 0000000000..0a05aa811d --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoringCeratops.java @@ -0,0 +1,74 @@ +/* + * 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.g; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.filter.StaticFilters; + +/** + * + * @author caldover + */ +public class GoringCeratops extends CardImpl { + + public GoringCeratops(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Double Strike + this.addAbility(DoubleStrikeAbility.getInstance()); + + // Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn. + Effect effect = new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE, true); + effect.setText("other creatures you control gain double strike"); + Ability ability = new AttacksTriggeredAbility(effect, false); + this.addAbility(ability); + } + + public GoringCeratops(final GoringCeratops card) { + super(card); + } + + @Override + public GoringCeratops copy() { + return new GoringCeratops(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2b7821d642..867240b77a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -57,6 +57,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); + cards.add(new SetCardInfo("Goring Certatops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); From 8221a68efef88ec196de1ac07721de1032fc99b3 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 5 Sep 2017 17:53:03 +0200 Subject: [PATCH 035/100] Minor fix for user handling. --- .../java/mage/server/tournament/TournamentSession.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java index cf4b16ee86..8819f262ec 100644 --- a/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java +++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentSession.java @@ -170,9 +170,11 @@ public class TournamentSession { } private void removeTournamentForUser() { - UserManager.instance.getUser(userId).ifPresent(user - -> user.removeTournament(playerId)); - + Optional user = UserManager.instance.getUser(userId); + if (user.isPresent()) { + user.get().removeTable(playerId); + user.get().removeTournament(playerId); + } } } From 97e34dab4905cf92dfc5071634d79c29234c52f0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 10:15:40 -0400 Subject: [PATCH 036/100] Added Explore event --- .../mage/abilities/effects/keyword/ExploreSourceEffect.java | 2 ++ Mage/src/main/java/mage/game/events/GameEvent.java | 1 + 2 files changed, 3 insertions(+) diff --git a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java index b161c9578b..e6ea352256 100644 --- a/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/keyword/ExploreSourceEffect.java @@ -39,6 +39,7 @@ import mage.counters.CounterType; import mage.filter.FilterCard; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; @@ -75,6 +76,7 @@ public class ExploreSourceEffect extends OneShotEffect { if (player == null) { return false; } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXPLORED, source.getSourceId(), source.getSourceId(), source.getControllerId())); if (player.getLibrary().hasCards()) { Card card = player.getLibrary().getFromTop(game); Cards cards = new CardsImpl(); diff --git a/Mage/src/main/java/mage/game/events/GameEvent.java b/Mage/src/main/java/mage/game/events/GameEvent.java index 5033931abc..b6b65c4847 100644 --- a/Mage/src/main/java/mage/game/events/GameEvent.java +++ b/Mage/src/main/java/mage/game/events/GameEvent.java @@ -91,6 +91,7 @@ public class GameEvent implements Serializable { EMPTY_DRAW, DRAW_CARDS, // applies to an instruction to draw more than one card before any replacement effects apply to individual cards drawn DRAW_CARD, DREW_CARD, + EXPLORED, MIRACLE_CARD_REVEALED, MADNESS_CARD_EXILED, INVESTIGATED, From ede69d2ce9993d0e00a50ebc9c063323fdfecbc0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 10:29:28 -0400 Subject: [PATCH 037/100] Implemented Jace's Sentinel --- Mage.Sets/src/mage/cards/j/JacesSentinel.java | 91 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 2 files changed, 93 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/j/JacesSentinel.java diff --git a/Mage.Sets/src/mage/cards/j/JacesSentinel.java b/Mage.Sets/src/mage/cards/j/JacesSentinel.java new file mode 100644 index 0000000000..711ea8b814 --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JacesSentinel.java @@ -0,0 +1,91 @@ +/* + * 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.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author TheElk801 + */ +public class JacesSentinel extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Jace planeswalker"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.JACE)); + } + + public JacesSentinel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Warrior"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // As long as you control a Jace planeswalker, Jace's Sentinel gets +1/+0 and can't be blocked. + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( + new BoostSourceEffect(1, 0, Duration.WhileOnBattlefield), + new PermanentsOnTheBattlefieldCondition(filter), + "As long as you control a Jace planeswalker, {this} gets +1/+0")); + ability.addEffect(new ConditionalContinuousEffect( + new CantBeBlockedSourceEffect(), + new PermanentsOnTheBattlefieldCondition(filter), + "and has can't be blocked")); + } + + public JacesSentinel(final JacesSentinel card) { + super(card); + } + + @Override + public JacesSentinel copy() { + return new JacesSentinel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2b7821d642..388e21fb95 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -61,9 +61,11 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); + cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); From 9a2972f82fef04b0ef1526469d7eecf29b26a038 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 10:31:28 -0400 Subject: [PATCH 038/100] Implemented Huatli's Snubhorn --- .../src/mage/cards/h/HuatlisSnubhorn.java | 63 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 64 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java diff --git a/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java new file mode 100644 index 0000000000..5ea7d6a700 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java @@ -0,0 +1,63 @@ +/* + * 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 java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class HuatlisSnubhorn extends CardImpl { + + public HuatlisSnubhorn(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + } + + public HuatlisSnubhorn(final HuatlisSnubhorn card) { + super(card); + } + + @Override + public HuatlisSnubhorn copy() { + return new HuatlisSnubhorn(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 388e21fb95..6e017ae197 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -59,6 +59,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); + cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); From 1937ea4f89d487ef2f7831ab9f4b900caaf5a857 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 10:35:54 -0400 Subject: [PATCH 039/100] Implemented Drover of the Mighty --- .../src/mage/cards/d/DroverOfTheMighty.java | 78 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java diff --git a/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java new file mode 100644 index 0000000000..ca6476f76f --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DroverOfTheMighty.java @@ -0,0 +1,78 @@ +/* + * 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.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostSourceWhileControlsEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class DroverOfTheMighty extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Dinosaur"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public DroverOfTheMighty(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Human"); + this.subtype.add("Druid"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Drover of the Mighty gets +2/+2 as long as you control a Dinosaur. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceWhileControlsEffect(filter, 2, 2))); + + // {T}: Add one mana of any color to your mana pool. + this.addAbility(new AnyColorManaAbility()); + } + + public DroverOfTheMighty(final DroverOfTheMighty card) { + super(card); + } + + @Override + public DroverOfTheMighty copy() { + return new DroverOfTheMighty(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 6e017ae197..341ccdce52 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -51,6 +51,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dire Fleet Captain", 221, Rarity.UNCOMMON, mage.cards.d.DireFleetCaptain.class)); cards.add(new SetCardInfo("Dragonskull Summit", 252, Rarity.RARE, mage.cards.d.DragonskullSummit.class)); cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); + cards.add(new SetCardInfo("Drover of the Mighty", 167, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); From c8013bb3ca221838f703f8796c8cfc2f432c1073 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 13:26:54 -0400 Subject: [PATCH 040/100] updated XLN spoilers --- Utils/mtg-cards-data.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 7deb2bdda2..0339c0f04f 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32342,6 +32342,7 @@ Tocatli Honor Guard|Ixalan|42|R|{1}{W}|Creature - Human Soldier|1|3|Creatures en Wakening Sun's Avatar|Ixalan|44|M|{5}{W}{W}{W}|Creature - Dinosaur Avatar|7|7|When Wakening Sun's Avatar enters the battlefield, if you cast if from you hand, destroy all non-Dinosaur creatures.| Arcane Adaptation|Ixalan|46|R|{2}{U}|Enchantment|||As Arcane Adaptation enters the battlefield, choose a creature type.$Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.| Daring Saboteur|Ixalan|49|R|{1}{U}|Creature - Human Pirate|2|1|{2}{U}: Daring Saboteur can't be blocked this turn.$Whenever Daring Saboteur deals combat damage to a player, you may draw a card. If you do, discard a card.| +Deadeye Quartermaster|Ixalan|50|U|{3}{U}|Creature - Human Pirate|2|2|When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library.| Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| @@ -32349,6 +32350,7 @@ Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creat Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| +Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| @@ -32358,9 +32360,11 @@ Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid &md Deadeye Tracker|Ixalan|99|R|{B}|Creature - Human Pirate|1|1|{1}{B}, {T}: Exile two target cards from an opponent's graveyard. Deadeye Tracker explores.| Deathless Ancient|Ixalan|100|U|{4}{B}{B}|Creature - Vampire Knight|4|4|Flying$Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand.| Fathom Fleet Captain|Ixalan|106|R|{1}{B}|Creature - Human Pirate|2|1|Menace$Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace.| +Kitesail Freebooter|Ixalan|110|U|{1}{B}|Creature - Human Pirate|1|2|Flying$When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield.| Queen's Bay Soldier|Ixalan|115|C|{1}{B}|Creature - Vampire Soldier|2|2|| Revel in Riches|Ixalan|117|R|{4}{B}|Enchantment|||Whenever a creature an opponent controls dies, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$At the beginning of your upkeep, if you control ten or more Treasures, you win the game.| Ruin Raider|Ixalan|118|R|{2}{B}|Creature - Orc Pirate|3|2|Raid — At the beginning of your end step, if you attacked with a creature this turn, reveal the top card of your library and put that card into your hand. You lose life equal to the card's converted mana cost.| +Sanctum Seeker|Ixalan|120|R|{2}{B}{B}|Creature - Vampire Knight|3|4|Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life.| Vraska's Contempt|Ixalan|129|R|{2}{B}{B}|Instant|||Exile target creature or planeswalker. You gain 2 life.| Walk the Plank|Ixalan|130|U|{B}{B}|Sorcery|||Destroy target non-Merfolk creature.| Wanted Scoundrels|Ixalan|131|U|{1}{B}|Creature - Human Pirate|4|3|When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool."| @@ -32398,13 +32402,18 @@ Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At th Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| Shapers of Nature|Ixalan|228|U|{1}{G}{U}|Creature - Merfolk Shaman|3|3|{3}{G}: Put a +1/+1 counter on target creature.${2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| +Conqueror's Galleon|Ixalan|234|R|{4}|Artifact - Vehicle|2|10|When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.$Crew 4| +Conqueror's Foothold|Ixalan|234|R||Land|||{T}: Add {C} to your mana pool.${2}, {T}: Draw a card, then discard a card.${4}, {T}: Draw a card.${6}, {T}: Return target card from your graveyard to your hand.| Dusk Legion Dreadnought|Ixalan|236|U|{5}|Artifact - Vehicle|4|6|Vigilance$Crew 2| Pillar of Origins|Ixalan|241|U|{2}|Artifact|||As Pillar of Origins enters the battlefield, choose a creature type.${T}: Add one mana of any color to your mana pool. Spend this mana only to cast a creature spell if the chosen type.| +Pirate's Cutlass|Ixalan|242|C|{3}|Artifact - Equipment|||When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control.$Equipped creature gets +2/+1.$Equip 2| Primal Amulet|Ixalan|243|R|{4}|Artifact|||Instant and sorcery spells you cast cost {1} less to cast.$Whenever you cast an instant or sorcery spell, put a charge counter on Primal Amulet. Then if there are four or more charge counters on it, you may remove those counters and transform it.| Primal Wellspring|Ixalan|243|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| +Thaumatic Compass|Ixalan|249|R|{2}|Artifact|||{3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.$At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass.| +Spires of Orazca|Ixalan|249|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| Treasure Cove|Ixalan|250|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| Treasure Map|Ixalan|250|R|{2}|Artifact|||{1}, {T}: Scry 1. Put a landmark counter on Treasure Map. Then if there are three or more landmark counters on it, remove those counters, transform Treasure Map, and create three colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Vanquisher's Banner|Ixalan|251|R|{5}|Artifact|||As Vanquisher's Banner enters the battlefield, choose a creature type.$Creatures you control of the chosen type get +1/+1.$Whenever you cast a creature spell of the chosen type, draw a card.| From 94b62c5c0467cc87adccd3af78f5aad0a9cb5175 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 13:48:08 -0400 Subject: [PATCH 041/100] Implemented Deadeye Quartermaster --- .../mage/cards/d/DeadeyeQuartermaster.java | 76 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 3 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java diff --git a/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java new file mode 100644 index 0000000000..c51e6b9da0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadeyeQuartermaster.java @@ -0,0 +1,76 @@ +/* + * 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.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class DeadeyeQuartermaster extends CardImpl { + + private static final FilterCard filter = new FilterCard("an Equipment or Vehicle card"); + + static { + filter.add(Predicates.or(new SubtypePredicate(SubType.EQUIPMENT), new SubtypePredicate(SubType.EQUIPMENT))); + } + + public DeadeyeQuartermaster(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Deadeye Quartermaster enters the battlefield, you may search your library for an Equipment or a Vehicle card and put it into your hand. If you do, shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(1, 1, filter); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); + } + + public DeadeyeQuartermaster(final DeadeyeQuartermaster card) { + super(card); + } + + @Override + public DeadeyeQuartermaster copy() { + return new DeadeyeQuartermaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index e1a0b827bb..91e139120a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -43,6 +43,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); + cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); cards.add(new SetCardInfo("Deadeye Tormentor", 98, Rarity.COMMON, mage.cards.d.DeadeyeTormentor.class)); cards.add(new SetCardInfo("Deadeye Tracker", 99, Rarity.RARE, mage.cards.d.DeadeyeTracker.class)); cards.add(new SetCardInfo("Deathless Ancient", 100, Rarity.UNCOMMON, mage.cards.d.DeathlessAncient.class)); @@ -58,7 +59,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); - cards.add(new SetCardInfo("Goring Certatops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); + cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); From 737878f43bad18ab3070525f34d1a9f9ca28dbff Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 13:59:12 -0400 Subject: [PATCH 042/100] Implemented Castaway's Despair --- .../src/mage/cards/c/CastawaysDespair.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/CastawaysDespair.java diff --git a/Mage.Sets/src/mage/cards/c/CastawaysDespair.java b/Mage.Sets/src/mage/cards/c/CastawaysDespair.java new file mode 100644 index 0000000000..92fd4ac9dc --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/CastawaysDespair.java @@ -0,0 +1,79 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.target.common.TargetCreaturePermanent; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.effects.common.TapEnchantedEffect; +import mage.constants.Outcome; +import mage.target.TargetPermanent; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class CastawaysDespair extends CardImpl { + + public CastawaysDespair(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}"); + + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When Castaway's Despair enters the battlefield, tap enchanted creature. + this.addAbility(new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect())); + + // Enchanted creature doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect())); + } + + public CastawaysDespair(final CastawaysDespair card) { + super(card); + } + + @Override + public CastawaysDespair copy() { + return new CastawaysDespair(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 91e139120a..a6236cb47b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -41,6 +41,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); + cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); From d8e20525314230d85f01e8a45383ed1f54faa6ff Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:01:18 -0400 Subject: [PATCH 043/100] Implemented Overflowing Insight --- .../src/mage/cards/o/OverflowingInsight.java | 59 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 60 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/o/OverflowingInsight.java diff --git a/Mage.Sets/src/mage/cards/o/OverflowingInsight.java b/Mage.Sets/src/mage/cards/o/OverflowingInsight.java new file mode 100644 index 0000000000..8a0f2d805b --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OverflowingInsight.java @@ -0,0 +1,59 @@ +/* + * 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.o; + +import java.util.UUID; +import mage.abilities.effects.common.DrawCardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.target.TargetPlayer; + +/** + * + * @author TheElk801 + */ +public class OverflowingInsight extends CardImpl { + + public OverflowingInsight(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}{U}"); + + // Target player draws seven cards. + this.getSpellAbility().addEffect(new DrawCardTargetEffect(7)); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public OverflowingInsight(final OverflowingInsight card) { + super(card); + } + + @Override + public OverflowingInsight copy() { + return new OverflowingInsight(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index a6236cb47b..530e70399b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -74,6 +74,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); + cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); From 16c6b5d23fb05d205fc854b64a32047a049b863f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:28:01 -0400 Subject: [PATCH 044/100] Implemented Kitesail Freebooter --- .../src/mage/cards/k/KitesailFreebooter.java | 206 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 207 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KitesailFreebooter.java diff --git a/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java new file mode 100644 index 0000000000..697d6a5ab2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java @@ -0,0 +1,206 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +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.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class KitesailFreebooter extends CardImpl { + + public KitesailFreebooter(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield. + Ability ability = new EntersBattlefieldTriggeredAbility(new KitesailFreebooterExileEffect()); + ability.addTarget(new TargetOpponent()); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new KitesailFreebooterReturnExiledCardAbility())); + this.addAbility(ability); + } + + public KitesailFreebooter(final KitesailFreebooter card) { + super(card); + } + + @Override + public KitesailFreebooter copy() { + return new KitesailFreebooter(this); + } +} + +class KitesailFreebooterExileEffect extends OneShotEffect { + + public KitesailFreebooterExileEffect() { + super(Outcome.Benefit); + this.staticText = "target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until {this} leaves the battlefield"; + } + + public KitesailFreebooterExileEffect(final KitesailFreebooterExileEffect effect) { + super(effect); + } + + @Override + public KitesailFreebooterExileEffect copy() { + return new KitesailFreebooterExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (controller != null && opponent != null && sourcePermanent != null) { + if (!opponent.getHand().isEmpty()) { + opponent.revealCards(sourcePermanent.getIdName(), opponent.getHand(), game); + + FilterCard filter = new FilterNonlandCard("noncreature, nonland card to exile"); + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + TargetCard target = new TargetCard(Zone.HAND, filter); + if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, game)) { + Card card = opponent.getHand().get(target.getFirstTarget(), game); + // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. + if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { + controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true); + } + } + } + return true; + } + return false; + + } +} + +/** + * Returns the exiled card as source permanent leaves battlefield Uses no stack + * + * @author LevelX2 + */ +class KitesailFreebooterReturnExiledCardAbility extends DelayedTriggeredAbility { + + public KitesailFreebooterReturnExiledCardAbility() { + super(new KitesailFreebooterReturnExiledCardEffect(), Duration.OneUse); + this.usesStack = false; + this.setRuleVisible(false); + } + + public KitesailFreebooterReturnExiledCardAbility(final KitesailFreebooterReturnExiledCardAbility ability) { + super(ability); + } + + @Override + public KitesailFreebooterReturnExiledCardAbility copy() { + return new KitesailFreebooterReturnExiledCardAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(this.getSourceId())) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD) { + return true; + } + } + return false; + } +} + +class KitesailFreebooterReturnExiledCardEffect extends OneShotEffect { + + public KitesailFreebooterReturnExiledCardEffect() { + super(Outcome.Benefit); + this.staticText = "Return exiled nonland card to its owner's hand"; + } + + public KitesailFreebooterReturnExiledCardEffect(final KitesailFreebooterReturnExiledCardEffect effect) { + super(effect); + } + + @Override + public KitesailFreebooterReturnExiledCardEffect copy() { + return new KitesailFreebooterReturnExiledCardEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (sourceObject != null && controller != null) { + ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (exile != null && sourcePermanent != null) { + controller.moveCards(exile, Zone.HAND, source, game); + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 530e70399b..96e23b19b5 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -69,6 +69,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); + cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); From 062a0c3ec3bf2d2f87e5be9332682f73b1081e6b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:33:35 -0400 Subject: [PATCH 045/100] Implemented Raging Swordtooth --- .../src/mage/cards/r/RagingSwordtooth.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RagingSwordtooth.java diff --git a/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java new file mode 100644 index 0000000000..20f4415c2f --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RagingSwordtooth.java @@ -0,0 +1,75 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DamageAllEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author TheElk801 + */ +public class RagingSwordtooth extends CardImpl { + + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("other creature"); + + static { + filter.add(new AnotherPredicate()); + } + + public RagingSwordtooth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature. + addAbility(new EntersBattlefieldTriggeredAbility(new DamageAllEffect(1, filter))); + } + + public RagingSwordtooth(final RagingSwordtooth card) { + super(card); + } + + @Override + public RagingSwordtooth copy() { + return new RagingSwordtooth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 96e23b19b5..4ec2c8fac1 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -81,6 +81,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); + cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); From 3a31ce225ecf8fa70a3960d66c468a1184148436 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:47:57 -0400 Subject: [PATCH 046/100] Implemented Grasping Current --- .../src/mage/cards/g/GraspingCurrent.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GraspingCurrent.java diff --git a/Mage.Sets/src/mage/cards/g/GraspingCurrent.java b/Mage.Sets/src/mage/cards/g/GraspingCurrent.java new file mode 100644 index 0000000000..cbc5d71444 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GraspingCurrent.java @@ -0,0 +1,71 @@ +/* + * 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.g; + +import java.util.UUID; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class GraspingCurrent extends CardImpl { + + private final static FilterCard filter = new FilterCard("Jace, Ingenious Mind-Mage"); + + static { + filter.add(new NamePredicate("Jace, Ingenious Mind-Mage")); + } + + public GraspingCurrent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}"); + + // Return up to two target creatures to their owner's hand. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + + // Search your library and/or graveyard for a card named Jace, Ingenious Mind-Mage, reveal it, then put it into your hand. If you searched your library this way, shuffle it. + this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter)); + } + + public GraspingCurrent(final GraspingCurrent card) { + super(card); + } + + @Override + public GraspingCurrent copy() { + return new GraspingCurrent(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4ec2c8fac1..7cbd1761c2 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -61,6 +61,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); + cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); From 96a85fe78720e0c118397a69842b58e8534db7be Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:50:14 -0400 Subject: [PATCH 047/100] Implemented Sun-Blessed Mount --- .../src/mage/cards/s/SunBlessedMount.java | 71 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 72 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SunBlessedMount.java diff --git a/Mage.Sets/src/mage/cards/s/SunBlessedMount.java b/Mage.Sets/src/mage/cards/s/SunBlessedMount.java new file mode 100644 index 0000000000..e993d92bd1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunBlessedMount.java @@ -0,0 +1,71 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; + +/** + * + * @author TheElk801 + */ +public class SunBlessedMount extends CardImpl { + + private final static FilterCard filter = new FilterCard("Huatli, Dinosaur Knight"); + + static { + filter.add(new NamePredicate("Huatli, Dinosaur Knight")); + } + + public SunBlessedMount(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // When Sun-Blessed Mount enters the battlefield, you may search your library and/or graveyard for a card named Huatli, Dinosaur Knight, reveal it, then put it into your hand. If you searched your library this way, shuffle it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutInHandEffect(filter), true)); + } + + public SunBlessedMount(final SunBlessedMount card) { + super(card); + } + + @Override + public SunBlessedMount copy() { + return new SunBlessedMount(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 7cbd1761c2..4b06fb21cf 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -94,6 +94,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); + cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); From ab2c17185458917283e319c7ec0573c8021c080a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 14:57:57 -0400 Subject: [PATCH 048/100] Implemented Shapers of Nature --- .../src/mage/cards/s/ShapersOfNature.java | 79 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 80 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShapersOfNature.java diff --git a/Mage.Sets/src/mage/cards/s/ShapersOfNature.java b/Mage.Sets/src/mage/cards/s/ShapersOfNature.java new file mode 100644 index 0000000000..83ee9ce6c2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShapersOfNature.java @@ -0,0 +1,79 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCounterCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class ShapersOfNature extends CardImpl { + + public ShapersOfNature(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{U}"); + + this.subtype.add("Merfolk"); + this.subtype.add("Shaman"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {3}{G}: Put a +1/+1 counter on target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance(1)), new ManaCostsImpl("{3}{G}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + // {2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card. + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{2}{U}")); + ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); + this.addAbility(ability); + } + + public ShapersOfNature(final ShapersOfNature card) { + super(card); + } + + @Override + public ShapersOfNature copy() { + return new ShapersOfNature(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4b06fb21cf..8425d60e7c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -90,6 +90,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); + cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); From f235bdc36ec9f54e22e031313f366445ec9ec1e9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 15:26:45 -0400 Subject: [PATCH 049/100] Implemented Settle the Wreckage --- .../src/mage/cards/s/SettleTheWreckage.java | 114 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 115 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SettleTheWreckage.java diff --git a/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java new file mode 100644 index 0000000000..7cc8bd744a --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SettleTheWreckage.java @@ -0,0 +1,114 @@ +/* + * 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.s; + +import java.util.Iterator; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class SettleTheWreckage extends CardImpl { + + public SettleTheWreckage(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}"); + + // Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library. + this.getSpellAbility().addEffect(new SettleTheWreckageEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public SettleTheWreckage(final SettleTheWreckage card) { + super(card); + } + + @Override + public SettleTheWreckage copy() { + return new SettleTheWreckage(this); + } +} + +class SettleTheWreckageEffect extends OneShotEffect { + + SettleTheWreckageEffect() { + super(Outcome.Neutral); + this.staticText = "Exile all attacking creatures target player controls. That player may search his or her library for that many basic land cards, put those cards onto the battlefield tapped, then shuffle his or her library"; + } + + SettleTheWreckageEffect(final SettleTheWreckageEffect effect) { + super(effect); + } + + @Override + public SettleTheWreckageEffect copy() { + return new SettleTheWreckageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + int attackers = 0; + Iterator creatureIds = game.getCombat().getAttackers().iterator(); + while (creatureIds.hasNext()) { + Permanent creature = game.getPermanent(creatureIds.next()); + if (creature != null && creature.getControllerId().equals(player.getId())) { + creature.moveToExile(null, null, source.getId(), game); + attackers++; + } + } + TargetCardInLibrary target = new TargetCardInLibrary(0, attackers, StaticFilters.FILTER_BASIC_LAND_CARD); + if (player.chooseUse(Outcome.Benefit, "Search for up to " + attackers + " basic land" + ((attackers == 1) ? "" : "s") + "?", source, game) && player.searchLibrary(target, game)) { + for (UUID cardId : target.getTargets()) { + Card card = player.getLibrary().getCard(cardId, game); + if (card != null) { + card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId(), true); + } + } + player.shuffleLibrary(source, game); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 8425d60e7c..2dfbe5c7b8 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -90,6 +90,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); + cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); From 601e7cba9b4fbf534e44cf3a0871c8f79ca28940 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 18:59:49 -0400 Subject: [PATCH 050/100] Implemented Wanted Scoundrels --- .../src/mage/cards/w/WantedScoundrels.java | 69 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WantedScoundrels.java diff --git a/Mage.Sets/src/mage/cards/w/WantedScoundrels.java b/Mage.Sets/src/mage/cards/w/WantedScoundrels.java new file mode 100644 index 0000000000..e8034cebb6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WantedScoundrels.java @@ -0,0 +1,69 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.CreateTokenTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class WantedScoundrels extends CardImpl { + + public WantedScoundrels(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // When Wanted Scoundrels dies, target opponent creates two colorless Treasure artifact tokens with "T, Sacrifice this artifact: Add one mana of any color to your mana pool." + Ability ability = new DiesTriggeredAbility(new CreateTokenTargetEffect(new TreasureToken(), 2), false); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public WantedScoundrels(final WantedScoundrels card) { + super(card); + } + + @Override + public WantedScoundrels copy() { + return new WantedScoundrels(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2dfbe5c7b8..689b97b8cb 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -112,6 +112,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); + cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } From fce99fa182b3c65efa7817f150d6dfbababcf9fb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 19:39:04 -0400 Subject: [PATCH 051/100] Implemented Conqueror's Galleon/Foothold --- .../src/mage/cards/c/ConquerorsFoothold.java | 89 +++++++++++++++++++ .../src/mage/cards/c/ConquerorsGalleon.java | 78 ++++++++++++++++ .../src/mage/cards/j/JaceCunningCastaway.java | 24 ++--- Mage.Sets/src/mage/sets/Ixalan.java | 2 + Mage/src/main/java/mage/abilities/Gender.java | 3 +- ...ExileAndReturnTransformedSourceEffect.java | 5 +- 6 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java create mode 100644 Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java new file mode 100644 index 0000000000..0c50dac919 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConquerorsFoothold.java @@ -0,0 +1,89 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.DrawDiscardControllerEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author TheElk801 + */ +public class ConquerorsFoothold extends CardImpl { + + public ConquerorsFoothold(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.nightCard = true; + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {2}, {T}: Draw a card, then discard a card. + SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DrawDiscardControllerEffect(), + new ManaCostsImpl("{2}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // {4}, {T}: Draw a card. + SimpleActivatedAbility ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new DrawCardSourceControllerEffect(1), + new ManaCostsImpl("{4}")); + ability2.addCost(new TapSourceCost()); + this.addAbility(ability2); + + // {6}, {T}: Return target card from your graveyard to your hand. + SimpleActivatedAbility ability3 = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new ReturnToHandTargetEffect(), + new ManaCostsImpl("{6}")); + ability3.addCost(new TapSourceCost()); + ability3.addTarget(new TargetCardInYourGraveyard()); + this.addAbility(ability3); + } + + public ConquerorsFoothold(final ConquerorsFoothold card) { + super(card); + } + + @Override + public ConquerorsFoothold copy() { + return new ConquerorsFoothold(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java b/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java new file mode 100644 index 0000000000..beefa13d4d --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ConquerorsGalleon.java @@ -0,0 +1,78 @@ +/* + * 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.c; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileAndReturnTransformedSourceEffect; +import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; + +/** + * + * @author TheElk801 + */ +public class ConquerorsGalleon extends CardImpl { + + public ConquerorsGalleon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + this.subtype.add("Vehicle"); + this.power = new MageInt(2); + this.toughness = new MageInt(10); + + this.transformable = true; + this.secondSideCardClazz = ConquerorsFoothold.class; + + // When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control. + this.addAbility(new TransformAbility()); + this.addAbility(new AttacksTriggeredAbility( + new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new ExileAndReturnTransformedSourceEffect())), + false, + "When {this} attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.")); + + // Crew 4 + this.addAbility(new CrewAbility(4)); + } + + public ConquerorsGalleon(final ConquerorsGalleon card) { + super(card); + } + + @Override + public ConquerorsGalleon copy() { + return new ConquerorsGalleon(this); + } +} diff --git a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java index c41c432980..30f8dcd742 100644 --- a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java +++ b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java @@ -66,7 +66,7 @@ public class JaceCunningCastaway extends CardImpl { this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3)); // +1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card. - this.addAbility(new LoyaltyAbility(new JaceArchitectOfThouStartEffect1(), 1)); + this.addAbility(new LoyaltyAbility(new JaceCunningCastawayEffect1(), 1)); // -2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it." this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new JaceCunningCastawayIllusionToken()), -2)); @@ -85,45 +85,45 @@ public class JaceCunningCastaway extends CardImpl { } } -class JaceArchitectOfThouStartEffect1 extends OneShotEffect { +class JaceCunningCastawayEffect1 extends OneShotEffect { - public JaceArchitectOfThouStartEffect1() { + public JaceCunningCastawayEffect1() { super(Outcome.DrawCard); this.staticText = "Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card"; } - public JaceArchitectOfThouStartEffect1(final JaceArchitectOfThouStartEffect1 effect) { + public JaceCunningCastawayEffect1(final JaceCunningCastawayEffect1 effect) { super(effect); } @Override - public JaceArchitectOfThouStartEffect1 copy() { - return new JaceArchitectOfThouStartEffect1(this); + public JaceCunningCastawayEffect1 copy() { + return new JaceCunningCastawayEffect1(this); } @Override public boolean apply(Game game, Ability source) { - DelayedTriggeredAbility delayedAbility = new ThopterSpyNetwoDamageTriggeredAbility(); + DelayedTriggeredAbility delayedAbility = new JaceCunningCastawayDamageTriggeredAbility(); game.addDelayedTriggeredAbility(delayedAbility, source); return true; } } -class ThopterSpyNetwoDamageTriggeredAbility extends DelayedTriggeredAbility { +class JaceCunningCastawayDamageTriggeredAbility extends DelayedTriggeredAbility { List damagedPlayerIds = new ArrayList<>(); - public ThopterSpyNetwoDamageTriggeredAbility() { + public JaceCunningCastawayDamageTriggeredAbility() { super(new DrawDiscardControllerEffect(1, 1), Duration.EndOfTurn, false); } - public ThopterSpyNetwoDamageTriggeredAbility(final ThopterSpyNetwoDamageTriggeredAbility ability) { + public JaceCunningCastawayDamageTriggeredAbility(final JaceCunningCastawayDamageTriggeredAbility ability) { super(ability); } @Override - public ThopterSpyNetwoDamageTriggeredAbility copy() { - return new ThopterSpyNetwoDamageTriggeredAbility(this); + public JaceCunningCastawayDamageTriggeredAbility copy() { + return new JaceCunningCastawayDamageTriggeredAbility(this); } @Override diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 689b97b8cb..c9b9c881f3 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -42,6 +42,8 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); cards.add(new SetCardInfo("Carnage Tyrant", 179, Rarity.MYTHIC, mage.cards.c.CarnageTyrant.class)); cards.add(new SetCardInfo("Castaway's Despair", 281, Rarity.COMMON, mage.cards.c.CastawaysDespair.class)); + cards.add(new SetCardInfo("Conqueror's Foothold", 234, Rarity.RARE, mage.cards.c.ConquerorsFoothold.class)); + cards.add(new SetCardInfo("Conqueror's Galleon", 234, Rarity.RARE, mage.cards.c.ConquerorsGalleon.class)); cards.add(new SetCardInfo("Daring Saboteur", 49, Rarity.RARE, mage.cards.d.DaringSaboteur.class)); cards.add(new SetCardInfo("Deadeye Plunderers", 220, Rarity.UNCOMMON, mage.cards.d.DeadeyePlunderers.class)); cards.add(new SetCardInfo("Deadeye Quartermaster", 50, Rarity.UNCOMMON, mage.cards.d.DeadeyeQuartermaster.class)); diff --git a/Mage/src/main/java/mage/abilities/Gender.java b/Mage/src/main/java/mage/abilities/Gender.java index d7dd334967..be6f398006 100644 --- a/Mage/src/main/java/mage/abilities/Gender.java +++ b/Mage/src/main/java/mage/abilities/Gender.java @@ -4,7 +4,7 @@ package mage.abilities; * Created by IGOUDT on 5-3-2017. */ public enum Gender { - MALE("his", "him"), FEMALE("her", "her"); + MALE("his", "him"), FEMALE("her", "her"), NEUTRAL("its", "it"); String personalPronoun; String possesivePronoun; @@ -22,5 +22,4 @@ public enum Gender { return possesivePronoun; } - } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java index 476ae10141..3a5d55092a 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileAndReturnTransformedSourceEffect.java @@ -23,9 +23,12 @@ import mage.players.Player; */ public class ExileAndReturnTransformedSourceEffect extends OneShotEffect { - protected Effect additionalEffect; + public ExileAndReturnTransformedSourceEffect() { + this(Gender.NEUTRAL); + } + public ExileAndReturnTransformedSourceEffect(Gender gender) { this(gender, null); } From 99d3a743104fba4647742394de0a1ef1a0e2a0db Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 20:17:02 -0400 Subject: [PATCH 052/100] Implemented Thaumatic Compass and Spires of Orazca --- .../src/mage/cards/s/SpiresOfOrazca.java | 87 ++++++++++++++++++ .../src/mage/cards/t/ThaumaticCompass.java | 88 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + 3 files changed, 177 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java create mode 100644 Mage.Sets/src/mage/cards/t/ThaumaticCompass.java diff --git a/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java b/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.java new file mode 100644 index 0000000000..a26d61a122 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SpiresOfOrazca.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 mage.cards.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.RemoveFromCombatTargetEffect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SpiresOfOrazca extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("attacking creature an opponent controls"); + + static { + filter.add(new AttackingPredicate()); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public SpiresOfOrazca(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + this.nightCard = true; + + // {T}: Add {C} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {T}: Untap target attacking creature an opponent controls and remove it from combat. + Effect effect = new UntapTargetEffect(); + effect.setText("Untap target attacking creature an opponent controls and remove it from combat."); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + effect = new RemoveFromCombatTargetEffect(); + effect.setText(" "); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public SpiresOfOrazca(final SpiresOfOrazca card) { + super(card); + } + + @Override + public SpiresOfOrazca copy() { + return new SpiresOfOrazca(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java new file mode 100644 index 0000000000..e8272c8103 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/ThaumaticCompass.java @@ -0,0 +1,88 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.s.SpiresOfOrazca; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.filter.common.FilterLandPermanent; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class ThaumaticCompass extends CardImpl { + + public ThaumaticCompass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.transformable = true; + this.secondSideCardClazz = SpiresOfOrazca.class; + + // {3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new SearchLibraryPutInHandEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + new GenericManaCost(3)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass. + this.addAbility(new TransformAbility()); + TriggeredAbility ability2 = new BeginningOfEndStepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, false); + this.addAbility(new ConditionalTriggeredAbility( + ability2, + new PermanentsOnTheBattlefieldCondition(new FilterLandPermanent(), ComparisonType.MORE_THAN, 6, true), + "At the beginning of your end step, if you control seven or more lands, transform {this}.")); + } + + public ThaumaticCompass(final ThaumaticCompass card) { + super(card); + } + + @Override + public ThaumaticCompass copy() { + return new ThaumaticCompass(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c9b9c881f3..6c73e489a9 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -96,11 +96,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); + cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); + cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); cards.add(new SetCardInfo("Tishana, Voice of Thunder", 230, Rarity.MYTHIC, mage.cards.t.TishanaVoiceOfThunder.class)); From 6f70a09a98bc4049a045813fa5faaa9790d9428e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 21:42:52 -0400 Subject: [PATCH 053/100] Implemented Huatli's Spurring --- .../src/mage/cards/h/HuatlisSpurring.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HuatlisSpurring.java diff --git a/Mage.Sets/src/mage/cards/h/HuatlisSpurring.java b/Mage.Sets/src/mage/cards/h/HuatlisSpurring.java new file mode 100644 index 0000000000..0346ac0dc4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HuatlisSpurring.java @@ -0,0 +1,80 @@ +/* + * 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 java.util.UUID; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalContinuousEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class HuatlisSpurring extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("a Jace planeswalker"); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + filter.add(new CardTypePredicate(CardType.PLANESWALKER)); + filter.add(new SubtypePredicate(SubType.HUATLI)); + } + + public HuatlisSpurring(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}"); + + // Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead. + this.getSpellAbility().addEffect(new ConditionalContinuousEffect( + new BoostTargetEffect(4, 0, Duration.EndOfTurn), + new BoostTargetEffect(2, 0, Duration.EndOfTurn), + new PermanentsOnTheBattlefieldCondition(filter), + "Target creature gets +2/+0 until end of turn. If you control a Huatli planeswalker, that creature gets +4/+0 until end of turn instead.")); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public HuatlisSpurring(final HuatlisSpurring card) { + super(card); + } + + @Override + public HuatlisSpurring copy() { + return new HuatlisSpurring(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 6c73e489a9..0df428f08e 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -67,6 +67,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); + cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); From 30a569d271fb3c1e57ced0ad16e85ef5b4f6504d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 5 Sep 2017 21:53:55 -0400 Subject: [PATCH 054/100] Implemented Sanctum Seeker --- Mage.Sets/src/mage/cards/s/SanctumSeeker.java | 80 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 81 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SanctumSeeker.java diff --git a/Mage.Sets/src/mage/cards/s/SanctumSeeker.java b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java new file mode 100644 index 0000000000..3b526974b1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanctumSeeker.java @@ -0,0 +1,80 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeOpponentsEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author TheElk801 + */ +public class SanctumSeeker extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Vampire you control attacks"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + } + + public SanctumSeeker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + + this.subtype.add("Vampire"); + this.subtype.add("Knight"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Whenever a Vampire you control attacks, each opponent loses 1 life and you gain 1 life. + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new LoseLifeOpponentsEffect(1), false, filter); + Effect effect = new GainLifeEffect(1); + effect.setText("and you gain 1 life"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public SanctumSeeker(final SanctumSeeker card) { + super(card); + } + + @Override + public SanctumSeeker copy() { + return new SanctumSeeker(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0df428f08e..f9db662b2c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -92,6 +92,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rootbound Crag", 256, Rarity.RARE, mage.cards.r.RootboundCrag.class)); cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); + cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); From c37ac867051009deff0bd3bb19d20595b14df00f Mon Sep 17 00:00:00 2001 From: nachazo <19270296+nachazo@users.noreply.github.com> Date: Wed, 6 Sep 2017 11:09:49 +0200 Subject: [PATCH 055/100] Update Exodus.java --- Mage.Sets/src/mage/sets/Exodus.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 0221bc232c..0cf1c1eecf 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -136,6 +136,7 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); + cards.add(new SetCardInfo("ScareTactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); cards.add(new SetCardInfo("Shackles", 18, Rarity.COMMON, mage.cards.s.Shackles.class)); From b7224fe42a8ed4c6687ec2c2687e83bca2930cc2 Mon Sep 17 00:00:00 2001 From: nachazo <19270296+nachazo@users.noreply.github.com> Date: Wed, 6 Sep 2017 11:10:45 +0200 Subject: [PATCH 056/100] Add files via upload --- Mage.Sets/src/mage/cards/s/ScareTactics.java | 58 ++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ScareTactics.java diff --git a/Mage.Sets/src/mage/cards/s/ScareTactics.java b/Mage.Sets/src/mage/cards/s/ScareTactics.java new file mode 100644 index 0000000000..582716bd0b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ScareTactics.java @@ -0,0 +1,58 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; + +/** + * + * @author Ekkaia + */ +public class ScareTactics extends CardImpl { + + public ScareTactics(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + + // Creatures you control get +1/+0 until end of turn. + this.getSpellAbility().addEffect(new BoostControlledEffect(1, 0, Duration.EndOfTurn)); + } + + public ScareTactics(final ScareTactics card) { + super(card); + } + + @Override + public ScareTactics copy() { + return new ScareTactics(this); + } +} \ No newline at end of file From d0aa1d3cd9ce5791814ed13fd1a0fdc4d144ec49 Mon Sep 17 00:00:00 2001 From: nachazo <19270296+nachazo@users.noreply.github.com> Date: Wed, 6 Sep 2017 11:15:03 +0200 Subject: [PATCH 057/100] Update Exodus.java --- Mage.Sets/src/mage/sets/Exodus.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 0cf1c1eecf..05b9ae6630 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -135,8 +135,8 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Rootwater Alligator", 122, Rarity.COMMON, mage.cards.r.RootwaterAlligator.class)); cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); - cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); cards.add(new SetCardInfo("ScareTactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); + cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); cards.add(new SetCardInfo("Shackles", 18, Rarity.COMMON, mage.cards.s.Shackles.class)); From b793367d4dbff133a0e6251aa7ee2fde8209a306 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 10:23:37 -0400 Subject: [PATCH 058/100] Fixed Kalastria Highborn --- .../src/mage/cards/k/KalastriaHighborn.java | 94 +++++++++---------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java index b1f72d5731..34bef1325d 100644 --- a/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java +++ b/Mage.Sets/src/mage/cards/k/KalastriaHighborn.java @@ -29,37 +29,48 @@ package mage.cards.k; import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.Ability; +import mage.abilities.common.DiesThisOrAnotherCreatureTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DoIfCostPaid; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.events.ZoneChangeEvent; -import mage.game.permanent.Permanent; +import mage.players.Player; import mage.target.TargetPlayer; /** * - * @author maurer.it_at_gmail.com + * @author maurer.it_at_gmail.com, TheElk801 */ public class KalastriaHighborn extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Vampire you control"); + + static { + filter.add(new SubtypePredicate(SubType.VAMPIRE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + public KalastriaHighborn(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}"); this.subtype.add("Vampire"); this.subtype.add("Shaman"); this.power = new MageInt(2); this.toughness = new MageInt(2); - this.addAbility(new KalastriaHighbornTriggeredAbility()); + Ability ability = new DiesThisOrAnotherCreatureTriggeredAbility(new DoIfCostPaid(new LoseGainEffect(), new ManaCostsImpl("{B}")), false, filter); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); } public KalastriaHighborn(final KalastriaHighborn card) { @@ -72,52 +83,35 @@ public class KalastriaHighborn extends CardImpl { } } -class KalastriaHighbornTriggeredAbility extends TriggeredAbilityImpl { - KalastriaHighbornTriggeredAbility ( ) { - super(Zone.ALL, new LoseLifeTargetEffect(2), false); - this.addCost(new ManaCostsImpl("{B}")); - this.addTarget(new TargetPlayer()); - this.getEffects().add(new GainLifeEffect(2)); +class LoseGainEffect extends OneShotEffect { + + LoseGainEffect() { + super(Outcome.Benefit); + this.staticText = "target player loses 2 life and you gain 2 life"; } - KalastriaHighbornTriggeredAbility ( KalastriaHighbornTriggeredAbility ability ) { - super(ability); + LoseGainEffect(final LoseGainEffect effect) { + super(effect); } @Override - public KalastriaHighbornTriggeredAbility copy() { - return new KalastriaHighbornTriggeredAbility(this); + public LoseGainEffect copy() { + return new LoseGainEffect(this); } @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - // ayrat: make sure Kalastria Highborn is on battlefield - if (game.getPermanent(this.getSourceId()) == null) { - // or it is being removed - if (game.getLastKnownInformation(this.getSourceId(), Zone.BATTLEFIELD) == null) { - return false; - } - } - - ZoneChangeEvent zEvent = (ZoneChangeEvent)event; - Permanent permanent = zEvent.getTarget(); - - return permanent != null && - zEvent.getToZone() == Zone.GRAVEYARD && - zEvent.getFromZone() == Zone.BATTLEFIELD && - (permanent.getControllerId().equals(this.getControllerId()) && - permanent.hasSubtype(SubType.VAMPIRE, game) || permanent.getId().equals(this.getSourceId())); - } - - @Override - public String getRule() { - return "Whenever {this} or another Vampire you control is put" - + " into a graveyard from the battlefield, you may pay {B}. If you" - + " do, target player loses 2 life and you gain 2 life."; + public boolean apply(Game game, Ability source) { + Player you = game.getPlayer(source.getControllerId()); + Player them = game.getPlayer(source.getFirstTarget()); + if (you == null && them == null) { + return false; + } + if (you != null) { + you.gainLife(2, game); + } + if (them != null) { + them.loseLife(2, game, false); + } + return true; } } From 2b74c6b4d2cc9a1c1a3c2d73c57f293eabf994c4 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 10:44:00 -0400 Subject: [PATCH 059/100] updated XLN spoiler --- Utils/mtg-cards-data.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 0339c0f04f..5e47d07ab7 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32379,6 +32379,7 @@ Sunbird's Invocation|Ixalan|165|R|{5}{R}|Enchantment|||Whenever you cast a spell Drover of the Mighty|Ixalan|167|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| Tilonalli's Skinshifter|Ixalan|170|R|{2}{R}|Creature - Human Shaman|0|1|Whenever Tilonalli's Skinshifter attacks, it becomes a copy of another target nonlegendary attacking creature until end of turn.| Unfriendly Fire|Ixalan|172|C|{4}{R}|Instant|||Unfriendly Fire deals 4 damage to target creature or player.| +Wily Goblin|Ixalan|174|U|{R}{R}|Creature - Goblin Pirate|1|1|When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| Carnage Tyrant|Ixalan|179|M|{4}{G}{G}|Creature - Dinosaur|7|6|Carnage Tyrant can't be countered.$Trample, hexproof| Deathgorge Scavenger|Ixalan|???|R|???|Creature - Dinosaur|3|2|Whenever Deathgorge Scavenger enters the battlefield or attacks, you may exile target card from a graveyard. If a creature card is exiled this way, you may gain 2 life. If a noncreature card is exiled this way, Deathgorge Scavenger gets +1/+1 until end of turn.| Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you cast a noncreature spell, put a +1/+1 counter on Deeproot Champion.| @@ -32386,10 +32387,12 @@ Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emper Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| +Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| +Wildgrowth Walker|Ixalan|216|U|{1}{G}|Creature - Elemental|1|3|Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life.| Admiral Beckett Brass|Ixalan|217|M|{1}{U}{B}{R}|Legendary Creature - Human Pirate|3|3|Other Pirates you control get +1/+1.$At the beginning of your end step, gain control of target nonland permanent controlled by a player who was dealt damage by three or more Pirates this turn.| Belligerent Brontodon|Ixalan|218|U|{5}{G}{W}|Creature - Dinosaur|4|6|Each creature you control assigns combats damage equal to its toughness rather than its power.| Call to the Feast|Ixalan|219|U|{2}{W}{B}|Sorcery|||Create three 1/1 white Vampire creature tokens with lifelink.| From e4bd858eba8e024a5b0e8c62afe7379847e8c781 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 6 Sep 2017 16:58:08 +0200 Subject: [PATCH 060/100] Added SWS to sets data. --- Utils/mtg-sets-data.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Utils/mtg-sets-data.txt b/Utils/mtg-sets-data.txt index b1ce026994..f5b538022d 100644 --- a/Utils/mtg-sets-data.txt +++ b/Utils/mtg-sets-data.txt @@ -204,3 +204,4 @@ Weatherlight|WTH| Worldwake|WWK| Ixalan|XLN| Zendikar|ZEN| +Star Wars|SWS| From 039900fda45fe0c72b7717c137aeabde4d559e9e Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 10:51:14 -0400 Subject: [PATCH 061/100] updated XLN spoiler --- Utils/mtg-cards-data.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 5e47d07ab7..2820ecda21 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32346,11 +32346,14 @@ Deadeye Quartermaster|Ixalan|50|U|{3}{U}|Creature - Human Pirate|2|2|When Deadey Deeproot Waters|Ixalan|51|U|{2}{U}|Enchantment|||Whenever you cast a Merfolk spell, create a 1/1 blue Merfolk creature token with hexproof.| Dreamcaller Siren|Ixalan|54|R|{2}{U}{U}|Creature - Siren Pirate|3|3|Flash$Flying$Dreamcaller Siren can only block creatures with flying.$When Dreamcaller Siren enters the battlefield, if you control another Pirate, tap up to two nonland permanents.| Entrancing Melody|Ixalan|55|R|{X}{U}{U}|Instant|||Gain control of target creature with converted mana cost X.| +Favorable Winds|Ixalan|56|U|{1}{U}|Enchantment|||Creatures you control with flying get +1/+1.| Herald of Secret Streams|Ixalan|59|R|{3}{U}|Creature - Merfolk Warrior|2|3|Creatures you control with +1/+1 counters on them can't be blocked.| Headwater Sentries|Ixalan|58|C|{3}{U}|Creature - Merfolk Warrior|2|5|| Jace, Cunning Castaway|Ixalan|60|M|{1}{U}{U}|Legendary Planeswalker - Jace|||+1: Whenever one or more creatures you control deal combat damage to a player this turn, draw a card, then discard a card.$-2: Create a 2/2 blue Illusion creature token with "When this creature becomes the target of a spell, sacrifice it."$-5: Create two tokens that are copies of Jace, Cunning Castaway, except they're not legendary.| Kopala, Warden of Waves|Ixalan|61|R|{1}{U}{U}|Legendary Creature - Merfolk Wizard|2|2|Spells your opponents cast that target a Merfolk you control cost {2} more to cast.$Abilities your opponents activate that target a Merfolk you control cost {2} more to activate.| +Storm Fleet Aerialist|Ixalan|63|U|{1}{U}|Creature - Human Pirate|1|2|Flying$Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn.| Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven cards.| +Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| @@ -32359,6 +32362,7 @@ Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| Deadeye Tracker|Ixalan|99|R|{B}|Creature - Human Pirate|1|1|{1}{B}, {T}: Exile two target cards from an opponent's graveyard. Deadeye Tracker explores.| Deathless Ancient|Ixalan|100|U|{4}{B}{B}|Creature - Vampire Knight|4|4|Flying$Tap three untapped Vampires you control: Return Deathless Ancient from your graveyard to your hand.| +Duress|Ixalan|105|C|{B}|Sorcery|||Target opponent reveals his or her hand. You choose a noncreature, nonland card from it. That player discards that card.| Fathom Fleet Captain|Ixalan|106|R|{1}{B}|Creature - Human Pirate|2|1|Menace$Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace.| Kitesail Freebooter|Ixalan|110|U|{1}{B}|Creature - Human Pirate|1|2|Flying$When Kitesail Freebooter enters the battlefield, target opponent reveals his or her hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield.| Queen's Bay Soldier|Ixalan|115|C|{1}{B}|Creature - Vampire Soldier|2|2|| @@ -32374,6 +32378,7 @@ Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2| Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| +Storm Fleet Arsonist|Ixalan|162|U|{4}{R}|Creature - Orc Pirate|4|4|Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent.| Sun-Crowned Hunters|Ixalan|164|C|{4}{R}{R}|Creature - Dinosaur|5|4|Enrage — Whenever Sun-Crowned Hunters is dealt damage, it deals 3 damage to target opponent.| Sunbird's Invocation|Ixalan|165|R|{5}{R}|Enchantment|||Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order.| Drover of the Mighty|Ixalan|167|U|{1}{G}|Creature - Human Druid|1|1|Drover of the Mighty gets +2/+2 as long as you control a Dinosaur.${T}: Add one mana of any color to your mana pool.| @@ -32389,6 +32394,7 @@ Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads e Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| +Slice in Twain|Ixalan|207|U|{2}{G}{G}|Instant|||Destroy target artifact or enchantment.$Draw a card.| Tishana's Wayfinder|Ixalan|211|C|{2}{G}|Creature - Merfolk Scout|2|2|When Tishana's Wayfinder enters the battlefield, it explores.| Verdant Sun's Avatar|Ixalan|213|R|{5}{G}{G}|Creature - Dinosaur Avatar|5|5|When Verdant Sun's Avatar or another creature enters the battlefield under your control, you gain life equal to that creature's toughness.| Waker of the Wilds|Ixalan|215|R|{2}{G}{G}|Creature - Merfolk Shaman|3|3|{X}{G}{G}: Put X +1/+1 counters on target land you control. That land becomes a 0/0 Elemental creature with haste. It's still a land.| @@ -32403,6 +32409,7 @@ Hostage Taker|Ixalan|223|R|{2}{U}{B}|Creature - Human Pirate|2|3|When Hostage Ta Huatli, Warrior Poet|Ixalan|224|M|{3}{R}{W}|Legendary Planeswalker - Huatli|||+2: You gain life equal to the greatest power among creatures you control.$0: Create a 3/3 green Dinosaur creature token with trample.$-X: Huatli, Warrior Poet deals X damage divided as you choose among any number of target creatures. Creatures dealt damage this way can't block this turn.| Marauding Looter|Ixalan|225|U|{2}{U}{R}|Creature - Human Pirate|4|3|Raid - At the beginning of your end step, if you attacked with a creature this turn, you may draw a card. If you do, discard a card.| Raging Swordtooth|Ixalan|226|U|{3}{R}{G}|Creature - Dinosaur|5|5|Trample$When Raging Swordtooth enters the battlefield, it deals 1 damage to each other creature.| +Regisaur Alpha|Ixalan|227|R|{3}{R}{G}|Creature - Dinosaur|4|4|Other Dinosaurs you control have haste.$When Regisaur Alpha enters the battlefield, create a 3/3 green Dinosaur creature token with trample.| Shapers of Nature|Ixalan|228|U|{1}{G}{U}|Creature - Merfolk Shaman|3|3|{3}{G}: Put a +1/+1 counter on target creature.${2}{U}, Remove a +1/+1 counter from a creature you control: Draw a card.| Tishana, Voice of Thunder|Ixalan|230|M|{5}{G}{U}|Legendary Creature - Merfolk Shaman|*|*|Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.$You have no maximum hand size.$When Tishana enters the battlefield, draw a card for each creature you control.| Conqueror's Galleon|Ixalan|234|R|{4}|Artifact - Vehicle|2|10|When Conqueror's Galleon attacks, exile it at the end of combat, then return it to the battlefield transformed under your control.$Crew 4| From 35622e855d5597b96fda778c771c86c6c29850df Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 11:08:15 -0400 Subject: [PATCH 062/100] added XLN reprints --- Mage.Sets/src/mage/sets/Ixalan.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f9db662b2c..d7f660fa90 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -57,9 +57,11 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dreamcaller Siren", 54, Rarity.RARE, mage.cards.d.DreamcallerSiren.class)); cards.add(new SetCardInfo("Drover of the Mighty", 167, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); + cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); + cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); cards.add(new SetCardInfo("Goring Ceratops", 13, Rarity.RARE, mage.cards.g.GoringCeratops.class)); @@ -79,6 +81,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); cards.add(new SetCardInfo("Mavren Fein, Dusk Apostle", 24, Rarity.RARE, mage.cards.m.MavrenFeinDuskApostle.class)); cards.add(new SetCardInfo("Old-Growth Dryads", 199, Rarity.RARE, mage.cards.o.OldGrowthDryads.class)); + cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); @@ -98,6 +101,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); + cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); From 6e6f1f0bfccc4252546bbe7b0ed73bd9c29d4464 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 11:20:33 -0400 Subject: [PATCH 063/100] Implemented Regisaur Alpha --- Mage.Sets/src/mage/cards/r/RegisaurAlpha.java | 85 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 86 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RegisaurAlpha.java diff --git a/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java new file mode 100644 index 0000000000..8b1f69312b --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RegisaurAlpha.java @@ -0,0 +1,85 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.permanent.token.DinosaurToken; + +/** + * + * @author TheElk801 + */ +public class RegisaurAlpha extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("other Dinosaurss you control"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public RegisaurAlpha(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Other Dinosaurs you control have haste. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new GainAbilityControlledEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield, filter, true))); + + // When Regisaur Alpha enters the battlefield, create a 3/3 green Dinosaur creature token with trample. + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new DinosaurToken()))); + } + + public RegisaurAlpha(final RegisaurAlpha card) { + super(card); + } + + @Override + public RegisaurAlpha copy() { + return new RegisaurAlpha(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index d7f660fa90..75a3d199b1 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -89,6 +89,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); + cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); cards.add(new SetCardInfo("River's Rebuke", 71, Rarity.RARE, mage.cards.r.RiversRebuke.class)); From 62feb30510ef436ed2dc4144bbb218dd2cdabdeb Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 11:26:07 -0400 Subject: [PATCH 064/100] Implemented Storm Fleet Aerialist --- .../src/mage/cards/s/StormFleetAerialist.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StormFleetAerialist.java diff --git a/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java new file mode 100644 index 0000000000..4ae4bb5a88 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetAerialist.java @@ -0,0 +1,75 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class StormFleetAerialist extends CardImpl { + + public StormFleetAerialist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Raid - Storm Fleet Aerialist enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1), false), + RaidCondition.instance, + "Raid - {this} enters the battlefield with a +1/+1 counter on it if you attacked with a creature this turn", + "{this} enters the battlefield with a +1/+1 counter"), + new PlayerAttackedWatcher()); + } + + public StormFleetAerialist(final StormFleetAerialist card) { + super(card); + } + + @Override + public StormFleetAerialist copy() { + return new StormFleetAerialist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 75a3d199b1..13cacc096b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -106,6 +106,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); + cards.add(new SetCardInfo("Storm Fleet Aerialist", 63, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); From ae53c5aad23c821e7f37e644a55be35d131173bf Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 11:49:26 -0400 Subject: [PATCH 065/100] Implemented Wildgrowth Walker --- .../src/mage/cards/w/WildgrowthWalker.java | 111 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WildgrowthWalker.java diff --git a/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java new file mode 100644 index 0000000000..5a12627c58 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WildgrowthWalker.java @@ -0,0 +1,111 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class WildgrowthWalker extends CardImpl { + + public WildgrowthWalker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); + + this.subtype.add("Elemental"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Whenever a creature you control explores, put a +1/+1 counter on Wildgrowth Walker and you gain 3 life. + Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance()); + Ability ability = new WildgrowthWalkerTriggeredAbility(effect); + effect = new GainLifeEffect(3); + ability.addEffect(effect); + this.addAbility(ability); + } + + public WildgrowthWalker(final WildgrowthWalker card) { + super(card); + } + + @Override + public WildgrowthWalker copy() { + return new WildgrowthWalker(this); + } +} + +class WildgrowthWalkerTriggeredAbility extends TriggeredAbilityImpl { + + WildgrowthWalkerTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + WildgrowthWalkerTriggeredAbility(final WildgrowthWalkerTriggeredAbility effect) { + super(effect); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.EXPLORED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Permanent creature = game.getPermanentOrLKIBattlefield(event.getSourceId()); + if (creature != null) { + return creature.getControllerId().equals(controllerId); + } + return false; + } + + @Override + public WildgrowthWalkerTriggeredAbility copy() { + return new WildgrowthWalkerTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a creature you control explores, put a +1/+1 counter on {this} and you gain 3 life"; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 13cacc096b..d70c6a3ea0 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -125,6 +125,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); + cards.add(new SetCardInfo("Wildgrowth Walker", 216, Rarity.UNCOMMON, mage.cards.w.WildgrowthWalker.class)); cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } From 08b18ac4c1f4fc0a9a1c2a9ca6525a3cdf10c167 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 11:51:42 -0400 Subject: [PATCH 066/100] Implemented Wily Goblin --- Mage.Sets/src/mage/cards/w/WilyGoblin.java | 65 ++++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 66 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WilyGoblin.java diff --git a/Mage.Sets/src/mage/cards/w/WilyGoblin.java b/Mage.Sets/src/mage/cards/w/WilyGoblin.java new file mode 100644 index 0000000000..9df791cb7a --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WilyGoblin.java @@ -0,0 +1,65 @@ +/* + * 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.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.permanent.token.TreasureToken; + +/** + * + * @author TheElk801 + */ +public class WilyGoblin extends CardImpl { + + public WilyGoblin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{R}"); + + this.subtype.add("Goblin"); + this.subtype.add("Pirate"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Wily Goblin enters the battlefield, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool." + this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); + } + + public WilyGoblin(final WilyGoblin card) { + super(card); + } + + @Override + public WilyGoblin copy() { + return new WilyGoblin(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index d70c6a3ea0..ff9b8aa588 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -126,6 +126,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); cards.add(new SetCardInfo("Wildgrowth Walker", 216, Rarity.UNCOMMON, mage.cards.w.WildgrowthWalker.class)); + cards.add(new SetCardInfo("Wily Goblin", 174, Rarity.UNCOMMON, mage.cards.w.WilyGoblin.class)); cards.add(new SetCardInfo("Woodland Stream", 284, Rarity.COMMON, mage.cards.w.WoodlandStream.class)); } } From a50150c70fa120ac6ce43bd1fd0389e3adfaaa3b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 12:23:49 -0400 Subject: [PATCH 067/100] Implemented Storm Fleet Arsonist --- .../src/mage/cards/s/StormFleetArsonist.java | 75 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 76 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/StormFleetArsonist.java diff --git a/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java new file mode 100644 index 0000000000..82c7377a01 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/StormFleetArsonist.java @@ -0,0 +1,75 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.RaidCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.FilterPermanent; +import mage.target.common.TargetOpponent; +import mage.watchers.common.PlayerAttackedWatcher; + +/** + * + * @author TheElk801 + */ +public class StormFleetArsonist extends CardImpl { + + public StormFleetArsonist(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}"); + + this.subtype.add("Orc"); + this.subtype.add("Pirate"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent. + Ability ability = new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new SacrificeEffect(new FilterPermanent(), 1, "Target opponent")), + RaidCondition.instance, + "Raid - When {this} enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent."); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability, new PlayerAttackedWatcher()); + } + + public StormFleetArsonist(final StormFleetArsonist card) { + super(card); + } + + @Override + public StormFleetArsonist copy() { + return new StormFleetArsonist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index ff9b8aa588..c1bb063c8b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -107,6 +107,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 63, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); + cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); From 363a06065de2fe9dad2221b8960031aab14d7248 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 12:55:20 -0400 Subject: [PATCH 068/100] Implemented Savage Stomp --- Mage.Sets/src/mage/cards/s/SavageStomp.java | 125 ++++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 126 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SavageStomp.java diff --git a/Mage.Sets/src/mage/cards/s/SavageStomp.java b/Mage.Sets/src/mage/cards/s/SavageStomp.java new file mode 100644 index 0000000000..1b8b13dd8b --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SavageStomp.java @@ -0,0 +1,125 @@ +/* + * 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.s; + +import java.util.Iterator; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.FightTargetsEffect; +import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; +import mage.target.Target; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class SavageStomp extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you don't control"); + + static { + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public SavageStomp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}"); + + // Savage Stomp costs {2} less to cast if it targets a Dinosaur you control. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new SpellCostReductionSourceEffect(2, SavageStompCondition.instance))); + + // Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control. + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setApplyEffectsAfter(); + this.getSpellAbility().addEffect(effect); + effect = new FightTargetsEffect(); + effect.setText("Then that creature fights target creature you don't control"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + Target target = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(target); + } + + public SavageStomp(final SavageStomp card) { + super(card); + } + + @Override + public SavageStomp copy() { + return new SavageStomp(this); + } +} + +enum SavageStompCondition implements Condition { + instance; + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaur you control"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + @Override + public boolean apply(Game game, Ability source) { + StackObject sourceSpell = game.getStack().getStackObject(source.getSourceId()); + if (sourceSpell != null) { + Iterator targets = sourceSpell.getStackAbility().getTargets().iterator(); + while (targets.hasNext()) { + Permanent permanent = game.getPermanentOrLKIBattlefield(targets.next().getFirstTarget()); + if (permanent != null && filter.match(permanent, game) && permanent.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + return false; + } + + @Override + public String toString() { + return "it targets a Dinosaur you control"; + } + +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index c1bb063c8b..0b9061e4cc 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -97,6 +97,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); + cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); From 1021ba2d61437cb72025f8114e22678349e7ee89 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 15:44:21 -0400 Subject: [PATCH 069/100] Implemented Ixalan's Binding --- .../src/mage/cards/i/IxalansBinding.java | 142 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 143 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/i/IxalansBinding.java diff --git a/Mage.Sets/src/mage/cards/i/IxalansBinding.java b/Mage.Sets/src/mage/cards/i/IxalansBinding.java new file mode 100644 index 0000000000..0e562625f0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/IxalansBinding.java @@ -0,0 +1,142 @@ +/* + * 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.i; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterNonlandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class IxalansBinding extends CardImpl { + + private final static FilterNonlandPermanent filter = new FilterNonlandPermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public IxalansBinding(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); + + // When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield. + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(filter.getMessage())); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + + // Your opponents can't cast spells with the same name as the exiled card. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IxalansBindingReplacementEffect())); + } + + public IxalansBinding(final IxalansBinding card) { + super(card); + } + + @Override + public IxalansBinding copy() { + return new IxalansBinding(this); + } +} + +class IxalansBindingReplacementEffect extends ContinuousRuleModifyingEffectImpl { + + IxalansBindingReplacementEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Your opponents can't cast spells with the same name as the exiled card"; + } + + IxalansBindingReplacementEffect(final IxalansBindingReplacementEffect effect) { + super(effect); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL_LATE; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Card card = game.getCard(event.getSourceId()); + if (sourcePermanent != null && card != null) { + UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); + if (exileZone != null) { + ExileZone exile = game.getExile().getExileZone(exileZone); + if (exile == null) { + // try without ZoneChangeCounter - that is useful for tokens + exileZone = CardUtil.getCardExileZoneId(game, source); + if (exileZone != null) { + exile = game.getExile().getExileZone(exileZone); + } + } + if (exile != null) { + for (Card crad : exile.getCards(game)) { + if (crad.getName().equals(card.getName())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public IxalansBindingReplacementEffect copy() { + return new IxalansBindingReplacementEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0b9061e4cc..f771d2ec3f 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -72,6 +72,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); cards.add(new SetCardInfo("Huatli, Warrior Poet", 224, Rarity.MYTHIC, mage.cards.h.HuatliWarriorPoet.class)); + cards.add(new SetCardInfo("Ixalan's Binding", 17, Rarity.UNCOMMON, mage.cards.i.IxalansBinding.class)); cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); From 6fc78d1d782c0e0dc23caf026e13443b4c5ec2aa Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 16:19:53 -0400 Subject: [PATCH 070/100] Implemented Pirate's Cutlass, changed text templating for creating token effects --- .../src/mage/cards/p/PiratesCutlass.java | 89 +++++++++++++++++++ Mage.Sets/src/mage/cards/t/TrustyMachete.java | 10 +-- Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../effects/common/CreateTokenEffect.java | 12 ++- .../common/CreateTokenTargetEffect.java | 37 ++++++-- 5 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/p/PiratesCutlass.java diff --git a/Mage.Sets/src/mage/cards/p/PiratesCutlass.java b/Mage.Sets/src/mage/cards/p/PiratesCutlass.java new file mode 100644 index 0000000000..0c6b00b464 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PiratesCutlass.java @@ -0,0 +1,89 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class PiratesCutlass extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Pirate you control"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public PiratesCutlass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); + + this.subtype.add("Equipment"); + + // When Pirate's Cutlass enters the battlefield, attach it to target Pirate you control. + Ability ability = new EntersBattlefieldTriggeredAbility(new AttachEffect(Outcome.BoostCreature, "attach it to target Pirate you control"), false); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + + // Equipped creature gets +2/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 1))); + + // Equip 2 + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + + } + + public PiratesCutlass(final PiratesCutlass card) { + super(card); + } + + @Override + public PiratesCutlass copy() { + return new PiratesCutlass(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TrustyMachete.java b/Mage.Sets/src/mage/cards/t/TrustyMachete.java index ba0f973043..3f64f88a0f 100644 --- a/Mage.Sets/src/mage/cards/t/TrustyMachete.java +++ b/Mage.Sets/src/mage/cards/t/TrustyMachete.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 mage.cards.t; import java.util.UUID; @@ -45,14 +44,15 @@ import mage.constants.Zone; */ public class TrustyMachete extends CardImpl { - public TrustyMachete (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + public TrustyMachete(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); this.subtype.add("Equipment"); - this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 1))); + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); } - public TrustyMachete (final TrustyMachete card) { + public TrustyMachete(final TrustyMachete card) { super(card); } diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f771d2ec3f..a5abf0b667 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -85,6 +85,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Opt", 65, Rarity.COMMON, mage.cards.o.Opt.class)); cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); + cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 025cebb7ac..71deb80ab0 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -113,7 +113,7 @@ public class CreateTokenEffect extends OneShotEffect { public ArrayList getLastAddedTokenIds() { return lastAddedTokenIds; } - + public void exileTokensCreatedAtNextEndStep(Game game, Ability source) { for (UUID tokenId : this.getLastAddedTokenIds()) { Permanent tokenPermanent = game.getPermanent(tokenId); @@ -122,7 +122,7 @@ public class CreateTokenEffect extends OneShotEffect { exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source); } - } + } } public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) { @@ -133,9 +133,9 @@ public class CreateTokenEffect extends OneShotEffect { exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game)); game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source); } - } + } } - + private void setText() { StringBuilder sb = new StringBuilder("create "); if (amount.toString().equals("1")) { @@ -153,6 +153,10 @@ public class CreateTokenEffect extends OneShotEffect { if (token.getDescription().endsWith("token")) { sb.append("s "); } + int tokenLocation = sb.indexOf("token "); + if (tokenLocation != -1) { + sb.replace(tokenLocation, tokenLocation + 6, "tokens "); + } } if (attacking) { if (tapped) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java index 863528dbbe..753a4a96f8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java @@ -67,25 +67,44 @@ public class CreateTokenTargetEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - StringBuilder sb = new StringBuilder("put "); - sb.append(CardUtil.numberToText(amount.toString(), "a")); - sb.append(' ').append(token.getDescription()).append(" onto the battlefield"); - if (tapped) { - sb.append(" tapped"); + StringBuilder sb = new StringBuilder(); + sb.append("target ").append(mode.getTargets().get(0).getTargetName()); + sb.append(" creates "); + if (amount.toString().equals("1")) { + sb.append("a "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append(token.getDescription()); + } else { + sb.append(CardUtil.numberToText(amount.toString())).append(' '); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append(token.getDescription()); + if (token.getDescription().endsWith("token")) { + sb.append("s "); + } + int tokenLocation = sb.indexOf("token "); + if (tokenLocation != -1) { + sb.replace(tokenLocation, tokenLocation + 6, "tokens "); + } } if (attacking) { if (tapped) { - sb.append(" and"); + sb.append(" tapped and"); } sb.append(" attacking"); } String message = amount.getMessage(); if (!message.isEmpty()) { - sb.append(" for each "); + if (amount.toString().equals("X")) { + sb.append(", where X is "); + } else { + sb.append(" for each "); + } } sb.append(message); - sb.append(" under target ").append(mode.getTargets().get(0).getTargetName()); - sb.append("'s control"); return sb.toString(); } } From 0f72c4fb224187927ad0bd77b04a31d6a7604bb0 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 17:39:58 -0400 Subject: [PATCH 071/100] Additional token effect text changes --- .../src/mage/cards/b/BackFromTheBrink.java | 4 +- .../mage/cards/b/BloodforgedBattleAxe.java | 4 +- .../src/mage/cards/c/CacklingCounterpart.java | 4 +- Mage.Sets/src/mage/cards/c/Chronozoa.java | 4 +- Mage.Sets/src/mage/cards/c/CloneLegion.java | 4 +- .../src/mage/cards/c/CogworkAssembler.java | 4 +- Mage.Sets/src/mage/cards/d/DanceOfMany.java | 4 +- .../cards/d/DarettiIngeniousIconoclast.java | 4 +- .../src/mage/cards/f/FaerieArtisans.java | 4 +- .../src/mage/cards/f/FatedInfatuation.java | 4 +- .../mage/cards/f/FeldonOfTheThirdPath.java | 4 +- .../src/mage/cards/f/FelhideSpiritbinder.java | 4 +- .../src/mage/cards/f/FlamerushRider.java | 4 +- .../mage/cards/f/FlameshadowConjuring.java | 4 +- .../src/mage/cards/f/FollowedFootsteps.java | 4 +- .../src/mage/cards/f/FracturedIdentity.java | 4 +- Mage.Sets/src/mage/cards/g/GiantAdephage.java | 4 +- Mage.Sets/src/mage/cards/h/HeatShimmer.java | 4 +- .../mage/cards/i/InallaArchmageRitualist.java | 4 +- .../src/mage/cards/j/JaceCunningCastaway.java | 6 +- .../mage/cards/k/KikiJikiMirrorBreaker.java | 4 +- Mage.Sets/src/mage/cards/k/KindredCharge.java | 4 +- Mage.Sets/src/mage/cards/m/MimicVat.java | 4 +- .../src/mage/cards/m/MinionReflector.java | 4 +- Mage.Sets/src/mage/cards/m/MirrorMatch.java | 4 +- Mage.Sets/src/mage/cards/m/MirrorMockery.java | 4 +- .../src/mage/cards/m/MirrorSigilSergeant.java | 4 +- Mage.Sets/src/mage/cards/m/Mirrorpool.java | 4 +- Mage.Sets/src/mage/cards/m/Mirrorworks.java | 4 +- Mage.Sets/src/mage/cards/m/MyrPropagator.java | 4 +- Mage.Sets/src/mage/cards/n/NemesisTrap.java | 4 +- Mage.Sets/src/mage/cards/p/PackRat.java | 4 +- .../src/mage/cards/p/ParallelEvolution.java | 4 +- .../src/mage/cards/p/ProgenitorMimic.java | 4 +- .../src/mage/cards/r/RhysTheRedeemed.java | 4 +- .../mage/cards/r/RikuOfTwoReflections.java | 4 +- .../src/mage/cards/r/RiteOfReplication.java | 6 +- Mage.Sets/src/mage/cards/s/SaheeliRai.java | 4 +- .../src/mage/cards/s/SaheelisArtistry.java | 6 +- Mage.Sets/src/mage/cards/s/Seance.java | 4 +- Mage.Sets/src/mage/cards/s/SecondHarvest.java | 4 +- Mage.Sets/src/mage/cards/s/SoulFoundry.java | 4 +- Mage.Sets/src/mage/cards/s/SoulSeparator.java | 4 +- Mage.Sets/src/mage/cards/s/Spawnwrithe.java | 4 +- Mage.Sets/src/mage/cards/s/SpittingImage.java | 4 +- Mage.Sets/src/mage/cards/s/SplinterTwin.java | 4 +- .../src/mage/cards/s/SplittingSlime.java | 4 +- .../src/mage/cards/s/SproutingPhytohydra.java | 4 +- .../src/mage/cards/s/StolenIdentity.java | 4 +- Mage.Sets/src/mage/cards/s/SupplantForm.java | 4 +- .../mage/cards/t/TemptWithReflections.java | 8 +-- Mage.Sets/src/mage/cards/t/TheScarabGod.java | 4 +- Mage.Sets/src/mage/cards/t/Twinflame.java | 4 +- ....java => CreateTokenCopySourceEffect.java} | 16 ++--- ....java => CreateTokenCopyTargetEffect.java} | 58 ++++++++++--------- .../effects/common/CreateTokenEffect.java | 1 + .../common/CreateTokenTargetEffect.java | 1 + .../effects/common/PopulateEffect.java | 2 +- .../mage/abilities/keyword/MyriadAbility.java | 4 +- 59 files changed, 154 insertions(+), 150 deletions(-) rename Mage/src/main/java/mage/abilities/effects/{PutTokenOntoBattlefieldCopySourceEffect.java => CreateTokenCopySourceEffect.java} (57%) rename Mage/src/main/java/mage/abilities/effects/common/{PutTokenOntoBattlefieldCopyTargetEffect.java => CreateTokenCopyTargetEffect.java} (84%) diff --git a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java index c91caa44ee..c056da0ca2 100644 --- a/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java +++ b/Mage.Sets/src/mage/cards/b/BackFromTheBrink.java @@ -33,7 +33,7 @@ import mage.abilities.common.ActivateAsSorceryActivatedAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -57,7 +57,7 @@ public class BackFromTheBrink extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{U}{U}"); // Exile a creature card from your graveyard and pay its mana cost: Create a token that's a copy of that card. Activate this ability only any time you could cast a sorcery. - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setText("create a token that's a copy of that card"); this.addAbility(new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, effect, new BackFromTheBrinkCost())); diff --git a/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java b/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java index 10c5aab52a..98d934b7c5 100644 --- a/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java +++ b/Mage.Sets/src/mage/cards/b/BloodforgedBattleAxe.java @@ -30,7 +30,7 @@ package mage.cards.b; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.keyword.EquipAbility; import mage.cards.CardImpl; @@ -81,7 +81,7 @@ public class BloodforgedBattleAxe extends CardImpl { class BloodforgedBattleAxeAbility extends TriggeredAbilityImpl { public BloodforgedBattleAxeAbility() { - super(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect()); + super(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect()); } public BloodforgedBattleAxeAbility(final BloodforgedBattleAxeAbility ability) { diff --git a/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java b/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java index 22c7c059e9..1db428edc3 100644 --- a/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java +++ b/Mage.Sets/src/mage/cards/c/CacklingCounterpart.java @@ -29,7 +29,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -46,7 +46,7 @@ public class CacklingCounterpart extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{U}{U}"); // Create a token that's a copy of target creature you control. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); // Flashback {5}{U}{U} diff --git a/Mage.Sets/src/mage/cards/c/Chronozoa.java b/Mage.Sets/src/mage/cards/c/Chronozoa.java index 39fdd61b6f..8d3980b5e3 100644 --- a/Mage.Sets/src/mage/cards/c/Chronozoa.java +++ b/Mage.Sets/src/mage/cards/c/Chronozoa.java @@ -35,7 +35,7 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.LastTimeCounterRemovedCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VanishingSacrificeAbility; @@ -69,7 +69,7 @@ public class Chronozoa extends CardImpl { this.addAbility(new VanishingSacrificeAbility()); // When Chronozoa is put into a graveyard from play, if it had no time counters on it, create two tokens that are copies of it. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(2); + Effect effect = new CreateTokenCopySourceEffect(2); effect.setText("create two tokens that are copies of it"); this.addAbility(new ConditionalTriggeredAbility(new DiesTriggeredAbility(effect, false), LastTimeCounterRemovedCondition.instance, diff --git a/Mage.Sets/src/mage/cards/c/CloneLegion.java b/Mage.Sets/src/mage/cards/c/CloneLegion.java index cfe1eecbdd..423b0c22ff 100644 --- a/Mage.Sets/src/mage/cards/c/CloneLegion.java +++ b/Mage.Sets/src/mage/cards/c/CloneLegion.java @@ -30,7 +30,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class CloneLegionEffect extends OneShotEffect { if (controller != null && targetPlayer != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, targetPlayer.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java index 0432779b8b..7aa000630d 100644 --- a/Mage.Sets/src/mage/cards/c/CogworkAssembler.java +++ b/Mage.Sets/src/mage/cards/c/CogworkAssembler.java @@ -36,7 +36,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -96,7 +96,7 @@ class CogworkAssemblerCreateTokenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent copiedPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (copiedPermanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, true); if (effect.apply(game, source)) { for (Permanent copyPermanent : effect.getAddedPermanent()) { ExileTargetEffect exileEffect = new ExileTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/d/DanceOfMany.java b/Mage.Sets/src/mage/cards/d/DanceOfMany.java index 62f2f7ea4f..773f801ac3 100644 --- a/Mage.Sets/src/mage/cards/d/DanceOfMany.java +++ b/Mage.Sets/src/mage/cards/d/DanceOfMany.java @@ -38,7 +38,7 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.InfoEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; @@ -114,7 +114,7 @@ class DanceOfManyCreateTokenCopyEffect extends OneShotEffect { Permanent sourceObject = game.getPermanent(source.getSourceId()); if (permanent != null && sourceObject != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); game.getState().setValue(source.getSourceId() + "_token", effect.getAddedPermanent()); diff --git a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java index 839b49512d..8da715a5dc 100644 --- a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java +++ b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java @@ -36,7 +36,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -87,7 +87,7 @@ public class DarettiIngeniousIconoclast extends CardImpl { // -6: Choose target artifact card in a graveyard or artifact on the battlefield. Create three tokens that are copies of it. ability = new LoyaltyAbility( - new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 3), + new CreateTokenCopyTargetEffect(null, null, false, 3), -6); ability.addTarget(new TargetCardInGraveyardOrBattlefield(new FilterArtifactCard("artifact card in a graveyard or artifact on the battlefield"))); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java index dd66fb2c92..8caf385e5f 100644 --- a/Mage.Sets/src/mage/cards/f/FaerieArtisans.java +++ b/Mage.Sets/src/mage/cards/f/FaerieArtisans.java @@ -33,7 +33,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -110,7 +110,7 @@ class FaerieArtisansEffect extends OneShotEffect { Permanent permanentToCopy = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); if (controller != null && permanentToCopy != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, false); effect.setTargetPointer(new FixedTarget(permanentToCopy, game)); if (effect.apply(game, source)) { String oldTokens = (String) game.getState().getValue(source.getSourceId().toString() + source.getSourceObjectZoneChangeCounter()); diff --git a/Mage.Sets/src/mage/cards/f/FatedInfatuation.java b/Mage.Sets/src/mage/cards/f/FatedInfatuation.java index db36763b33..a5c82de3d8 100644 --- a/Mage.Sets/src/mage/cards/f/FatedInfatuation.java +++ b/Mage.Sets/src/mage/cards/f/FatedInfatuation.java @@ -30,7 +30,7 @@ package mage.cards.f; import java.util.UUID; import mage.abilities.condition.common.MyTurnCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +48,7 @@ public class FatedInfatuation extends CardImpl { // Create a token that's a copy of target creature you control. If it's your turn, scry 2. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new ScryEffect(2), MyTurnCondition.instance, "If it's your turn, scry 2")); } diff --git a/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java b/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java index 1903cd2290..40adbbd86f 100644 --- a/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java +++ b/Mage.Sets/src/mage/cards/f/FeldonOfTheThirdPath.java @@ -36,7 +36,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -103,7 +103,7 @@ class FeldonOfTheThirdPathEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card card = game.getCard(getTargetPointer().getFirst(game, source)); if (card != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), CardType.ARTIFACT, true); effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId()))); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java b/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java index 8da4e58b75..ef29cb8cf3 100644 --- a/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java +++ b/Mage.Sets/src/mage/cards/f/FelhideSpiritbinder.java @@ -36,7 +36,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.InspiredAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -105,7 +105,7 @@ class FelhideSpiritbinderEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ENCHANTMENT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ENCHANTMENT, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FlamerushRider.java b/Mage.Sets/src/mage/cards/f/FlamerushRider.java index d9f816482a..6147c56174 100644 --- a/Mage.Sets/src/mage/cards/f/FlamerushRider.java +++ b/Mage.Sets/src/mage/cards/f/FlamerushRider.java @@ -36,7 +36,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.DashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -111,7 +111,7 @@ class FlamerushRiderEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (controller != null && permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true, 1, true, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true, 1, true, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java b/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java index b57cb5448b..1c017740df 100644 --- a/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java +++ b/Mage.Sets/src/mage/cards/f/FlameshadowConjuring.java @@ -36,7 +36,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -105,7 +105,7 @@ class FlameshadowConjuringEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java b/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java index dc214e80eb..dd846509e2 100644 --- a/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java +++ b/Mage.Sets/src/mage/cards/f/FollowedFootsteps.java @@ -33,7 +33,7 @@ import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -99,7 +99,7 @@ class FollowedFootstepsEffect extends OneShotEffect { Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent target = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo()); if (target != null) { - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(enchantment.getAttachedTo())); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/f/FracturedIdentity.java b/Mage.Sets/src/mage/cards/f/FracturedIdentity.java index 49ae7d81c0..7a7d532aa4 100644 --- a/Mage.Sets/src/mage/cards/f/FracturedIdentity.java +++ b/Mage.Sets/src/mage/cards/f/FracturedIdentity.java @@ -30,7 +30,7 @@ package mage.cards.f; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class FracturedIdentityEffect extends OneShotEffect { permanent.moveToExile(null, null, source.getSourceId(), game); UUID controllerId = permanent.getControllerId(); for (UUID opponentId : game.getOpponents(controllerId)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(opponentId, null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(opponentId, null, false); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/g/GiantAdephage.java b/Mage.Sets/src/mage/cards/g/GiantAdephage.java index 813a91faa2..17171f9dbf 100644 --- a/Mage.Sets/src/mage/cards/g/GiantAdephage.java +++ b/Mage.Sets/src/mage/cards/g/GiantAdephage.java @@ -30,7 +30,7 @@ package mage.cards.g; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -53,7 +53,7 @@ public class GiantAdephage extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever Giant Adephage deals combat damage to a player, create a token that is a copy of Giant Adephage. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect(), false)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenCopySourceEffect(), false)); } diff --git a/Mage.Sets/src/mage/cards/h/HeatShimmer.java b/Mage.Sets/src/mage/cards/h/HeatShimmer.java index 76e1cacb42..68967ad6ab 100644 --- a/Mage.Sets/src/mage/cards/h/HeatShimmer.java +++ b/Mage.Sets/src/mage/cards/h/HeatShimmer.java @@ -34,7 +34,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,7 +90,7 @@ class HeatShimmerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (controller != null && permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java b/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java index b5748d102e..a9cfb55618 100644 --- a/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java +++ b/Mage.Sets/src/mage/cards/i/InallaArchmageRitualist.java @@ -42,7 +42,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.LoseLifeTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.AbilityWord; @@ -139,7 +139,7 @@ class InallaArchmageRitualistEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, null, true); effect.setTargetPointer(getTargetPointer()); if (effect.apply(game, source)) { for (Permanent tokenPermanent : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java index 30f8dcd742..f1c02d0bd1 100644 --- a/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java +++ b/Mage.Sets/src/mage/cards/j/JaceCunningCastaway.java @@ -37,7 +37,7 @@ import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DrawDiscardControllerEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -176,8 +176,8 @@ class JaceCunningCastawayCopyEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, 2); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 2); + effect.setTargetPointer(new FixedTarget(source.getSourceId(), game)); effect.setIsntLegendary(true); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java b/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java index 6e56f122b0..c35c73f2fb 100644 --- a/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java +++ b/Mage.Sets/src/mage/cards/k/KikiJikiMirrorBreaker.java @@ -34,7 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeTargetEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; @@ -111,7 +111,7 @@ class KikiJikiMirrorBreakerEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/k/KindredCharge.java b/Mage.Sets/src/mage/cards/k/KindredCharge.java index bc93536051..46ef8164c3 100644 --- a/Mage.Sets/src/mage/cards/k/KindredCharge.java +++ b/Mage.Sets/src/mage/cards/k/KindredCharge.java @@ -37,7 +37,7 @@ import mage.abilities.effects.common.ChooseCreatureTypeEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -100,7 +100,7 @@ class KindredChargeEffect extends OneShotEffect { filter.add(new SubtypePredicate(SubType.byDescription(creatureType))); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MimicVat.java b/Mage.Sets/src/mage/cards/m/MimicVat.java index 21e3ae8a9c..8fd4c37ba9 100644 --- a/Mage.Sets/src/mage/cards/m/MimicVat.java +++ b/Mage.Sets/src/mage/cards/m/MimicVat.java @@ -39,7 +39,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -206,7 +206,7 @@ class MimicVatCreateTokenEffect extends OneShotEffect { if (!permanent.getImprinted().isEmpty()) { Card card = game.getCard(permanent.getImprinted().get(0)); if (card != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MinionReflector.java b/Mage.Sets/src/mage/cards/m/MinionReflector.java index 506f9ac33c..a9ae22da15 100644 --- a/Mage.Sets/src/mage/cards/m/MinionReflector.java +++ b/Mage.Sets/src/mage/cards/m/MinionReflector.java @@ -35,7 +35,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.cards.CardImpl; @@ -137,7 +137,7 @@ class MinionReflectorEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorMatch.java b/Mage.Sets/src/mage/cards/m/MirrorMatch.java index 3aa3fd7ab5..d5d3f8d584 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMatch.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMatch.java @@ -33,7 +33,7 @@ import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -97,7 +97,7 @@ class MirrorMatchEffect extends OneShotEffect { Permanent attacker = game.getPermanent(attackerId); if (attacker != null && source.getControllerId().equals(game.getCombat().getDefendingPlayerId(attackerId, game))) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false); effect.setTargetPointer(new FixedTarget(attacker, game)); effect.apply(game, source); CombatGroup group = game.getCombat().findGroup(attacker.getId()); diff --git a/Mage.Sets/src/mage/cards/m/MirrorMockery.java b/Mage.Sets/src/mage/cards/m/MirrorMockery.java index 6adcef3291..d5b14c0045 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorMockery.java +++ b/Mage.Sets/src/mage/cards/m/MirrorMockery.java @@ -34,7 +34,7 @@ import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -102,7 +102,7 @@ class MirrorMockeryEffect extends OneShotEffect { } Permanent enchanted = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo()); if (enchanted != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(enchanted, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java b/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java index 9e6d32754c..a01b37b68d 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java +++ b/Mage.Sets/src/mage/cards/m/MirrorSigilSergeant.java @@ -35,7 +35,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -71,7 +71,7 @@ public class MirrorSigilSergeant extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // At the beginning of your upkeep, if you control a blue permanent, you may create a token that's a copy of Mirror-Sigil Sergeant. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("you may create a token that's a copy of {this}"); TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, effect, TargetController.YOU, true); this.addAbility(new ConditionalTriggeredAbility(ability, new PermanentsOnTheBattlefieldCondition(filter), rule)); diff --git a/Mage.Sets/src/mage/cards/m/Mirrorpool.java b/Mage.Sets/src/mage/cards/m/Mirrorpool.java index baa09029bb..76adc1b069 100644 --- a/Mage.Sets/src/mage/cards/m/Mirrorpool.java +++ b/Mage.Sets/src/mage/cards/m/Mirrorpool.java @@ -35,7 +35,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CopyTargetSpellEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.mana.ColorlessManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -81,7 +81,7 @@ public class Mirrorpool extends CardImpl { this.addAbility(ability); // {4}{C}, {T}, Sacrifice Mirrorpool: Create a token that's a copy of target creature you control. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopyTargetEffect(), new ManaCostsImpl("{4}{C}")); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopyTargetEffect(), new ManaCostsImpl("{4}{C}")); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetControlledCreaturePermanent()); diff --git a/Mage.Sets/src/mage/cards/m/Mirrorworks.java b/Mage.Sets/src/mage/cards/m/Mirrorworks.java index 2d1e051fb9..d461aebcc8 100644 --- a/Mage.Sets/src/mage/cards/m/Mirrorworks.java +++ b/Mage.Sets/src/mage/cards/m/Mirrorworks.java @@ -32,7 +32,7 @@ import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -61,7 +61,7 @@ public class Mirrorworks extends CardImpl { // Whenever another nontoken artifact enters the battlefield under your control, you may pay {2}. // If you do, create a token that's a copy of that artifact. - Effect effect = new DoIfCostPaid(new PutTokenOntoBattlefieldCopyTargetEffect(true), + Effect effect = new DoIfCostPaid(new CreateTokenCopyTargetEffect(true), new ManaCostsImpl("{2}"), "Create a token that's a copy of that artifact?"); effect.setText("you may pay {2}. If you do, create a token that's a copy of that artifact"); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filter, false, SetTargetPointer.PERMANENT, null)); diff --git a/Mage.Sets/src/mage/cards/m/MyrPropagator.java b/Mage.Sets/src/mage/cards/m/MyrPropagator.java index 6a7e2a6ef2..9795b4e107 100644 --- a/Mage.Sets/src/mage/cards/m/MyrPropagator.java +++ b/Mage.Sets/src/mage/cards/m/MyrPropagator.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -53,7 +53,7 @@ public class MyrPropagator extends CardImpl { this.toughness = new MageInt(1); // {3}, {tap}: Create a token that's a copy of Myr Propagator. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect(), new GenericManaCost(3)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect(), new GenericManaCost(3)); ability.addCost(new TapSourceCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/n/NemesisTrap.java b/Mage.Sets/src/mage/cards/n/NemesisTrap.java index af5f67aafd..1a28e4260d 100644 --- a/Mage.Sets/src/mage/cards/n/NemesisTrap.java +++ b/Mage.Sets/src/mage/cards/n/NemesisTrap.java @@ -37,7 +37,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -111,7 +111,7 @@ class NemesisTrapEffect extends OneShotEffect { // exile target controller.moveCards(targetedCreature, Zone.EXILED, source, game); // create token - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(targetedCreature, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/p/PackRat.java b/Mage.Sets/src/mage/cards/p/PackRat.java index 1f0cb97b75..4a8bbb951d 100644 --- a/Mage.Sets/src/mage/cards/p/PackRat.java +++ b/Mage.Sets/src/mage/cards/p/PackRat.java @@ -35,7 +35,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -83,7 +83,7 @@ public class PackRat extends CardImpl { // Pack Rat's power and toughness are each equal to the number of Rats you control. this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new PermanentsOnBattlefieldCount(filter), Duration.EndOfGame))); // {2}{B}, Discard a card: Create a token that's a copy of Pack Rat. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTokenOntoBattlefieldCopySourceEffect(), new ManaCostsImpl("{2}{B}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenCopySourceEffect(), new ManaCostsImpl("{2}{B}")); ability.addCost(new DiscardCardCost()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/ParallelEvolution.java b/Mage.Sets/src/mage/cards/p/ParallelEvolution.java index dedb99c3ca..ae1fba4247 100644 --- a/Mage.Sets/src/mage/cards/p/ParallelEvolution.java +++ b/Mage.Sets/src/mage/cards/p/ParallelEvolution.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -97,7 +97,7 @@ class ParallelEvolutionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(permanent.getControllerId()); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(permanent.getControllerId()); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java index 09301b3f9b..9b71ac9057 100644 --- a/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java +++ b/Mage.Sets/src/mage/cards/p/ProgenitorMimic.java @@ -34,7 +34,7 @@ import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.effects.common.CopyPermanentEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -67,7 +67,7 @@ public class ProgenitorMimic extends CardImpl { // You may have Progenitor Mimic enter the battlefield as a copy of any creature on the battlefield // except it gains "At the beginning of your upkeep, if this creature isn't a token, // create a token that's a copy of this creature." - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("create a token that's a copy of this creature"); AbilityApplier applier = new AbilityApplier( diff --git a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java index e5e11655e6..c5b37477a3 100644 --- a/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java +++ b/Mage.Sets/src/mage/cards/r/RhysTheRedeemed.java @@ -35,7 +35,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -117,7 +117,7 @@ class RhysTheRedeemedEffect extends OneShotEffect { if (controller != null) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { if (permanent.getControllerId().equals(source.getControllerId())) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java index f2cdde3f9d..ad0ecfdfc7 100644 --- a/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java +++ b/Mage.Sets/src/mage/cards/r/RikuOfTwoReflections.java @@ -35,7 +35,7 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.common.CopyTargetSpellEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -82,7 +82,7 @@ public class RikuOfTwoReflections extends CardImpl { this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(effect, new ManaCostsImpl("{U}{R}")), filter, false, true)); // Whenever another nontoken creature enters the battlefield under your control, you may pay {G}{U}. If you do, create a token that's a copy of that creature. - effect = new DoIfCostPaid(new PutTokenOntoBattlefieldCopyTargetEffect(true), + effect = new DoIfCostPaid(new CreateTokenCopyTargetEffect(true), new ManaCostsImpl("{G}{U}"), "Create a token that's a copy of that creature?"); effect.setText("you may pay {G}{U}. If you do, create a token that's a copy of that creature"); this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filterPermanent, false, SetTargetPointer.PERMANENT, null)); diff --git a/Mage.Sets/src/mage/cards/r/RiteOfReplication.java b/Mage.Sets/src/mage/cards/r/RiteOfReplication.java index 0801769a28..5b0a31ac7b 100644 --- a/Mage.Sets/src/mage/cards/r/RiteOfReplication.java +++ b/Mage.Sets/src/mage/cards/r/RiteOfReplication.java @@ -30,7 +30,7 @@ package mage.cards.r; import java.util.UUID; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -51,8 +51,8 @@ public class RiteOfReplication extends CardImpl { // Create a token that's a copy of target creature. If Rite of Replication was kicked, create five of those tokens instead. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 5), - new PutTokenOntoBattlefieldCopyTargetEffect(), KickedCondition.instance, + this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new CreateTokenCopyTargetEffect(null, null, false, 5), + new CreateTokenCopyTargetEffect(), KickedCondition.instance, "Create a token that's a copy of target creature. If {this} was kicked, create five of those tokens instead")); } diff --git a/Mage.Sets/src/mage/cards/s/SaheeliRai.java b/Mage.Sets/src/mage/cards/s/SaheeliRai.java index b66844ae70..b6528ecbf6 100644 --- a/Mage.Sets/src/mage/cards/s/SaheeliRai.java +++ b/Mage.Sets/src/mage/cards/s/SaheeliRai.java @@ -37,7 +37,7 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamagePlayersEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.Card; @@ -115,7 +115,7 @@ class SaheeliRaiCreateTokenEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent copiedPermanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); if (copiedPermanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(null, CardType.ARTIFACT, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(null, CardType.ARTIFACT, true); if (effect.apply(game, source)) { for (Permanent copyPermanent : effect.getAddedPermanent()) { ExileTargetEffect exileEffect = new ExileTargetEffect(); diff --git a/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java b/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java index b24622c005..35e47ac56b 100644 --- a/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java +++ b/Mage.Sets/src/mage/cards/s/SaheelisArtistry.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Mode; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -50,13 +50,13 @@ public class SaheelisArtistry extends CardImpl { this.getSpellAbility().getModes().setMaxModes(2); // • Create a token that's a copy of target artifact. this.getSpellAbility().addTarget(new TargetArtifactPermanent()); - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setText("Create a token that's a copy of target artifact"); this.getSpellAbility().addEffect(effect); // • Create a token that's a copy of target creature, except that it's an artifact in addition to its other types. Mode mode1 = new Mode(); mode1.getTargets().add(new TargetCreaturePermanent()); - effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + effect = new CreateTokenCopyTargetEffect(); effect.setBecomesArtifact(true); effect.setText("Create a token that's a copy of target creature, except that it's an artifact in addition to its other types"); mode1.getEffects().add(effect); diff --git a/Mage.Sets/src/mage/cards/s/Seance.java b/Mage.Sets/src/mage/cards/s/Seance.java index 8a5794460d..68615fe293 100644 --- a/Mage.Sets/src/mage/cards/s/Seance.java +++ b/Mage.Sets/src/mage/cards/s/Seance.java @@ -34,7 +34,7 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -96,7 +96,7 @@ class SeanceEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setAdditionalSubType("Spirit"); effect.apply(game, source); diff --git a/Mage.Sets/src/mage/cards/s/SecondHarvest.java b/Mage.Sets/src/mage/cards/s/SecondHarvest.java index 8350f3fa3b..e2793a550b 100644 --- a/Mage.Sets/src/mage/cards/s/SecondHarvest.java +++ b/Mage.Sets/src/mage/cards/s/SecondHarvest.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -89,7 +89,7 @@ class SecondHarvestEffect extends OneShotEffect { filter.add(new TokenPredicate()); for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/s/SoulFoundry.java b/Mage.Sets/src/mage/cards/s/SoulFoundry.java index 80e7ce2392..34544acfda 100644 --- a/Mage.Sets/src/mage/cards/s/SoulFoundry.java +++ b/Mage.Sets/src/mage/cards/s/SoulFoundry.java @@ -37,7 +37,7 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -175,7 +175,7 @@ class SoulFoundryEffect extends OneShotEffect { Card imprinted = game.getCard(soulFoundry.getImprinted().get(0)); if (imprinted != null && game.getState().getZone(imprinted.getId()) == Zone.EXILED) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(imprinted.getId(), imprinted.getZoneChangeCounter(game))); return effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/s/SoulSeparator.java b/Mage.Sets/src/mage/cards/s/SoulSeparator.java index aa5f131223..725652828f 100644 --- a/Mage.Sets/src/mage/cards/s/SoulSeparator.java +++ b/Mage.Sets/src/mage/cards/s/SoulSeparator.java @@ -34,7 +34,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -59,7 +59,7 @@ public class SoulSeparator extends CardImpl { // {5}, {T}, Sacrifice Soul Separator: Exile target creature card from your graveyard. // Create a token that's a copy of that card except it's 1/1, it's a Spirit in addition to its other types, and it has flying. // Create a black Zombie creature token with power equal to that card's power and toughness equal that card's toughness. - PutTokenOntoBattlefieldCopyTargetEffect copyEffect = new PutTokenOntoBattlefieldCopyTargetEffect(null, null, false, 1, false, false, null, 1, 1, true); + CreateTokenCopyTargetEffect copyEffect = new CreateTokenCopyTargetEffect(null, null, false, 1, false, false, null, 1, 1, true); copyEffect.setAdditionalSubType("Spirit"); copyEffect.setText("Create a token that's a copy of that card except it's 1/1, it's a Spirit in addition to its other types, and it has flying."); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, copyEffect, new ManaCostsImpl("{5}")); diff --git a/Mage.Sets/src/mage/cards/s/Spawnwrithe.java b/Mage.Sets/src/mage/cards/s/Spawnwrithe.java index e4fa9482c2..17eeeca17a 100644 --- a/Mage.Sets/src/mage/cards/s/Spawnwrithe.java +++ b/Mage.Sets/src/mage/cards/s/Spawnwrithe.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -52,7 +52,7 @@ public class Spawnwrithe extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); // Whenever Spawnwrithe deals combat damage to a player, create a token that's a copy of Spawnwrithe. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect(), false)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new CreateTokenCopySourceEffect(), false)); } diff --git a/Mage.Sets/src/mage/cards/s/SpittingImage.java b/Mage.Sets/src/mage/cards/s/SpittingImage.java index 735419229c..b1209264be 100644 --- a/Mage.Sets/src/mage/cards/s/SpittingImage.java +++ b/Mage.Sets/src/mage/cards/s/SpittingImage.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.keyword.RetraceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -54,7 +54,7 @@ public class SpittingImage extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{G/U}{G/U}"); // Create a token that's a copy of target creature. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); // Retrace (You may cast this card from your graveyard by discarding a land card in addition to paying its other costs.) diff --git a/Mage.Sets/src/mage/cards/s/SplinterTwin.java b/Mage.Sets/src/mage/cards/s/SplinterTwin.java index 36a0e5fe35..c9981a97fb 100644 --- a/Mage.Sets/src/mage/cards/s/SplinterTwin.java +++ b/Mage.Sets/src/mage/cards/s/SplinterTwin.java @@ -37,7 +37,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -103,7 +103,7 @@ class SplinterTwinEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(permanent, game)); effect.apply(game, source); for (Permanent addedToken : effect.getAddedPermanent()) { diff --git a/Mage.Sets/src/mage/cards/s/SplittingSlime.java b/Mage.Sets/src/mage/cards/s/SplittingSlime.java index 6322473028..45c544ca9c 100644 --- a/Mage.Sets/src/mage/cards/s/SplittingSlime.java +++ b/Mage.Sets/src/mage/cards/s/SplittingSlime.java @@ -30,7 +30,7 @@ package mage.cards.s; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.MonstrosityAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -52,7 +52,7 @@ public class SplittingSlime extends CardImpl { this.addAbility(new MonstrosityAbility("{4}{G}{G}", 3)); // When Splitting Slime becomes monstrous, create a token that's a copy of Splitting Slime. - this.addAbility(new BecomesMonstrousSourceTriggeredAbility(new PutTokenOntoBattlefieldCopySourceEffect())); + this.addAbility(new BecomesMonstrousSourceTriggeredAbility(new CreateTokenCopySourceEffect())); } diff --git a/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java b/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java index e8e6ac9974..106f1f9572 100644 --- a/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java +++ b/Mage.Sets/src/mage/cards/s/SproutingPhytohydra.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.DealtDamageToSourceTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.PutTokenOntoBattlefieldCopySourceEffect; +import mage.abilities.effects.CreateTokenCopySourceEffect; import mage.abilities.keyword.DefenderAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -54,7 +54,7 @@ public class SproutingPhytohydra extends CardImpl { // Defender this.addAbility(DefenderAbility.getInstance()); // Whenever Sprouting Phytohydra is dealt damage, you may create a token that's a copy of Sprouting Phytohydra. - Effect effect = new PutTokenOntoBattlefieldCopySourceEffect(); + Effect effect = new CreateTokenCopySourceEffect(); effect.setText("you may create a token that's a copy of {this}"); this.addAbility(new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, effect, true)); } diff --git a/Mage.Sets/src/mage/cards/s/StolenIdentity.java b/Mage.Sets/src/mage/cards/s/StolenIdentity.java index fb5856e320..3a0d8a23f3 100644 --- a/Mage.Sets/src/mage/cards/s/StolenIdentity.java +++ b/Mage.Sets/src/mage/cards/s/StolenIdentity.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.effects.common.CipherEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -54,7 +54,7 @@ public class StolenIdentity extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{U}{U}"); // Create a token that's a copy of target artifact or creature. - this.getSpellAbility().addEffect(new PutTokenOntoBattlefieldCopyTargetEffect()); + this.getSpellAbility().addEffect(new CreateTokenCopyTargetEffect()); this.getSpellAbility().addTarget(new TargetPermanent(filter)); // Cipher this.getSpellAbility().addEffect(new CipherEffect()); diff --git a/Mage.Sets/src/mage/cards/s/SupplantForm.java b/Mage.Sets/src/mage/cards/s/SupplantForm.java index bf83582175..1ed9b2032d 100644 --- a/Mage.Sets/src/mage/cards/s/SupplantForm.java +++ b/Mage.Sets/src/mage/cards/s/SupplantForm.java @@ -29,7 +29,7 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +48,7 @@ public class SupplantForm extends CardImpl { // Return target creature to its owner's hand. You create a token that's a copy of that creature. this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setText("You create a token that's a copy of that creature"); this.getSpellAbility().addEffect(effect); } diff --git a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java index ad80e9bc86..0c75bfe781 100644 --- a/Mage.Sets/src/mage/cards/t/TemptWithReflections.java +++ b/Mage.Sets/src/mage/cards/t/TemptWithReflections.java @@ -33,7 +33,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -88,7 +88,7 @@ class TemptWithReflectionsEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(this.getTargetPointer().getFirst(game, source)); if (permanent != null) { - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); @@ -111,13 +111,13 @@ class TemptWithReflectionsEffect extends OneShotEffect { } while (!player.getId().equals(game.getActivePlayerId())); for (UUID playerId : playersSaidYes) { - effect = new PutTokenOntoBattlefieldCopyTargetEffect(playerId); + effect = new CreateTokenCopyTargetEffect(playerId); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); } if (!playersSaidYes.isEmpty()) { - effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(getTargetPointer()); effect.apply(game, source); } diff --git a/Mage.Sets/src/mage/cards/t/TheScarabGod.java b/Mage.Sets/src/mage/cards/t/TheScarabGod.java index f793d92e0f..d5b5fd1c26 100644 --- a/Mage.Sets/src/mage/cards/t/TheScarabGod.java +++ b/Mage.Sets/src/mage/cards/t/TheScarabGod.java @@ -39,7 +39,7 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.cards.Card; @@ -161,7 +161,7 @@ class TheScarabGodEffect2 extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && card != null) { controller.moveCards(card, Zone.EXILED, source, game); // Also if the move to exile is replaced, the copy takes place - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, 1, false, false, null, 4, 4, false); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 1, false, false, null, 4, 4, false); effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game))); effect.setOnlySubType("Zombie"); effect.setOnlyColor(ObjectColor.BLACK); diff --git a/Mage.Sets/src/mage/cards/t/Twinflame.java b/Mage.Sets/src/mage/cards/t/Twinflame.java index 565e9b91b3..17bd0ce651 100644 --- a/Mage.Sets/src/mage/cards/t/Twinflame.java +++ b/Mage.Sets/src/mage/cards/t/Twinflame.java @@ -33,7 +33,7 @@ import mage.abilities.abilityword.StriveAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -101,7 +101,7 @@ class TwinflameCopyEffect extends OneShotEffect { for (UUID creatureId : this.getTargetPointer().getTargets(game, source)) { Permanent creature = game.getPermanentOrLKIBattlefield(creatureId); if (creature != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true); effect.setTargetPointer(new FixedTarget(creature, game)); effect.apply(game, source); toExile.addAll(effect.getAddedPermanent()); diff --git a/Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java b/Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java similarity index 57% rename from Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java rename to Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java index 5fdba542a4..d0220524e7 100644 --- a/Mage/src/main/java/mage/abilities/effects/PutTokenOntoBattlefieldCopySourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/CreateTokenCopySourceEffect.java @@ -1,7 +1,7 @@ package mage.abilities.effects; import mage.abilities.Ability; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -10,21 +10,21 @@ import mage.target.targetpointer.FixedTarget; /** * Created by glerman on 20/6/15. */ -public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { +public class CreateTokenCopySourceEffect extends OneShotEffect { private final int number; - public PutTokenOntoBattlefieldCopySourceEffect() { + public CreateTokenCopySourceEffect() { this(1); } - public PutTokenOntoBattlefieldCopySourceEffect(int copies) { + public CreateTokenCopySourceEffect(int copies) { super(Outcome.PutCreatureInPlay); this.number = copies; staticText = "create a token that's a copy of {this}"; } - public PutTokenOntoBattlefieldCopySourceEffect(final PutTokenOntoBattlefieldCopySourceEffect effect) { + public CreateTokenCopySourceEffect(final CreateTokenCopySourceEffect effect) { super(effect); this.number = effect.number; } @@ -33,7 +33,7 @@ public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (permanent != null) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, false, number); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, number); effect.setTargetPointer(new FixedTarget(source.getSourceId())); return effect.apply(game, source); } @@ -41,7 +41,7 @@ public class PutTokenOntoBattlefieldCopySourceEffect extends OneShotEffect { } @Override - public PutTokenOntoBattlefieldCopySourceEffect copy() { - return new PutTokenOntoBattlefieldCopySourceEffect(this); + public CreateTokenCopySourceEffect copy() { + return new CreateTokenCopySourceEffect(this); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java similarity index 84% rename from Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java rename to Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java index 9c3e4da898..b268294353 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PutTokenOntoBattlefieldCopyTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenCopyTargetEffect.java @@ -54,7 +54,7 @@ import mage.util.functions.EmptyApplyToPermanent; * * @author LevelX2 */ -public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { +public class CreateTokenCopyTargetEffect extends OneShotEffect { private final UUID playerId; private final CardType additionalCardType; @@ -74,12 +74,12 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { private boolean useLKI = false; private boolean isntLegendary = false; - public PutTokenOntoBattlefieldCopyTargetEffect(boolean useLKI) { + public CreateTokenCopyTargetEffect(boolean useLKI) { this(); this.useLKI = useLKI; } - public PutTokenOntoBattlefieldCopyTargetEffect() { + public CreateTokenCopyTargetEffect() { super(Outcome.PutCreatureInPlay); this.playerId = null; this.additionalCardType = null; @@ -95,15 +95,15 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.color = null; } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId) { + public CreateTokenCopyTargetEffect(UUID playerId) { this(playerId, null, false); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste) { this(playerId, additionalCardType, gainsHaste, 1); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number) { this(playerId, additionalCardType, gainsHaste, number, false, false); } @@ -117,15 +117,15 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { * @param tapped * @param attacking */ - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking) { this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, null); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer) { this(playerId, additionalCardType, gainsHaste, number, tapped, attacking, attackedPlayer, Integer.MIN_VALUE, Integer.MIN_VALUE, false); } - public PutTokenOntoBattlefieldCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) { + public CreateTokenCopyTargetEffect(UUID playerId, CardType additionalCardType, boolean gainsHaste, int number, boolean tapped, boolean attacking, UUID attackedPlayer, int power, int toughness, boolean gainsFlying) { super(Outcome.PutCreatureInPlay); this.playerId = playerId; this.additionalCardType = additionalCardType; @@ -140,7 +140,7 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { this.gainsFlying = gainsFlying; } - public PutTokenOntoBattlefieldCopyTargetEffect(final PutTokenOntoBattlefieldCopyTargetEffect effect) { + public CreateTokenCopyTargetEffect(final CreateTokenCopyTargetEffect effect) { super(effect); this.playerId = effect.playerId; this.additionalCardType = effect.additionalCardType; @@ -258,8 +258,8 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { } @Override - public PutTokenOntoBattlefieldCopyTargetEffect copy() { - return new PutTokenOntoBattlefieldCopyTargetEffect(this); + public CreateTokenCopyTargetEffect copy() { + return new CreateTokenCopyTargetEffect(this); } @Override @@ -267,27 +267,29 @@ public class PutTokenOntoBattlefieldCopyTargetEffect extends OneShotEffect { if (staticText != null && !staticText.isEmpty()) { return staticText; } - StringBuilder sb = new StringBuilder(); - sb.append("Put "); + StringBuilder sb = new StringBuilder("create "); if (number == 1) { - sb.append("a token"); + sb.append("a "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append("token"); } else { - sb.append(CardUtil.numberToText(number)).append(" tokens"); + sb.append(number); + sb.append(" "); + if (tapped && !attacking) { + sb.append("tapped "); + } + sb.append("tokens"); } - sb.append(" onto the battlefield "); - if (tapped && !attacking) { - sb.append("tapped "); - } else if (!tapped && attacking) { - sb.append("attacking "); - } else if (tapped && attacking) { - sb.append("tapped and attacking "); - } - sb.append("that's a copy of target "); - if (mode.getTargets() != null) { - sb.append(mode.getTargets().get(0).getTargetName()); + if (attacking) { + sb.append(" that are"); + if (tapped) { + sb.append(" tapped and"); + } + sb.append(" attacking"); } return sb.toString(); - } public List getAddedPermanent() { diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 71deb80ab0..e0e5fcac8d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -159,6 +159,7 @@ public class CreateTokenEffect extends OneShotEffect { } } if (attacking) { + sb.append(" that are"); if (tapped) { sb.append(" tapped and"); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java index 753a4a96f8..418b9e7593 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenTargetEffect.java @@ -91,6 +91,7 @@ public class CreateTokenTargetEffect extends OneShotEffect { } } if (attacking) { + sb.append(" that are"); if (tapped) { sb.append(" tapped and"); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java index aceb92f35a..3b80d45ba1 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PopulateEffect.java @@ -90,7 +90,7 @@ public class PopulateEffect extends OneShotEffect { if (!game.isSimulation()) { game.informPlayers("Token selected for populate: " + tokenToCopy.getLogName()); } - Effect effect = new PutTokenOntoBattlefieldCopyTargetEffect(); + Effect effect = new CreateTokenCopyTargetEffect(); effect.setTargetPointer(new FixedTarget(target.getFirstTarget())); return effect.apply(game, source); } diff --git a/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java b/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java index d09b69ee59..79f0754e57 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MyriadAbility.java @@ -35,7 +35,7 @@ import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.constants.Outcome; import mage.constants.SetTargetPointer; import mage.game.Game; @@ -102,7 +102,7 @@ class MyriadEffect extends OneShotEffect { Player opponent = game.getPlayer(playerId); if (opponent != null && controller.chooseUse(Outcome.PutCreatureInPlay, "Put a copy of " + sourceObject.getIdName() + " onto battlefield attacking " + opponent.getName() + '?', source, game)) { - PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(controller.getId(), null, false, 1, true, true, playerId); + CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(controller.getId(), null, false, 1, true, true, playerId); effect.setTargetPointer(new FixedTarget(sourceObject, game)); effect.apply(game, source); tokens.addAll(effect.getAddedPermanent()); From e954de0012c138448d2bd838141a9b0df4b78072 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 18:04:41 -0400 Subject: [PATCH 072/100] Implemented Fathom Fleet Captain --- .../src/mage/cards/f/FathomFleetCaptain.java | 90 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + .../game/permanent/token/PirateToken.java | 50 +++++++++++ 3 files changed, 141 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java create mode 100644 Mage/src/main/java/mage/game/permanent/token/PirateToken.java diff --git a/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java new file mode 100644 index 0000000000..5ca4677a1a --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FathomFleetCaptain.java @@ -0,0 +1,90 @@ +/* + * 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.common.AttacksTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.PirateToken; + +/** + * + * @author TheElk801 + */ +public class FathomFleetCaptain extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another nontoken Pirate"); + + static { + filter.add(new SubtypePredicate(SubType.PIRATE)); + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new TokenPredicate())); + } + + public FathomFleetCaptain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Menace + this.addAbility(new MenaceAbility()); + + // Whenever Fathom Fleet Captain attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace. + this.addAbility(new ConditionalTriggeredAbility( + new AttacksTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new PirateToken()), new GenericManaCost(2)), false), + new PermanentsOnTheBattlefieldCondition(filter), + "Whenever {this} attacks, if you control another nontoken Pirate, you may pay {2}. If you do, creature a 2/2 black Pirate creature token with menace")); + } + + public FathomFleetCaptain(final FathomFleetCaptain card) { + super(card); + } + + @Override + public FathomFleetCaptain copy() { + return new FathomFleetCaptain(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index a5abf0b667..16d7d35985 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -61,6 +61,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); + cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); cards.add(new SetCardInfo("Favorable Winds", 56, Rarity.UNCOMMON, mage.cards.f.FavorableWinds.class)); cards.add(new SetCardInfo("Gishath, Sun's Avatar", 222, Rarity.MYTHIC, mage.cards.g.GishathSunsAvatar.class)); cards.add(new SetCardInfo("Glacial Fortress", 255, Rarity.RARE, mage.cards.g.GlacialFortress.class)); diff --git a/Mage/src/main/java/mage/game/permanent/token/PirateToken.java b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java new file mode 100644 index 0000000000..fe4d04270f --- /dev/null +++ b/Mage/src/main/java/mage/game/permanent/token/PirateToken.java @@ -0,0 +1,50 @@ +/* +* 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.game.permanent.token; + +import mage.constants.CardType; +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +import mage.constants.SubType; + +/** + * + * @author TheElk801 + */ +public class PirateToken extends Token { + + public PirateToken() { + super("Pirate", "2/2 black Pirate creature token with menace"); + cardType.add(CardType.CREATURE); + color.setBlack(true); + subtype.add(SubType.PIRATE); + power = new MageInt(2); + toughness = new MageInt(2); + addAbility(new MenaceAbility()); + } +} From ce2c1bb61de77366e5bc2f56219231120aafbdc9 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 18:09:54 -0400 Subject: [PATCH 073/100] Implemented Kinjalli's Sunwing --- .../src/mage/cards/k/KinjallisSunwing.java | 117 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KinjallisSunwing.java diff --git a/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java b/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java new file mode 100644 index 0000000000..8f03a7d3af --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KinjallisSunwing.java @@ -0,0 +1,117 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.FlyingAbility; +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.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author TheElk801 + */ +public class KinjallisSunwing extends CardImpl { + + public KinjallisSunwing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Creatures your opponents control enter the battlefield tapped. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KinjallisSunwingEffect())); + } + + public KinjallisSunwing(final KinjallisSunwing card) { + super(card); + } + + @Override + public KinjallisSunwing copy() { + return new KinjallisSunwing(this); + } +} + +class KinjallisSunwingEffect extends ReplacementEffectImpl { + + KinjallisSunwingEffect() { + super(Duration.WhileOnBattlefield, Outcome.Tap); + staticText = "Creatures your opponents control enter the battlefield tapped"; + } + + KinjallisSunwingEffect(final KinjallisSunwingEffect effect) { + super(effect); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent target = ((EntersTheBattlefieldEvent) event).getTarget(); + if (target != null) { + target.tap(game); + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent != null && permanent.isCreature()) { + return true; + } + } + return false; + } + + @Override + public KinjallisSunwingEffect copy() { + return new KinjallisSunwingEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 16d7d35985..f7d55ce22c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -77,6 +77,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Jace's Sentinel", 283, Rarity.UNCOMMON, mage.cards.j.JacesSentinel.class)); cards.add(new SetCardInfo("Jace, Cunning Castaway", 60, Rarity.MYTHIC, mage.cards.j.JaceCunningCastaway.class)); cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); + cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); From 8b6aa6d463b627ef281a31911fe516d5fd942ba5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 20:59:41 -0400 Subject: [PATCH 074/100] Implemented Sorcerous Spyglass --- .../src/mage/cards/s/SorcerousSpyglass.java | 149 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + Utils/mtg-cards-data.txt | 2 +- 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java diff --git a/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java new file mode 100644 index 0000000000..3bee634072 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SorcerousSpyglass.java @@ -0,0 +1,149 @@ +/* + * 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.s; + +import java.util.Optional; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.NameACardEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class SorcerousSpyglass extends CardImpl { + + public SorcerousSpyglass(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); + + // As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name. + this.addAbility(new AsEntersBattlefieldAbility(new SorcerousSpyglassEntersEffect())); + + // Activated abilities of sources with the chosen name can't be activated unless they're mana abilities. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SorcerousSpyglassActivationEffect())); + } + + public SorcerousSpyglass(final SorcerousSpyglass card) { + super(card); + } + + @Override + public SorcerousSpyglass copy() { + return new SorcerousSpyglass(this); + } +} + +class SorcerousSpyglassEntersEffect extends NameACardEffect { + + SorcerousSpyglassEntersEffect() { + super(NameACardEffect.TypeOfName.ALL); + staticText = "look at an opponent's hand, then choose any card name"; + } + + SorcerousSpyglassEntersEffect(final SorcerousSpyglassEntersEffect effect) { + super(effect); + } + + @Override + public SorcerousSpyglassEntersEffect copy() { + return new SorcerousSpyglassEntersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + TargetOpponent target = new TargetOpponent(true); + if (player.choose(Outcome.Benefit, target, source.getSourceId(), game)) { + Player opponent = game.getPlayer(target.getFirstTarget()); + if (opponent != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + player.lookAtCards(sourceObject != null ? sourceObject.getIdName() : null, opponent.getHand(), game); + player.chooseUse(Outcome.Benefit, "Press ok to name a card", "You won't be able to resize the window once you do", "Ok", " ", source, game); + } + } + } + return super.apply(game, source); + } +} + +class SorcerousSpyglassActivationEffect extends ContinuousRuleModifyingEffectImpl { + + public SorcerousSpyglassActivationEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment); + staticText = "Activated abilities of sources with the chosen name can't be activated unless they're mana abilities"; + } + + public SorcerousSpyglassActivationEffect(final SorcerousSpyglassActivationEffect effect) { + super(effect); + } + + @Override + public SorcerousSpyglassActivationEffect copy() { + return new SorcerousSpyglassActivationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject object = game.getObject(event.getSourceId()); + Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); + if (ability.isPresent() && object != null) { + if (game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId()) // controller in range + && ability.get().getAbilityType() != AbilityType.MANA + && object.getName().equals(game.getState().getValue(source.getSourceId().toString() + NameACardEffect.INFO_KEY))) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index f7d55ce22c..0ca424afd0 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -108,6 +108,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); + cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 2820ecda21..640f7f0a77 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32421,7 +32421,7 @@ Primal Amulet|Ixalan|243|R|{4}|Artifact|||Instant and sorcery spells you cast co Primal Wellspring|Ixalan|243|R||Land|||Add one mana of any color to your mana pool. When that mana is spent to cast an instant or sorcery spell, copy that spell and you may choose new targets for the copy.| Sentinel Totem|Ixalan|245|U|{1}|Artifact|||When Sentinel Totem enters the battlefield, scry 1.${T}, Exile Sentinel Totem: Exile all cards from all graveyards.| Sleek Schooner|Ixalan|247|U|{3}|Artifact - Vehicle|4|3|Crew 1| -Sorcerous Spyglass|Ixalan|248|R|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| +Sorcerous Spyglass|Ixalan|248|R|{2}|Artifact|||As Sorcerous Spyglass enters the battlefield, look at an opponent's hand, then choose any card name.$Activated abilities of sources with the chosen name can't be activated unless they're mana abilities.| Thaumatic Compass|Ixalan|249|R|{2}|Artifact|||{3}, {T}: Search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.$At the beginning of your end step, if you control seven or more lands, transform Thaumatic Compass.| Spires of Orazca|Ixalan|249|R||Land|||{T}: Add {C} to your mana pool.${T}: Untap target attacking creature an opponent controls and remove it from combat.| Treasure Cove|Ixalan|250|R||Land|||{T}: Add {C} to your mana pool.${T}, Sacrifice a Treasure: Draw a card.| From c765f0d8e9d9bdaf317663aa996a1811feb086dc Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 22:13:34 -0400 Subject: [PATCH 075/100] Implemented Wakening Sun's Avatar --- .../src/mage/cards/w/WakeningSunsAvatar.java | 81 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 82 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.java diff --git a/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.java b/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.java new file mode 100644 index 0000000000..e1d40982e5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/w/WakeningSunsAvatar.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.w; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.CastFromHandSourceCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.watchers.common.CastFromHandWatcher; + +/** + * + * @author TheElk801 + */ +public class WakeningSunsAvatar extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Dinosaur creatures"); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.DINOSAUR))); + } + + public WakeningSunsAvatar(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{W}{W}{W}"); + + this.subtype.add("Dinosaur"); + this.subtype.add("Avatar"); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + // When Wakening Sun's Avatar enters the battlefield, if you cast it from you hand, destroy all non-Dinosaur creatures. + this.addAbility(new ConditionalTriggeredAbility( + new EntersBattlefieldTriggeredAbility(new DestroyAllEffect(filter), false), + CastFromHandSourceCondition.instance, + "When {this} enters the battlefield, if you cast it from your hand, destroy all non-Dinosaur creatures."), + new CastFromHandWatcher()); + } + + public WakeningSunsAvatar(final WakeningSunsAvatar card) { + super(card); + } + + @Override + public WakeningSunsAvatar copy() { + return new WakeningSunsAvatar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0ca424afd0..eea7a36826 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -129,6 +129,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Vanquisher's Banner", 251, Rarity.RARE, mage.cards.v.VanquishersBanner.class)); cards.add(new SetCardInfo("Verdant Sun's Avatar", 213, Rarity.RARE, mage.cards.v.VerdantSunsAvatar.class)); cards.add(new SetCardInfo("Vraska's Contempt", 129, Rarity.RARE, mage.cards.v.VraskasContempt.class)); + cards.add(new SetCardInfo("Wakening Sun's Avatar", 44, Rarity.MYTHIC, mage.cards.w.WakeningSunsAvatar.class)); cards.add(new SetCardInfo("Waker of the Wilds", 215, Rarity.RARE, mage.cards.w.WakerOfTheWilds.class)); cards.add(new SetCardInfo("Walk the Plank", 130, Rarity.UNCOMMON, mage.cards.w.WalkThePlank.class)); cards.add(new SetCardInfo("Wanted Scoundrels", 131, Rarity.UNCOMMON, mage.cards.w.WantedScoundrels.class)); From c5fc7f715c44d027dfa68ea6a9e5f02e06509b5a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 22:29:59 -0400 Subject: [PATCH 076/100] added Dinosaur errata --- Mage.Sets/src/mage/cards/a/AlphaTyrranax.java | 8 ++++---- Mage.Sets/src/mage/cards/d/DeathmistRaptor.java | 7 ++++--- Mage.Sets/src/mage/cards/d/Dromosaur.java | 7 ++++--- Mage.Sets/src/mage/cards/f/Fungusaur.java | 7 ++++--- Mage.Sets/src/mage/cards/i/Imperiosaur.java | 6 ++++-- Mage.Sets/src/mage/cards/m/Magmasaur.java | 7 ++++--- Mage.Sets/src/mage/cards/p/Pangosaur.java | 8 +++++--- Mage.Sets/src/mage/cards/p/PutridRaptor.java | 8 ++++---- Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java | 5 +++-- Mage.Sets/src/mage/cards/r/RidgetopRaptor.java | 7 ++++--- Mage.Sets/src/mage/cards/r/RipscalePredator.java | 5 +++-- Mage.Sets/src/mage/cards/s/ShivanRaptor.java | 14 +++++++------- Mage.Sets/src/mage/cards/t/Tyrranax.java | 6 ++++-- Utils/mtg-cards-data.txt | 2 +- 14 files changed, 55 insertions(+), 42 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java b/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java index ad52403a27..70f3a694f3 100644 --- a/Mage.Sets/src/mage/cards/a/AlphaTyrranax.java +++ b/Mage.Sets/src/mage/cards/a/AlphaTyrranax.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 mage.cards.a; import java.util.UUID; @@ -41,15 +40,16 @@ import mage.constants.SubType; */ public class AlphaTyrranax extends CardImpl { - public AlphaTyrranax (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); + public AlphaTyrranax(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.subtype.add(SubType.BEAST); this.power = new MageInt(6); this.toughness = new MageInt(5); } - public AlphaTyrranax (final AlphaTyrranax card) { + public AlphaTyrranax(final AlphaTyrranax card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java b/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java index e0d8cdeefd..0eea387ca7 100644 --- a/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java +++ b/Mage.Sets/src/mage/cards/d/DeathmistRaptor.java @@ -41,6 +41,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; @@ -53,9 +54,9 @@ import mage.players.Player; public class DeathmistRaptor extends CardImpl { public DeathmistRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(3); this.toughness = new MageInt(3); diff --git a/Mage.Sets/src/mage/cards/d/Dromosaur.java b/Mage.Sets/src/mage/cards/d/Dromosaur.java index a154addcd3..18966f7110 100644 --- a/Mage.Sets/src/mage/cards/d/Dromosaur.java +++ b/Mage.Sets/src/mage/cards/d/Dromosaur.java @@ -35,6 +35,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; /** * @@ -43,8 +44,8 @@ import mage.constants.Duration; public class Dromosaur extends CardImpl { public Dromosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(3); @@ -61,4 +62,4 @@ public class Dromosaur extends CardImpl { public Dromosaur copy() { return new Dromosaur(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/f/Fungusaur.java b/Mage.Sets/src/mage/cards/f/Fungusaur.java index 54595e11b2..9b8690c443 100644 --- a/Mage.Sets/src/mage/cards/f/Fungusaur.java +++ b/Mage.Sets/src/mage/cards/f/Fungusaur.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.counters.CounterType; @@ -44,9 +45,9 @@ import mage.counters.CounterType; public class Fungusaur extends CardImpl { public Fungusaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); - this.subtype.add("Fungus"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.subtype.add(SubType.FUNGUS); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/i/Imperiosaur.java b/Mage.Sets/src/mage/cards/i/Imperiosaur.java index 785a643cd3..a630c9a3f9 100644 --- a/Mage.Sets/src/mage/cards/i/Imperiosaur.java +++ b/Mage.Sets/src/mage/cards/i/Imperiosaur.java @@ -33,6 +33,7 @@ import mage.abilities.StaticAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.SuperType; import mage.constants.Zone; import mage.filter.common.FilterLandPermanent; @@ -45,13 +46,14 @@ import mage.filter.predicate.mageobject.SupertypePredicate; public class Imperiosaur extends CardImpl { private static final FilterLandPermanent filter = new FilterLandPermanent(); + static { filter.add(new SupertypePredicate(SuperType.BASIC)); } public Imperiosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(5); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/m/Magmasaur.java b/Mage.Sets/src/mage/cards/m/Magmasaur.java index 82fe68b611..5878c29ca6 100644 --- a/Mage.Sets/src/mage/cards/m/Magmasaur.java +++ b/Mage.Sets/src/mage/cards/m/Magmasaur.java @@ -40,6 +40,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; @@ -57,9 +58,9 @@ import mage.players.Player; public class Magmasaur extends CardImpl { public Magmasaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}"); - this.subtype.add("Elemental"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(0); this.toughness = new MageInt(0); diff --git a/Mage.Sets/src/mage/cards/p/Pangosaur.java b/Mage.Sets/src/mage/cards/p/Pangosaur.java index 61658b75e0..8f4c448081 100644 --- a/Mage.Sets/src/mage/cards/p/Pangosaur.java +++ b/Mage.Sets/src/mage/cards/p/Pangosaur.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.ReturnToHandSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; @@ -46,8 +47,8 @@ import mage.game.events.GameEvent.EventType; public class Pangosaur extends CardImpl { public Pangosaur(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(6); this.toughness = new MageInt(6); @@ -66,6 +67,7 @@ public class Pangosaur extends CardImpl { } class PangosaurTriggeredAbility extends TriggeredAbilityImpl { + PangosaurTriggeredAbility() { super(Zone.BATTLEFIELD, new ReturnToHandSourceEffect()); } @@ -83,7 +85,7 @@ class PangosaurTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { return true; } - + @Override public PangosaurTriggeredAbility copy() { return new PangosaurTriggeredAbility(this); diff --git a/Mage.Sets/src/mage/cards/p/PutridRaptor.java b/Mage.Sets/src/mage/cards/p/PutridRaptor.java index 38f11681e9..afc93ff5e9 100644 --- a/Mage.Sets/src/mage/cards/p/PutridRaptor.java +++ b/Mage.Sets/src/mage/cards/p/PutridRaptor.java @@ -51,10 +51,10 @@ public class PutridRaptor extends CardImpl { } public PutridRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{B}"); - this.subtype.add("Zombie"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}"); + this.subtype.add(SubType.ZOMBIE); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(4); this.toughness = new MageInt(4); diff --git a/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java b/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java index ea2b4f0bc1..2174447741 100644 --- a/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java +++ b/Mage.Sets/src/mage/cards/p/PygmyAllosaurus.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.SwampwalkAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,8 +42,8 @@ import mage.constants.CardType; public class PygmyAllosaurus extends CardImpl { public PygmyAllosaurus(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{G}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java b/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java index 78094359aa..5c3be5f1fd 100644 --- a/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java +++ b/Mage.Sets/src/mage/cards/r/RidgetopRaptor.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.DoubleStrikeAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,9 +42,9 @@ import mage.constants.CardType; public class RidgetopRaptor extends CardImpl { public RidgetopRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); - this.subtype.add("Lizard"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(2); this.toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/cards/r/RipscalePredator.java b/Mage.Sets/src/mage/cards/r/RipscalePredator.java index afc172951e..916b3383d9 100644 --- a/Mage.Sets/src/mage/cards/r/RipscalePredator.java +++ b/Mage.Sets/src/mage/cards/r/RipscalePredator.java @@ -33,6 +33,7 @@ import mage.abilities.keyword.MenaceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -41,8 +42,8 @@ import mage.constants.CardType; public class RipscalePredator extends CardImpl { public RipscalePredator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(6); this.toughness = new MageInt(5); diff --git a/Mage.Sets/src/mage/cards/s/ShivanRaptor.java b/Mage.Sets/src/mage/cards/s/ShivanRaptor.java index 0bc6cf6a6c..bd590865ac 100644 --- a/Mage.Sets/src/mage/cards/s/ShivanRaptor.java +++ b/Mage.Sets/src/mage/cards/s/ShivanRaptor.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 mage.cards.s; import java.util.UUID; @@ -36,6 +35,7 @@ import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.SubType; /** * @@ -44,15 +44,15 @@ import mage.constants.CardType; public class ShivanRaptor extends CardImpl { public ShivanRaptor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); - this.subtype.add("Lizard"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(3); this.toughness = new MageInt(1); - this.addAbility(FirstStrikeAbility.getInstance()); - this.addAbility(HasteAbility.getInstance()); - this.addAbility(new EchoAbility("{2}{R}")); + this.addAbility(FirstStrikeAbility.getInstance()); + this.addAbility(HasteAbility.getInstance()); + this.addAbility(new EchoAbility("{2}{R}")); } public ShivanRaptor(final ShivanRaptor card) { @@ -64,4 +64,4 @@ public class ShivanRaptor extends CardImpl { return new ShivanRaptor(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/Tyrranax.java b/Mage.Sets/src/mage/cards/t/Tyrranax.java index 12d9b26384..ed12ed6ac8 100644 --- a/Mage.Sets/src/mage/cards/t/Tyrranax.java +++ b/Mage.Sets/src/mage/cards/t/Tyrranax.java @@ -36,6 +36,7 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; +import mage.constants.SubType; import mage.constants.Zone; /** @@ -45,8 +46,9 @@ import mage.constants.Zone; public class Tyrranax extends CardImpl { public Tyrranax(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{G}{G}"); - this.subtype.add("Beast"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.subtype.add(SubType.DINOSAUR); + this.subtype.add(SubType.BEAST); this.power = new MageInt(5); this.toughness = new MageInt(4); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 640f7f0a77..f7f1901c8e 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -11196,7 +11196,7 @@ Daru Sanctifier|Legions|9|C|{3}{W}|Creature - Human Cleric|1|4|Morph {1}{W} Y Clickslither|Legions|90|R|{1}{R}{R}{R}|Creature - Insect|3|3|Haste$Sacrifice a Goblin: Clickslither gets +2/+2 and gains trample until end of turn.| Crested Craghorn|Legions|91|C|{4}{R}|Creature - Goat Beast|4|1|Haste$Provoke (When this attacks, you may have target creature defending player controls untap and block it if able.)| Flamewave Invoker|Legions|92|C|{2}{R}|Creature - Goblin Mutant|2|2|{7}{R}: Flamewave Invoker deals 5 damage to target player.| -Frenetic Raptor|Legions|93|U|{5}{R}|Creature - Lizard Beast|6|6|Beasts can't block.| +Frenetic Raptor|Legions|93|U|{5}{R}|Creature - Dinosaur Beast|6|6|Beasts can't block.| Gempalm Incinerator|Legions|94|U|{2}{R}|Creature - Goblin|2|1|Cycling {1}{R} ({1}{R}, Discard this card: Draw a card.)$When you cycle Gempalm Incinerator, you may have it deal X damage to target creature, where X is the number of Goblins on the battlefield.| Goblin Assassin|Legions|95|U|{3}{R}{R}|Creature - Goblin Assassin|2|2|Whenever Goblin Assassin or another Goblin enters the battlefield, each player flips a coin. Each player whose coin comes up tails sacrifices a creature.| Goblin Clearcutter|Legions|96|U|{3}{R}|Creature - Goblin|3|3|{tap}, Sacrifice a Forest: Add three mana in any combination of {R} and/or {G} to your mana pool.| From ffa519dc08da9fcd6c15c101f4e8c0827d550831 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Wed, 6 Sep 2017 22:39:28 -0400 Subject: [PATCH 077/100] Implemented Frenetic Raptor --- Mage.Sets/src/mage/cards/b/Bedlam.java | 38 ++-------- .../src/mage/cards/f/FreneticRaptor.java | 70 +++++++++++++++++++ Mage.Sets/src/mage/sets/Legions.java | 1 + 3 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/f/FreneticRaptor.java diff --git a/Mage.Sets/src/mage/cards/b/Bedlam.java b/Mage.Sets/src/mage/cards/b/Bedlam.java index 0baceb297d..ccee7bc212 100644 --- a/Mage.Sets/src/mage/cards/b/Bedlam.java +++ b/Mage.Sets/src/mage/cards/b/Bedlam.java @@ -25,18 +25,19 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.b; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.RestrictionEffect; +import mage.abilities.effects.common.combat.CantBlockAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; @@ -47,11 +48,10 @@ import mage.game.permanent.Permanent; public class Bedlam extends CardImpl { public Bedlam(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}"); // Creatures can't block. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BedlamEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES, Duration.WhileOnBattlefield))); } public Bedlam(final Bedlam card) { @@ -63,33 +63,3 @@ public class Bedlam extends CardImpl { return new Bedlam(this); } } - -class BedlamEffect extends RestrictionEffect { - - BedlamEffect() { - super(Duration.WhileOnBattlefield); - staticText = "Creatures can't block"; - } - - BedlamEffect(final BedlamEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - if (permanent.isCreature()) { - return true; - } - return false; - } - - @Override - public BedlamEffect copy() { - return new BedlamEffect(this); - } - - @Override - public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/f/FreneticRaptor.java b/Mage.Sets/src/mage/cards/f/FreneticRaptor.java new file mode 100644 index 0000000000..096276a83c --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FreneticRaptor.java @@ -0,0 +1,70 @@ +/* + * 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.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBlockAllEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class FreneticRaptor extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.BEAST, "Beasts"); + + public FreneticRaptor(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}"); + + this.subtype.add("Dinosaur"); + this.subtype.add("Beast"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Beasts can't block. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAllEffect(filter, Duration.WhileOnBattlefield))); + } + + public FreneticRaptor(final FreneticRaptor card) { + super(card); + } + + @Override + public FreneticRaptor copy() { + return new FreneticRaptor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Legions.java b/Mage.Sets/src/mage/sets/Legions.java index 6f407f9535..21d1a61636 100644 --- a/Mage.Sets/src/mage/sets/Legions.java +++ b/Mage.Sets/src/mage/sets/Legions.java @@ -97,6 +97,7 @@ public class Legions extends ExpansionSet { cards.add(new SetCardInfo("Essence Sliver", 13, Rarity.RARE, mage.cards.e.EssenceSliver.class)); cards.add(new SetCardInfo("Feral Throwback", 126, Rarity.RARE, mage.cards.f.FeralThrowback.class)); cards.add(new SetCardInfo("Flamewave Invoker", 92, Rarity.COMMON, mage.cards.f.FlamewaveInvoker.class)); + cards.add(new SetCardInfo("Frenetic Raptor", 93, Rarity.UNCOMMON, mage.cards.f.FreneticRaptor.class)); cards.add(new SetCardInfo("Fugitive Wizard", 38, Rarity.COMMON, mage.cards.f.FugitiveWizard.class)); cards.add(new SetCardInfo("Gempalm Avenger", 14, Rarity.COMMON, mage.cards.g.GempalmAvenger.class)); cards.add(new SetCardInfo("Gempalm Incinerator", 94, Rarity.UNCOMMON, mage.cards.g.GempalmIncinerator.class)); From b6dceb28c894c318aef5d44360aee214aed4fa4f Mon Sep 17 00:00:00 2001 From: Justin Herlehy Date: Wed, 6 Sep 2017 20:38:11 -0700 Subject: [PATCH 078/100] Code Cleanup Deprecated SubTypeList methods that expect strings and List. Readability cleanup for SubType Enum. --- .../SetCardSubtypeAttachedEffect.java | 20 +- .../src/main/java/mage/constants/SubType.java | 631 +++++++++--------- Mage/src/main/java/mage/util/SubTypeList.java | 22 +- 3 files changed, 354 insertions(+), 319 deletions(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index fafe47f266..f68d71d251 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -29,13 +29,16 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.SubTypeList; -import java.util.List; - /** * @author nantuko */ @@ -44,7 +47,14 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { private SubTypeList setSubtypes = new SubTypeList(); private final AttachmentType attachmentType; - public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { + public SetCardSubtypeAttachedEffect(Duration duration, AttachmentType attachmentType, SubType... setSubtype) { + super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.setSubtypes.add(setSubtype); + this.attachmentType = attachmentType; + this.setText(); + } + + /*public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; @@ -56,7 +66,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { this.setSubtypes.addAll(setSubtypes); this.attachmentType = attachmentType; setText(); - } + }*/ public SetCardSubtypeAttachedEffect(final SetCardSubtypeAttachedEffect effect) { super(effect); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index cd6edde011..9c597260dc 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -1,396 +1,410 @@ package mage.constants; -import mage.util.SubTypeList; - import java.util.Arrays; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; +import mage.util.SubTypeList; + public enum SubType { //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. - ARCANE("Arcane", SubTypeSet.SpellType, false), - TRAP("Trap", SubTypeSet.SpellType, false), + ARCANE("Arcane", SubTypeSet.SpellType), + TRAP("Trap", SubTypeSet.SpellType), + // 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types. // Of that list, Forest, Island, Mountain, Plains, and Swamp are the basic land types. - FOREST("Forest", SubTypeSet.BasicLandType, false), - ISLAND("Island", SubTypeSet.BasicLandType, false), - MOUNTAIN("Mountain", SubTypeSet.BasicLandType, false), - PLAINS("Plains", SubTypeSet.BasicLandType, false), - SWAMP("Swamp", SubTypeSet.BasicLandType, false), - DESERT("Desert", SubTypeSet.NonBasicLandType, false), - GATE("Gate", SubTypeSet.NonBasicLandType, false), - LAIR("Lair", SubTypeSet.NonBasicLandType, false), - LOCUS("Locus", SubTypeSet.NonBasicLandType, false), - URZAS("Urza's", SubTypeSet.NonBasicLandType, false), - MINE("Mine", SubTypeSet.NonBasicLandType, false), - POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType, false), - TOWER("Tower", SubTypeSet.NonBasicLandType, false), + FOREST("Forest", SubTypeSet.BasicLandType), + ISLAND("Island", SubTypeSet.BasicLandType), + MOUNTAIN("Mountain", SubTypeSet.BasicLandType), + PLAINS("Plains", SubTypeSet.BasicLandType), + SWAMP("Swamp", SubTypeSet.BasicLandType), + DESERT("Desert", SubTypeSet.NonBasicLandType), + GATE("Gate", SubTypeSet.NonBasicLandType), + LAIR("Lair", SubTypeSet.NonBasicLandType), + LOCUS("Locus", SubTypeSet.NonBasicLandType), + URZAS("Urza's", SubTypeSet.NonBasicLandType), + MINE("Mine", SubTypeSet.NonBasicLandType), + POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType), + TOWER("Tower", SubTypeSet.NonBasicLandType), + // 205.3h Enchantments have their own unique set of subtypes; these subtypes are called enchantment types. - AURA("Aura", SubTypeSet.EnchantmentType, false), - CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType, false), - CURSE("Curse", SubTypeSet.EnchantmentType, false), - SHRINE("Shrine", SubTypeSet.EnchantmentType, false), + AURA("Aura", SubTypeSet.EnchantmentType), + CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType), + CURSE("Curse", SubTypeSet.EnchantmentType), + SHRINE("Shrine", SubTypeSet.EnchantmentType), + // 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types. - CLUE("Clue", SubTypeSet.ArtifactType, false), - CONTRAPTION("Contraption", SubTypeSet.ArtifactType, false), - EQUIPMENT("Equipment", SubTypeSet.ArtifactType, false), - FORTIFICATION("Fortification", SubTypeSet.ArtifactType, false), - TREASURE("Treasure", SubTypeSet.ArtifactType, false), - VEHICLE("Vehicle", SubTypeSet.ArtifactType, false), + CLUE("Clue", SubTypeSet.ArtifactType), + CONTRAPTION("Contraption", SubTypeSet.ArtifactType), + EQUIPMENT("Equipment", SubTypeSet.ArtifactType), + FORTIFICATION("Fortification", SubTypeSet.ArtifactType), + TREASURE("Treasure", SubTypeSet.ArtifactType), + VEHICLE("Vehicle", SubTypeSet.ArtifactType), + // 205.3m : Creatures and tribals share their lists of subtypes; these subtypes are called creature types. // A - ADVISOR("Advisor", SubTypeSet.CreatureType, false), - AETHERBORN("Aetherborn", SubTypeSet.CreatureType, false), - ALLY("Ally", SubTypeSet.CreatureType, false), - ANGEL("Angel", SubTypeSet.CreatureType, false), - ANTELOPE("Antelope", SubTypeSet.CreatureType, false), + ADVISOR("Advisor", SubTypeSet.CreatureType), + AETHERBORN("Aetherborn", SubTypeSet.CreatureType), + ALLY("Ally", SubTypeSet.CreatureType), + ANGEL("Angel", SubTypeSet.CreatureType), + ANTELOPE("Antelope", SubTypeSet.CreatureType), AQUALISH("Aqualish", SubTypeSet.CreatureType, true), // Star Wars - APE("Ape", SubTypeSet.CreatureType, false), + APE("Ape", SubTypeSet.CreatureType), ARCONA("Arcona", SubTypeSet.CreatureType, true), - ARCHER("Archer", SubTypeSet.CreatureType, false), - ARCHON("Archon", SubTypeSet.CreatureType, false), - ARTIFICER("Artificer", SubTypeSet.CreatureType, false), + ARCHER("Archer", SubTypeSet.CreatureType), + ARCHON("Archon", SubTypeSet.CreatureType), + ARTIFICER("Artificer", SubTypeSet.CreatureType), ARTIFICIER("Artificier", SubTypeSet.CreatureType, true), - ASSASSIN("Assassin", SubTypeSet.CreatureType, false), - ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType, false), - ATOG("Atog", SubTypeSet.CreatureType, false), + ASSASSIN("Assassin", SubTypeSet.CreatureType), + ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType), + ATOG("Atog", SubTypeSet.CreatureType), ATAT("AT-AT", SubTypeSet.CreatureType, true), - AUROCHS("Aurochs", SubTypeSet.CreatureType, false), + AUROCHS("Aurochs", SubTypeSet.CreatureType), AUTOBOT("Autobot", SubTypeSet.CreatureType, true), // H17, Grimlock - AVATAR("Avatar", SubTypeSet.CreatureType, false), + AVATAR("Avatar", SubTypeSet.CreatureType), // B - BADGER("Badger", SubTypeSet.CreatureType, false), - BARBARIAN("Barbarian", SubTypeSet.CreatureType, false), - BASILISK("Basilisk", SubTypeSet.CreatureType, false), - BAT("Bat", SubTypeSet.CreatureType, false), - BEAR("Bear", SubTypeSet.CreatureType, false), - BEAST("Beast", SubTypeSet.CreatureType, false), - BEEBLE("Beeble", SubTypeSet.CreatureType, false), - BERSERKER("Berserker", SubTypeSet.CreatureType, false), - BIRD("Bird", SubTypeSet.CreatureType, false), + BADGER("Badger", SubTypeSet.CreatureType), + BARBARIAN("Barbarian", SubTypeSet.CreatureType), + BASILISK("Basilisk", SubTypeSet.CreatureType), + BAT("Bat", SubTypeSet.CreatureType), + BEAR("Bear", SubTypeSet.CreatureType), + BEAST("Beast", SubTypeSet.CreatureType), + BEEBLE("Beeble", SubTypeSet.CreatureType), + BERSERKER("Berserker", SubTypeSet.CreatureType), + BIRD("Bird", SubTypeSet.CreatureType), BITH("Bith", SubTypeSet.CreatureType, true), // Star Wars - BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType, false), - BOAR("Boar", SubTypeSet.CreatureType, false), - BRINGER("Bringer", SubTypeSet.CreatureType, false), - BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType, false), + BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType), + BOAR("Boar", SubTypeSet.CreatureType), + BRINGER("Bringer", SubTypeSet.CreatureType), + BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType), // C CALAMARI("Calamari", SubTypeSet.CreatureType, true), // Star Wars - CAMARID("Camarid", SubTypeSet.CreatureType, false), - CAMEL("Camel", SubTypeSet.CreatureType, false), - CARIBOU("Caribou", SubTypeSet.CreatureType, false), - CARRIER("Carrier", SubTypeSet.CreatureType, false), - CAT("Cat", SubTypeSet.CreatureType, false), - CENTAUR("Centaur", SubTypeSet.CreatureType, false), + CAMARID("Camarid", SubTypeSet.CreatureType), + CAMEL("Camel", SubTypeSet.CreatureType), + CARIBOU("Caribou", SubTypeSet.CreatureType), + CARRIER("Carrier", SubTypeSet.CreatureType), + CAT("Cat", SubTypeSet.CreatureType), + CENTAUR("Centaur", SubTypeSet.CreatureType), CEREAN("Cerean", SubTypeSet.CreatureType, true), // Star Wars - CEPHALID("Cephalid", SubTypeSet.CreatureType, false), - CHIMERA("Chimera", SubTypeSet.CreatureType, false), + CEPHALID("Cephalid", SubTypeSet.CreatureType), + CHIMERA("Chimera", SubTypeSet.CreatureType), CHISS("Chiss", SubTypeSet.CreatureType, true), - CITIZEN("Citizen", SubTypeSet.CreatureType, false), - CLERIC("Cleric", SubTypeSet.CreatureType, false), - COCKATRICE("Cockatrice", SubTypeSet.CreatureType, false), - CONSTRUCT("Construct", SubTypeSet.CreatureType, false), - COWARD("Coward", SubTypeSet.CreatureType, false), - CRAB("Crab", SubTypeSet.CreatureType, false), - CROCODILE("Crocodile", SubTypeSet.CreatureType, false), + CITIZEN("Citizen", SubTypeSet.CreatureType), + CLERIC("Cleric", SubTypeSet.CreatureType), + COCKATRICE("Cockatrice", SubTypeSet.CreatureType), + CONSTRUCT("Construct", SubTypeSet.CreatureType), + COWARD("Coward", SubTypeSet.CreatureType), + CRAB("Crab", SubTypeSet.CreatureType), + CROCODILE("Crocodile", SubTypeSet.CreatureType), CYBORG("Cyborg", SubTypeSet.CreatureType, true), // Star Wars - CYCLOPS("Cyclops", SubTypeSet.CreatureType, false), + CYCLOPS("Cyclops", SubTypeSet.CreatureType), // D DATHOMIRIAN("Dathomirian", SubTypeSet.CreatureType, true), // Star Wars - DAUTHI("Dauthi", SubTypeSet.CreatureType, false), - DEMON("Demon", SubTypeSet.CreatureType, false), - DESERTER("Deserter", SubTypeSet.CreatureType, false), - DEVIL("Devil", SubTypeSet.CreatureType, false), - DINOSAUR("Dinosaur", SubTypeSet.CreatureType, false), // With Ixalan now being spoiled, need this to be selectable - DJINN("Djinn", SubTypeSet.CreatureType, false), - DRAGON("Dragon", SubTypeSet.CreatureType, false), - DRAKE("Drake", SubTypeSet.CreatureType, false), - DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType, false), - DRONE("Drone", SubTypeSet.CreatureType, false), - DRUID("Druid", SubTypeSet.CreatureType, false), + DAUTHI("Dauthi", SubTypeSet.CreatureType), + DEMON("Demon", SubTypeSet.CreatureType), + DESERTER("Deserter", SubTypeSet.CreatureType), + DEVIL("Devil", SubTypeSet.CreatureType), + DINOSAUR("Dinosaur", SubTypeSet.CreatureType), // With Ixalan now being spoiled, need this to be selectable + DJINN("Djinn", SubTypeSet.CreatureType), + DRAGON("Dragon", SubTypeSet.CreatureType), + DRAKE("Drake", SubTypeSet.CreatureType), + DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType), + DRONE("Drone", SubTypeSet.CreatureType), + DRUID("Druid", SubTypeSet.CreatureType), DROID("Droid", SubTypeSet.CreatureType, true), // Star Wars - DRYAD("Dryad", SubTypeSet.CreatureType, false), - DWARF("Dwarf", SubTypeSet.CreatureType, false), + DRYAD("Dryad", SubTypeSet.CreatureType), + DWARF("Dwarf", SubTypeSet.CreatureType), // E - EFREET("Efreet", SubTypeSet.CreatureType, false), - ELDER("Elder", SubTypeSet.CreatureType, false), - ELDRAZI("Eldrazi", SubTypeSet.CreatureType, false), - ELEMENTAL("Elemental", SubTypeSet.CreatureType, false), - ELEPHANT("Elephant", SubTypeSet.CreatureType, false), - ELF("Elf", SubTypeSet.CreatureType, false), - ELK("Elk", SubTypeSet.CreatureType, false), - EYE("Eye", SubTypeSet.CreatureType, false), + EFREET("Efreet", SubTypeSet.CreatureType), + ELDER("Elder", SubTypeSet.CreatureType), + ELDRAZI("Eldrazi", SubTypeSet.CreatureType), + ELEMENTAL("Elemental", SubTypeSet.CreatureType), + ELEPHANT("Elephant", SubTypeSet.CreatureType), + ELF("Elf", SubTypeSet.CreatureType), + ELK("Elk", SubTypeSet.CreatureType), + EYE("Eye", SubTypeSet.CreatureType), EWOK("Ewok", SubTypeSet.CreatureType, true), // Star Wars // F - FAERIE("Faerie", SubTypeSet.CreatureType, false), - FERRET("Ferret", SubTypeSet.CreatureType, false), - FISH("Fish", SubTypeSet.CreatureType, false), - FLAGBEARER("Flagbearer", SubTypeSet.CreatureType, false), - FOX("Fox", SubTypeSet.CreatureType, false), - FROG("Frog", SubTypeSet.CreatureType, false), - FUNGUS("Fungus", SubTypeSet.CreatureType, false), + FAERIE("Faerie", SubTypeSet.CreatureType), + FERRET("Ferret", SubTypeSet.CreatureType), + FISH("Fish", SubTypeSet.CreatureType), + FLAGBEARER("Flagbearer", SubTypeSet.CreatureType), + FOX("Fox", SubTypeSet.CreatureType), + FROG("Frog", SubTypeSet.CreatureType), + FUNGUS("Fungus", SubTypeSet.CreatureType), // G GAMORREAN("Gamorrean", SubTypeSet.CreatureType, true), // Star Wars GAND("Gand", SubTypeSet.CreatureType, true), // Star Wars - GARGOYLE("Gargoyle", SubTypeSet.CreatureType, false), - GERM("Germ", SubTypeSet.CreatureType, false), - GIANT("Giant", SubTypeSet.CreatureType, false), - GNOME("Gnome", SubTypeSet.CreatureType, false), - GOLEM("Golem", SubTypeSet.CreatureType, false), - GOAT("Goat", SubTypeSet.CreatureType, false), - GOBLIN("Goblin", SubTypeSet.CreatureType, false), - GOD("God", SubTypeSet.CreatureType, false), - GORGON("Gorgon", SubTypeSet.CreatureType, false), - GRAVEBORN("Graveborn", SubTypeSet.CreatureType, false), - GREMLIN("Gremlin", SubTypeSet.CreatureType, false), - GRIFFIN("Griffin", SubTypeSet.CreatureType, false), + GARGOYLE("Gargoyle", SubTypeSet.CreatureType), + GERM("Germ", SubTypeSet.CreatureType), + GIANT("Giant", SubTypeSet.CreatureType), + GNOME("Gnome", SubTypeSet.CreatureType), + GOLEM("Golem", SubTypeSet.CreatureType), + GOAT("Goat", SubTypeSet.CreatureType), + GOBLIN("Goblin", SubTypeSet.CreatureType), + GOD("God", SubTypeSet.CreatureType), + GORGON("Gorgon", SubTypeSet.CreatureType), + GRAVEBORN("Graveborn", SubTypeSet.CreatureType), + GREMLIN("Gremlin", SubTypeSet.CreatureType), + GRIFFIN("Griffin", SubTypeSet.CreatureType), GUNGAN("Gungan", SubTypeSet.CreatureType, true), // Star Wars // H - HAG("Hag", SubTypeSet.CreatureType, false), - HARPY("Harpy", SubTypeSet.CreatureType, false), - HELLION("Hellion", SubTypeSet.CreatureType, false), - HIPPO("Hippo", SubTypeSet.CreatureType, false), - HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType, false), - HOMARID("Homarid", SubTypeSet.CreatureType, false), - HOMUNCULUS("Homunculus", SubTypeSet.CreatureType, false), - HORROR("Horror", SubTypeSet.CreatureType, false), - HORSE("Horse", SubTypeSet.CreatureType, false), - HOUND("Hound", SubTypeSet.CreatureType, false), - HUMAN("Human", SubTypeSet.CreatureType, false), - HUNTER("Hunter", SubTypeSet.CreatureType, false), + HAG("Hag", SubTypeSet.CreatureType), + HARPY("Harpy", SubTypeSet.CreatureType), + HELLION("Hellion", SubTypeSet.CreatureType), + HIPPO("Hippo", SubTypeSet.CreatureType), + HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType), + HOMARID("Homarid", SubTypeSet.CreatureType), + HOMUNCULUS("Homunculus", SubTypeSet.CreatureType), + HORROR("Horror", SubTypeSet.CreatureType), + HORSE("Horse", SubTypeSet.CreatureType), + HOUND("Hound", SubTypeSet.CreatureType), + HUMAN("Human", SubTypeSet.CreatureType), + HUNTER("Hunter", SubTypeSet.CreatureType), HUTT("Hutt", SubTypeSet.CreatureType, true), // Star Wars - HYDRA("Hydra", SubTypeSet.CreatureType, false), - HYENA("Hyena", SubTypeSet.CreatureType, false), + HYDRA("Hydra", SubTypeSet.CreatureType), + HYENA("Hyena", SubTypeSet.CreatureType), // I - ILLUSION("Illusion", SubTypeSet.CreatureType, false), - IMP("Imp", SubTypeSet.CreatureType, false), - INCARNATION("Incarnation", SubTypeSet.CreatureType, false), - INSECT("Insect", SubTypeSet.CreatureType, false), + ILLUSION("Illusion", SubTypeSet.CreatureType), + IMP("Imp", SubTypeSet.CreatureType), + INCARNATION("Incarnation", SubTypeSet.CreatureType), + INSECT("Insect", SubTypeSet.CreatureType), ITHORIAN("Ithorian", SubTypeSet.CreatureType, true), // Star Wars // J - JACKAL("Jackal", SubTypeSet.CreatureType, false), + JACKAL("Jackal", SubTypeSet.CreatureType), JAWA("Jawa", SubTypeSet.CreatureType, true), JEDI("Jedi", SubTypeSet.CreatureType, true), // Star Wars - JELLYFISH("Jellyfish", SubTypeSet.CreatureType, false), - JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType, false), + JELLYFISH("Jellyfish", SubTypeSet.CreatureType), + JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType), // K KALEESH("Kaleesh", SubTypeSet.CreatureType, true), // Star Wars - KAVU("Kavu", SubTypeSet.CreatureType, false), + KAVU("Kavu", SubTypeSet.CreatureType), KELDOR("KelDor", SubTypeSet.CreatureType, true), - KIRIN("Kirin", SubTypeSet.CreatureType, false), - KITHKIN("Kithkin", SubTypeSet.CreatureType, false), - KNIGHT("Knight", SubTypeSet.CreatureType, false), - KOBOLD("Kobold", SubTypeSet.CreatureType, false), + KIRIN("Kirin", SubTypeSet.CreatureType), + KITHKIN("Kithkin", SubTypeSet.CreatureType), + KNIGHT("Knight", SubTypeSet.CreatureType), + KOBOLD("Kobold", SubTypeSet.CreatureType), KOORIVAR("Koorivar", SubTypeSet.CreatureType, true), - KOR("Kor", SubTypeSet.CreatureType, false), - KRAKEN("Kraken", SubTypeSet.CreatureType, false), + KOR("Kor", SubTypeSet.CreatureType), + KRAKEN("Kraken", SubTypeSet.CreatureType), // L - LAMIA("Lamia", SubTypeSet.CreatureType, false), - LAMMASU("Lammasu", SubTypeSet.CreatureType, false), - LEECH("Leech", SubTypeSet.CreatureType, false), - LEVIATHAN("Leviathan", SubTypeSet.CreatureType, false), - LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType, false), - LICID("Licid", SubTypeSet.CreatureType, false), - LIZARD("Lizard", SubTypeSet.CreatureType, false), + LAMIA("Lamia", SubTypeSet.CreatureType), + LAMMASU("Lammasu", SubTypeSet.CreatureType), + LEECH("Leech", SubTypeSet.CreatureType), + LEVIATHAN("Leviathan", SubTypeSet.CreatureType), + LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType), + LICID("Licid", SubTypeSet.CreatureType), + LIZARD("Lizard", SubTypeSet.CreatureType), // M MANTELLIAN("Mantellian", SubTypeSet.CreatureType, true), // Star Wars - MANTICORE("Manticore", SubTypeSet.CreatureType, false), - MASTICORE("Masticore", SubTypeSet.CreatureType, false), - MERCENARY("Mercenary", SubTypeSet.CreatureType, false), - MERFOLK("Merfolk", SubTypeSet.CreatureType, false), - METATHRAN("Metathran", SubTypeSet.CreatureType, false), - MINION("Minion", SubTypeSet.CreatureType, false), - MINOTAUR("Minotaur", SubTypeSet.CreatureType, false), + MANTICORE("Manticore", SubTypeSet.CreatureType), + MASTICORE("Masticore", SubTypeSet.CreatureType), + MERCENARY("Mercenary", SubTypeSet.CreatureType), + MERFOLK("Merfolk", SubTypeSet.CreatureType), + METATHRAN("Metathran", SubTypeSet.CreatureType), + MINION("Minion", SubTypeSet.CreatureType), + MINOTAUR("Minotaur", SubTypeSet.CreatureType), MIRIALAN("Mirialan", SubTypeSet.CreatureType, true), // Star Wars - MOLE("Mole", SubTypeSet.CreatureType, false), - MONGER("Monger", SubTypeSet.CreatureType, false), - MONGOOSE("Mongoose", SubTypeSet.CreatureType, false), - MONK("Monk", SubTypeSet.CreatureType, false), - MONKEY("Monkey", SubTypeSet.CreatureType, false), - MOONFOLK("Moonfolk", SubTypeSet.CreatureType, false), - MUTANT("Mutant", SubTypeSet.CreatureType, false), - MYR("Myr", SubTypeSet.CreatureType, false), - MYSTIC("Mystic", SubTypeSet.CreatureType, false), + MOLE("Mole", SubTypeSet.CreatureType), + MONGER("Monger", SubTypeSet.CreatureType), + MONGOOSE("Mongoose", SubTypeSet.CreatureType), + MONK("Monk", SubTypeSet.CreatureType), + MONKEY("Monkey", SubTypeSet.CreatureType), + MOONFOLK("Moonfolk", SubTypeSet.CreatureType), + MUTANT("Mutant", SubTypeSet.CreatureType), + MYR("Myr", SubTypeSet.CreatureType), + MYSTIC("Mystic", SubTypeSet.CreatureType), // N - NAGA("Naga", SubTypeSet.CreatureType, false), - NAUTILUS("Nautilus", SubTypeSet.CreatureType, false), + NAGA("Naga", SubTypeSet.CreatureType), + NAUTILUS("Nautilus", SubTypeSet.CreatureType), NAUTOLAN("Nautolan", SubTypeSet.CreatureType, true), // Star Wars NEIMOIDIAN("Neimoidian", SubTypeSet.CreatureType, true), // Star Wars - NEPHILIM("Nephilim", SubTypeSet.CreatureType, false), - NIGHTMARE("Nightmare", SubTypeSet.CreatureType, false), - NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType, false), - NINJA("Ninja", SubTypeSet.CreatureType, false), - NOGGLE("Noggle", SubTypeSet.CreatureType, false), - NOMAD("Nomad", SubTypeSet.CreatureType, false), - NYMPH("Nymph", SubTypeSet.CreatureType, false), + NEPHILIM("Nephilim", SubTypeSet.CreatureType), + NIGHTMARE("Nightmare", SubTypeSet.CreatureType), + NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType), + NINJA("Ninja", SubTypeSet.CreatureType), + NOGGLE("Noggle", SubTypeSet.CreatureType), + NOMAD("Nomad", SubTypeSet.CreatureType), + NYMPH("Nymph", SubTypeSet.CreatureType), // O - OCTOPUS("Octopus", SubTypeSet.CreatureType, false), - OGRE("Ogre", SubTypeSet.CreatureType, false), - OOZE("Ooze", SubTypeSet.CreatureType, false), - ORB("Orb", SubTypeSet.CreatureType, false), - ORC("Orc", SubTypeSet.CreatureType, false), - ORGG("Orgg", SubTypeSet.CreatureType, false), + OCTOPUS("Octopus", SubTypeSet.CreatureType), + OGRE("Ogre", SubTypeSet.CreatureType), + OOZE("Ooze", SubTypeSet.CreatureType), + ORB("Orb", SubTypeSet.CreatureType), + ORC("Orc", SubTypeSet.CreatureType), + ORGG("Orgg", SubTypeSet.CreatureType), ORTOLAN("Ortolan", SubTypeSet.CreatureType, true), - OUPHE("Ouphe", SubTypeSet.CreatureType, false), - OX("Ox", SubTypeSet.CreatureType, false), - OYSTER("Oyster", SubTypeSet.CreatureType, false), + OUPHE("Ouphe", SubTypeSet.CreatureType), + OX("Ox", SubTypeSet.CreatureType), + OYSTER("Oyster", SubTypeSet.CreatureType), // P - PEGASUS("Pegasus", SubTypeSet.CreatureType, false), - PENTAVITE("Pentavite", SubTypeSet.CreatureType, false), - PEST("Pest", SubTypeSet.CreatureType, false), - PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType, false), - PHOENIX("Phoenix", SubTypeSet.CreatureType, false), - PILOT("Pilot", SubTypeSet.CreatureType, false), - PINCHER("Pincher", SubTypeSet.CreatureType, false), - PIRATE("Pirate", SubTypeSet.CreatureType, false), - PLANT("Plant", SubTypeSet.CreatureType, false), - PRAETOR("Praetor", SubTypeSet.CreatureType, false), - PRISM("Prism", SubTypeSet.CreatureType, false), - PROCESSOR("Processor", SubTypeSet.CreatureType, false), + PEGASUS("Pegasus", SubTypeSet.CreatureType), + PENTAVITE("Pentavite", SubTypeSet.CreatureType), + PEST("Pest", SubTypeSet.CreatureType), + PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType), + PHOENIX("Phoenix", SubTypeSet.CreatureType), + PILOT("Pilot", SubTypeSet.CreatureType), + PINCHER("Pincher", SubTypeSet.CreatureType), + PIRATE("Pirate", SubTypeSet.CreatureType), + PLANT("Plant", SubTypeSet.CreatureType), + PRAETOR("Praetor", SubTypeSet.CreatureType), + PRISM("Prism", SubTypeSet.CreatureType), + PROCESSOR("Processor", SubTypeSet.CreatureType), PUREBLOOD("Pureblood", SubTypeSet.CreatureType, true), // Q QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars // R - RABBIT("Rabbit", SubTypeSet.CreatureType, false), - RAT("Rat", SubTypeSet.CreatureType, false), - REBEL("Rebel", SubTypeSet.CreatureType, false), - REFLECTION("Reflection", SubTypeSet.CreatureType, false), - RHINO("Rhino", SubTypeSet.CreatureType, false), - RIGGER("Rigger", SubTypeSet.CreatureType, false), + RABBIT("Rabbit", SubTypeSet.CreatureType), + RAT("Rat", SubTypeSet.CreatureType), + REBEL("Rebel", SubTypeSet.CreatureType), + REFLECTION("Reflection", SubTypeSet.CreatureType), + RHINO("Rhino", SubTypeSet.CreatureType), + RIGGER("Rigger", SubTypeSet.CreatureType), RODIAN("Rodian", SubTypeSet.CreatureType, true), // Star Wars - ROGUE("Rogue", SubTypeSet.CreatureType, false), + ROGUE("Rogue", SubTypeSet.CreatureType), // S - SABLE("Sable", SubTypeSet.CreatureType, false), - SALAMANDER("Salamander", SubTypeSet.CreatureType, false), - SAMURAI("Samurai", SubTypeSet.CreatureType, false), - SAND("Sand", SubTypeSet.CreatureType, false), - SAPROLING("Saproling", SubTypeSet.CreatureType, false), - SATYR("Satyr", SubTypeSet.CreatureType, false), - SCARECROW("Scarecrow", SubTypeSet.CreatureType, false), - SCION("Scion", SubTypeSet.CreatureType, false), - SCORPION("Scorpion", SubTypeSet.CreatureType, false), - SCOUT("Scout", SubTypeSet.CreatureType, false), - SERF("Serf", SubTypeSet.CreatureType, false), - SERPENT("Serpent", SubTypeSet.CreatureType, false), - SERVO("Servo", SubTypeSet.CreatureType, false), - SHADE("Shade", SubTypeSet.CreatureType, false), - SHAMAN("Shaman", SubTypeSet.CreatureType, false), - SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType, false), - SHEEP("Sheep", SubTypeSet.CreatureType, false), - SIREN("Siren", SubTypeSet.CreatureType, false), - SITH("Sith", SubTypeSet.CreatureType, false), - SKELETON("Skeleton", SubTypeSet.CreatureType, false), - SLITH("Slith", SubTypeSet.CreatureType, false), - SLIVER("Sliver", SubTypeSet.CreatureType, false), - SLUG("Slug", SubTypeSet.CreatureType, false), - SNAKE("Snake", SubTypeSet.CreatureType, false), - SOLDIER("Soldier", SubTypeSet.CreatureType, false), - SOLTARI("Soltari", SubTypeSet.CreatureType, false), - SPAWN("Spawn", SubTypeSet.CreatureType, false), - SPECTER("Specter", SubTypeSet.CreatureType, false), - SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType, false), - SPHINX("Sphinx", SubTypeSet.CreatureType, false), - SPIDER("Spider", SubTypeSet.CreatureType, false), - SPIKE("Spike", SubTypeSet.CreatureType, false), - SPIRIT("Spirit", SubTypeSet.CreatureType, false), - SPLITTER("Splitter", SubTypeSet.CreatureType, false), - SPONGE("Sponge", SubTypeSet.CreatureType, false), - SQUID("Squid", SubTypeSet.CreatureType, false), - SQUIRREL("Squirrel", SubTypeSet.CreatureType, false), - STARFISH("Starfish", SubTypeSet.CreatureType, false), + SABLE("Sable", SubTypeSet.CreatureType), + SALAMANDER("Salamander", SubTypeSet.CreatureType), + SAMURAI("Samurai", SubTypeSet.CreatureType), + SAND("Sand", SubTypeSet.CreatureType), + SAPROLING("Saproling", SubTypeSet.CreatureType), + SATYR("Satyr", SubTypeSet.CreatureType), + SCARECROW("Scarecrow", SubTypeSet.CreatureType), + SCION("Scion", SubTypeSet.CreatureType), + SCORPION("Scorpion", SubTypeSet.CreatureType), + SCOUT("Scout", SubTypeSet.CreatureType), + SERF("Serf", SubTypeSet.CreatureType), + SERPENT("Serpent", SubTypeSet.CreatureType), + SERVO("Servo", SubTypeSet.CreatureType), + SHADE("Shade", SubTypeSet.CreatureType), + SHAMAN("Shaman", SubTypeSet.CreatureType), + SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType), + SHEEP("Sheep", SubTypeSet.CreatureType), + SIREN("Siren", SubTypeSet.CreatureType), + SITH("Sith", SubTypeSet.CreatureType), + SKELETON("Skeleton", SubTypeSet.CreatureType), + SLITH("Slith", SubTypeSet.CreatureType), + SLIVER("Sliver", SubTypeSet.CreatureType), + SLUG("Slug", SubTypeSet.CreatureType), + SNAKE("Snake", SubTypeSet.CreatureType), + SOLDIER("Soldier", SubTypeSet.CreatureType), + SOLTARI("Soltari", SubTypeSet.CreatureType), + SPAWN("Spawn", SubTypeSet.CreatureType), + SPECTER("Specter", SubTypeSet.CreatureType), + SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType), + SPHINX("Sphinx", SubTypeSet.CreatureType), + SPIDER("Spider", SubTypeSet.CreatureType), + SPIKE("Spike", SubTypeSet.CreatureType), + SPIRIT("Spirit", SubTypeSet.CreatureType), + SPLITTER("Splitter", SubTypeSet.CreatureType), + SPONGE("Sponge", SubTypeSet.CreatureType), + SQUID("Squid", SubTypeSet.CreatureType), + SQUIRREL("Squirrel", SubTypeSet.CreatureType), + STARFISH("Starfish", SubTypeSet.CreatureType), STARSHIP("Starship", SubTypeSet.CreatureType, true), // Star Wars SULLUSTAN("Sullustan", SubTypeSet.CreatureType, true), // Star Wars - SURRAKAR("Surrakar", SubTypeSet.CreatureType, false), - SURVIVOR("Survivor", SubTypeSet.CreatureType, false), + SURRAKAR("Surrakar", SubTypeSet.CreatureType), + SURVIVOR("Survivor", SubTypeSet.CreatureType), // T - TETRAVITE("Tetravite", SubTypeSet.CreatureType, false), - THALAKOS("Thalakos", SubTypeSet.CreatureType, false), - THOPTER("Thopter", SubTypeSet.CreatureType, false), + TETRAVITE("Tetravite", SubTypeSet.CreatureType), + THALAKOS("Thalakos", SubTypeSet.CreatureType), + THOPTER("Thopter", SubTypeSet.CreatureType), TRANDOSHAN("Trandoshan", SubTypeSet.CreatureType, true), // Star Wars - THRULL("Thrull", SubTypeSet.CreatureType, false), - TREEFOLK("Treefolk", SubTypeSet.CreatureType, false), - TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType, false), - TROLL("Troll", SubTypeSet.CreatureType, false), - TURTLE("Turtle", SubTypeSet.CreatureType, false), + THRULL("Thrull", SubTypeSet.CreatureType), + TREEFOLK("Treefolk", SubTypeSet.CreatureType), + TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType), + TROLL("Troll", SubTypeSet.CreatureType), + TURTLE("Turtle", SubTypeSet.CreatureType), TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U UGNAUGHT("Ugnaught", SubTypeSet.CreatureType, true), - UNICORN("Unicorn", SubTypeSet.CreatureType, false), + UNICORN("Unicorn", SubTypeSet.CreatureType), //V - VAMPIRE("Vampire", SubTypeSet.CreatureType, false), - VEDALKEN("Vedalken", SubTypeSet.CreatureType, false), - VIASHINO("Viashino", SubTypeSet.CreatureType, false), - VOLVER("Volver", SubTypeSet.CreatureType, false), + VAMPIRE("Vampire", SubTypeSet.CreatureType), + VEDALKEN("Vedalken", SubTypeSet.CreatureType), + VIASHINO("Viashino", SubTypeSet.CreatureType), + VOLVER("Volver", SubTypeSet.CreatureType), //W - WALL("Wall", SubTypeSet.CreatureType, false), - WARRIOR("Warrior", SubTypeSet.CreatureType, false), + WALL("Wall", SubTypeSet.CreatureType), + WARRIOR("Warrior", SubTypeSet.CreatureType), WEEQUAY("Weequay", SubTypeSet.CreatureType, true), - WEIRD("Weird", SubTypeSet.CreatureType, false), - WEREWOLF("Werewolf", SubTypeSet.CreatureType, false), - WHALE("Whale", SubTypeSet.CreatureType, false), - WIZARD("Wizard", SubTypeSet.CreatureType, false), - WOLF("Wolf", SubTypeSet.CreatureType, false), - WOLVERINE("Wolverine", SubTypeSet.CreatureType, false), - WOMBAT("Wombat", SubTypeSet.CreatureType, false), + WEIRD("Weird", SubTypeSet.CreatureType), + WEREWOLF("Werewolf", SubTypeSet.CreatureType), + WHALE("Whale", SubTypeSet.CreatureType), + WIZARD("Wizard", SubTypeSet.CreatureType), + WOLF("Wolf", SubTypeSet.CreatureType), + WOLVERINE("Wolverine", SubTypeSet.CreatureType), + WOMBAT("Wombat", SubTypeSet.CreatureType), WOOKIEE("Wookiee", SubTypeSet.CreatureType, true), // Star Wars - WORM("Worm", SubTypeSet.CreatureType, false), - WRAITH("Wraith", SubTypeSet.CreatureType, false), - WURM("Wurm", SubTypeSet.CreatureType, false), + WORM("Worm", SubTypeSet.CreatureType), + WRAITH("Wraith", SubTypeSet.CreatureType), + WURM("Wurm", SubTypeSet.CreatureType), // Y - YETI("Yeti", SubTypeSet.CreatureType, false), + YETI("Yeti", SubTypeSet.CreatureType), // Z ZABRAK("Zabrak", SubTypeSet.CreatureType, true), // Star Wars - ZOMBIE("Zombie", SubTypeSet.CreatureType, false), - ZUBERA("Zubera", SubTypeSet.CreatureType, false), + ZOMBIE("Zombie", SubTypeSet.CreatureType), + ZUBERA("Zubera", SubTypeSet.CreatureType), // Planeswalker - AJANI("Ajani", SubTypeSet.PlaneswalkerType, false), - ARLINN("Arlinn", SubTypeSet.PlaneswalkerType, false), - ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType, false), + AJANI("Ajani", SubTypeSet.PlaneswalkerType), + ARLINN("Arlinn", SubTypeSet.PlaneswalkerType), + ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType), AURRA("Aurra", SubTypeSet.PlaneswalkerType, true), // Star Wars - BOLAS("Bolas", SubTypeSet.PlaneswalkerType, false), - CHANDRA("Chandra", SubTypeSet.PlaneswalkerType, false), - DACK("Dack", SubTypeSet.PlaneswalkerType, false), - DARETTI("Daretti", SubTypeSet.PlaneswalkerType, false), - DOMRI("Domri", SubTypeSet.PlaneswalkerType, false), + BOLAS("Bolas", SubTypeSet.PlaneswalkerType), + CHANDRA("Chandra", SubTypeSet.PlaneswalkerType), + DACK("Dack", SubTypeSet.PlaneswalkerType), + DARETTI("Daretti", SubTypeSet.PlaneswalkerType), + DOMRI("Domri", SubTypeSet.PlaneswalkerType), DOOKU("Dooku", SubTypeSet.PlaneswalkerType, true), // Star Wars - DOVIN("Dovin", SubTypeSet.PlaneswalkerType, false), - ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType, false), - FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType, false), - GARRUK("Garruk", SubTypeSet.PlaneswalkerType, false), - GIDEON("Gideon", SubTypeSet.PlaneswalkerType, false), - HUATLI("Huatli", SubTypeSet.PlaneswalkerType, false), - JACE("Jace", SubTypeSet.PlaneswalkerType, false), - KARN("Karn", SubTypeSet.PlaneswalkerType, false), - KAYA("Kaya", SubTypeSet.PlaneswalkerType, false), - KIORA("Kiora", SubTypeSet.PlaneswalkerType, false), - KOTH("Koth", SubTypeSet.PlaneswalkerType, false), - LILIANA("Liliana", SubTypeSet.PlaneswalkerType, false), - NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType, false), - NARSET("Narset", SubTypeSet.PlaneswalkerType, false), - NISSA("Nissa", SubTypeSet.PlaneswalkerType, false), - NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType, false), + DOVIN("Dovin", SubTypeSet.PlaneswalkerType), + ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType), + FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType), + GARRUK("Garruk", SubTypeSet.PlaneswalkerType), + GIDEON("Gideon", SubTypeSet.PlaneswalkerType), + HUATLI("Huatli", SubTypeSet.PlaneswalkerType), + JACE("Jace", SubTypeSet.PlaneswalkerType), + KARN("Karn", SubTypeSet.PlaneswalkerType), + KAYA("Kaya", SubTypeSet.PlaneswalkerType), + KIORA("Kiora", SubTypeSet.PlaneswalkerType), + KOTH("Koth", SubTypeSet.PlaneswalkerType), + LILIANA("Liliana", SubTypeSet.PlaneswalkerType), + NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType), + NARSET("Narset", SubTypeSet.PlaneswalkerType), + NISSA("Nissa", SubTypeSet.PlaneswalkerType), + NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType), OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars - RAL("Ral", SubTypeSet.PlaneswalkerType, false), - SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType, false), - SAMUT("Samut", SubTypeSet.PlaneswalkerType, false), - SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType, false), + RAL("Ral", SubTypeSet.PlaneswalkerType), + SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType), + SAMUT("Samut", SubTypeSet.PlaneswalkerType), + SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType), SIDIOUS("Sidious", SubTypeSet.PlaneswalkerType, true), // Star Wars - SORIN("Sorin", SubTypeSet.PlaneswalkerType, false), - TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType, false), - TEFERI("Teferi", SubTypeSet.PlaneswalkerType, false), - TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType, false), - TIBALT("Tibalt", SubTypeSet.PlaneswalkerType, false), - UGIN("Ugin", SubTypeSet.PlaneswalkerType, false), - VENSER("Venser", SubTypeSet.PlaneswalkerType, false), - VRASKA("Vraska", SubTypeSet.PlaneswalkerType, false), - XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType, false), + SORIN("Sorin", SubTypeSet.PlaneswalkerType), + TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType), + TEFERI("Teferi", SubTypeSet.PlaneswalkerType), + TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType), + TIBALT("Tibalt", SubTypeSet.PlaneswalkerType), + UGIN("Ugin", SubTypeSet.PlaneswalkerType), + VENSER("Venser", SubTypeSet.PlaneswalkerType), + VRASKA("Vraska", SubTypeSet.PlaneswalkerType), + XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType), YODA("Yoda", SubTypeSet.PlaneswalkerType, true); // Star Wars private final SubTypeSet subTypeSet; + SubType(String description, SubTypeSet subTypeSet) { + this(description, subTypeSet, false); + } + + SubType(String description, SubTypeSet subTypeSet, boolean customSet) { + this.description = description; + this.subTypeSet = subTypeSet; + this.customSet = customSet; + } + public String getDescription() { return description; } @@ -404,12 +418,6 @@ public enum SubType { return description; } - SubType(String description, SubTypeSet subTypeSet, boolean customSet) { - this.description = description; - this.subTypeSet = subTypeSet; - this.customSet = customSet; - } - public static SubType byDescription(String subType) { for (SubType s : values()) { if (s.getDescription().equals(subType)) { @@ -434,7 +442,10 @@ public enum SubType { } public static Set getBasicLands(boolean customSet) { - return Arrays.stream(values()).filter(s -> s.customSet == customSet).filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType).collect(Collectors.toSet()); + return Arrays.stream(values()) + .filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType) + .filter(s -> s.customSet == customSet) + .collect(Collectors.toSet()); } public static SubTypeList getLandTypes(boolean customSet) { diff --git a/Mage/src/main/java/mage/util/SubTypeList.java b/Mage/src/main/java/mage/util/SubTypeList.java index 71d920983d..8f90b17a8b 100644 --- a/Mage/src/main/java/mage/util/SubTypeList.java +++ b/Mage/src/main/java/mage/util/SubTypeList.java @@ -1,20 +1,27 @@ package mage.util; -import mage.constants.SubType; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import mage.constants.SubType; + public class SubTypeList extends ArrayList { + @Deprecated public boolean addAll(List subtypes) { - return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return addAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } + @Deprecated public boolean removeAll(List subtypes){ - return removeAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return removeAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } @@ -22,10 +29,17 @@ public class SubTypeList extends ArrayList { return Collections.addAll(this, subTypes); } + public boolean removeAll(SubType... subTypes) { + return super.removeAll(Arrays.stream(subTypes) + .collect(Collectors.toList())); + } + + @Deprecated public boolean add(String s) { return add(SubType.byDescription(s)); } + @Deprecated public boolean contains(String s) { return contains(SubType.byDescription(s)); } From 55f7f381695e31f3e5f2cca51f1c2ecc3739af64 Mon Sep 17 00:00:00 2001 From: Justin Herlehy Date: Wed, 6 Sep 2017 20:39:02 -0700 Subject: [PATCH 079/100] Code Cleanup Moved mispackaged card files to correct package. Updated cards to non-string subtype methods. --- .../cards/{m => b}/BelligerentBrontodon.java | 11 +++------- Mage.Sets/src/mage/cards/c/CoalitionFlag.java | 12 ++++++++--- .../cards/{t => d}/DuskLegionDreadnought.java | 5 +++-- .../src/mage/cards/n/NimDeathmantle.java | 12 ++++++++--- Mage.Sets/src/mage/cards/o/OniPossession.java | 21 ++++--------------- Mage.Sets/src/mage/sets/Ixalan.java | 4 ++-- 6 files changed, 30 insertions(+), 35 deletions(-) rename Mage.Sets/src/mage/cards/{m => b}/BelligerentBrontodon.java (94%) rename Mage.Sets/src/mage/cards/{t => d}/DuskLegionDreadnought.java (99%) diff --git a/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java similarity index 94% rename from Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java rename to Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java index 21527d441b..81647dab15 100644 --- a/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -25,22 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.cards.m; +package mage.cards.b; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index e96f8e13bc..811512b53e 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -28,6 +28,7 @@ package mage.cards.c; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -36,7 +37,12 @@ import mage.abilities.effects.common.ruleModifying.TargetsHaveToTargetPermanentI import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -50,7 +56,7 @@ public class CoalitionFlag extends CardImpl { public CoalitionFlag(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature you control TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -60,7 +66,7 @@ public class CoalitionFlag extends CardImpl { this.addAbility(ability); // Enchanted creature is a Flagbearer. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.FLAGBEARER, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.FLAGBEARER))); // While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TargetsHaveToTargetPermanentIfAbleEffect(new FilterPermanent(SubType.FLAGBEARER, "one Flagbearer")))); diff --git a/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java similarity index 99% rename from Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java rename to Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java index 3717aef2af..8af6045cd3 100644 --- a/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java +++ b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java @@ -25,12 +25,13 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.cards.t; +package mage.cards.d; import java.util.UUID; + import mage.MageInt; -import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; diff --git a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java index add8f8fe35..968ba66159 100644 --- a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java +++ b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java @@ -28,6 +28,7 @@ package mage.cards.n; import java.util.UUID; + import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -44,7 +45,12 @@ import mage.abilities.keyword.IntimidateAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -62,7 +68,7 @@ public class NimDeathmantle extends CardImpl { public NimDeathmantle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - this.subtype.add("Equipment"); + this.subtype.add(SubType.EQUIPMENT); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4))); @@ -70,7 +76,7 @@ public class NimDeathmantle extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.ZOMBIE, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.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. this.addAbility(new NimDeathmantleTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/o/OniPossession.java b/Mage.Sets/src/mage/cards/o/OniPossession.java index c68e5dab47..03473e8a04 100644 --- a/Mage.Sets/src/mage/cards/o/OniPossession.java +++ b/Mage.Sets/src/mage/cards/o/OniPossession.java @@ -27,9 +27,8 @@ */ package mage.cards.o; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -42,12 +41,7 @@ import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -58,16 +52,9 @@ import mage.target.common.TargetCreaturePermanent; */ public class OniPossession extends CardImpl { - private static final List setSubtypes = new ArrayList<>(); - - static { - setSubtypes.add("Demon"); - setSubtypes.add("Spirit"); - } - public OniPossession(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -84,7 +71,7 @@ public class OniPossession extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA))); // Enchanted creature is a Demon Spirit. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(setSubtypes, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.DEMON, SubType.SPIRIT))); } public OniPossession(final OniPossession card) { diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index eea7a36826..2d8d8d4712 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -34,7 +34,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); - cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); + cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); @@ -58,7 +58,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Drover of the Mighty", 167, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); - cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); From 7156bad4b11e92591cdc7c6f4a479958836efd8b Mon Sep 17 00:00:00 2001 From: spjspj Date: Thu, 7 Sep 2017 15:13:50 +1000 Subject: [PATCH 080/100] Add Sunbird's Invocation (XLN) --- .../src/mage/cards/s/SunbirdsInvocation.java | 165 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 166 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java new file mode 100644 index 0000000000..37f66ca4e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -0,0 +1,165 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author spjspj + */ +public class SunbirdsInvocation extends CardImpl { + + public SunbirdsInvocation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}"); + + // Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order. + this.addAbility(new SunbirdsInvocationTriggeredAbility()); + } + + public SunbirdsInvocation(final SunbirdsInvocation card) { + super(card); + } + + @Override + public SunbirdsInvocation copy() { + return new SunbirdsInvocation(this); + } +} + +class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbility { + + public SunbirdsInvocationTriggeredAbility() { + super(new SunbirdsInvocationEffect(), false); + } + + public SunbirdsInvocationTriggeredAbility(SunbirdsInvocationTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getFromZone() == Zone.HAND) { + if (spell.getCard() != null) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(spell.getId())); + } + return true; + } + } + } + return false; + } + + @Override + public SunbirdsInvocationTriggeredAbility copy() { + return new SunbirdsInvocationTriggeredAbility(this); + } +} + +class SunbirdsInvocationEffect extends OneShotEffect { + + public SunbirdsInvocationEffect() { + super(Outcome.PutCardInPlay); + staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + } + + public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + Cards cards = new CardsImpl(); + int xValue = game.getStack().getSpell(getTargetPointer().getFirst(game, source)).getConvertedManaCost(); + cards.addAll(controller.getLibrary().getTopCards(game, xValue)); + if (!cards.isEmpty()) { + controller.revealCards(sourceObject.getIdName(), cards, game); + + FilterCard filter = new FilterNonlandCard("card revealed this way with converted mana cost " + xValue + " or less"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + TargetCard target = new TargetCard(1, Zone.LIBRARY, filter); + + if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) { + Card card = cards.get(target.getFirstTarget(), game); + if (card != null) { + if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { + Card copy = game.copyCard(card, source, source.getControllerId()); + controller.cast(copy.getSpellAbility(), game, true); + } + return true; + } + } + } + + while (!cards.isEmpty()) { + Card card = cards.getRandom(game); + if (card != null) { + cards.remove(card); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); + } + } + + return true; + } + + @Override + public SunbirdsInvocationEffect copy() { + return new SunbirdsInvocationEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 2d8d8d4712..86460a0361 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -116,6 +116,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); + cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); From 7f4252148247c486f9df3db7792f3f188109af39 Mon Sep 17 00:00:00 2001 From: spjspj Date: Thu, 7 Sep 2017 16:43:25 +1000 Subject: [PATCH 081/100] Add Sanguine Sacrament, Siren Stormtamer (XLN) --- .../src/mage/cards/s/SanguineSacrament.java | 81 ++++++++ .../src/mage/cards/s/SirenStormtamer.java | 183 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + Utils/mtg-cards-data.txt | 2 +- 4 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/s/SanguineSacrament.java create mode 100644 Mage.Sets/src/mage/cards/s/SirenStormtamer.java diff --git a/Mage.Sets/src/mage/cards/s/SanguineSacrament.java b/Mage.Sets/src/mage/cards/s/SanguineSacrament.java new file mode 100644 index 0000000000..ccf88fce75 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanguineSacrament.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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.ReturnToLibrarySpellEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; + +/** + * + * @author spjspj + */ +public class SanguineSacrament extends CardImpl { + + public SanguineSacrament(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}{W}"); + + // You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library. + this.getSpellAbility().addEffect(new GainLifeEffect(new SanguineSacramentValue())); + this.getSpellAbility().addEffect(new ReturnToLibrarySpellEffect(false)); + } + + public SanguineSacrament(final SanguineSacrament card) { + super(card); + } + + @Override + public SanguineSacrament copy() { + return new SanguineSacrament(this); + } +} + +class SanguineSacramentValue extends ManacostVariableValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return super.calculate(game, sourceAbility, effect) * 2; + } + + @Override + public SanguineSacramentValue copy() { + return new SanguineSacramentValue(); + } + + @Override + public String toString() { + return "twice X"; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SirenStormtamer.java b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java new file mode 100644 index 0000000000..10f6b519fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java @@ -0,0 +1,183 @@ +/* + * 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.s; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.target.Target; +import mage.target.TargetObject; +import mage.target.Targets; + +/** + * + * @author spjspj + */ +public class SirenStormtamer extends CardImpl { + + public SirenStormtamer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add("Siren"); + this.subtype.add("Pirate"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{U}")); + ability.addTarget(new SirenStormtamerTargetObject()); + ability.addCost(new SacrificeSourceCost()); + + this.addAbility(ability); + } + + public SirenStormtamer(final SirenStormtamer card) { + super(card); + } + + @Override + public SirenStormtamer copy() { + return new SirenStormtamer(this); + } +} + +class SirenStormtamerTargetObject extends TargetObject { + + public SirenStormtamerTargetObject() { + this.minNumberOfTargets = 1; + this.maxNumberOfTargets = 1; + this.zone = Zone.STACK; + this.targetName = "spell or ability that targets you or a creature you control"; + } + + public SirenStormtamerTargetObject(final SirenStormtamerTargetObject target) { + super(target); + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + StackObject stackObject = game.getStack().getStackObject(id); + return (stackObject instanceof Spell) || (stackObject instanceof StackAbility); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + return canChoose(sourceControllerId, game); + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + return true; + } + + if (sourceControllerId.equals(targetId)) { + return true; + } + + } + } + } + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, + Game game) { + return possibleTargets(sourceControllerId, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + possibleTargets.add(stackObject.getId()); + } + + if (sourceControllerId.equals(targetId)) { + possibleTargets.add(stackObject.getId()); + } + } + } + } + } + } + return possibleTargets; + } + + @Override + public SirenStormtamerTargetObject copy() { + return new SirenStormtamerTargetObject(this); + } + + @Override + public Filter getFilter() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 86460a0361..e01192e098 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -101,11 +101,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); + cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); + cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 640f7f0a77..3be689a6da 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32356,7 +32356,7 @@ Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| -Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| From d3f0ed6c452d387f56733e3f259b6efeb2e0a5d6 Mon Sep 17 00:00:00 2001 From: spjspj Date: Thu, 7 Sep 2017 21:14:13 +1000 Subject: [PATCH 082/100] Add Priest of the Wandering Sun (XLN) --- .../mage/cards/p/PriestOfTheWakeningSun.java | 140 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 141 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java new file mode 100644 index 0000000000..ee8ef721a6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -0,0 +1,140 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author spjspj + */ +public class PriestOfTheWakeningSun extends CardImpl { + + private static final FilterCard filter = new FilterCard("a Dinosaur card"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public PriestOfTheWakeningSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new PriestOfTheWakeningSunEffect(), TargetController.YOU, true); + this.addAbility(ability); + + // {3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(target), true, true), new ManaCostsImpl("{3}{W}{W}")); + ability2.addCost(new SacrificeSourceCost()); + this.addAbility(ability2); + } + + public PriestOfTheWakeningSun(final PriestOfTheWakeningSun card) { + super(card); + } + + @Override + public PriestOfTheWakeningSun copy() { + return new PriestOfTheWakeningSun(this); + } +} + +class PriestOfTheWakeningSunEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("a Dinosaur card to reveal"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + PriestOfTheWakeningSunEffect() { + super(Outcome.Benefit); + this.staticText = "reveal a Dinosaur card from your hand. If you do, you gain 2 life"; + } + + PriestOfTheWakeningSunEffect(final PriestOfTheWakeningSunEffect effect) { + super(effect); + } + + @Override + public PriestOfTheWakeningSunEffect copy() { + return new PriestOfTheWakeningSunEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + + if (controller != null && sourceObject != null) { + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { + if (controller.chooseUse(outcome, "Reveal a Dinosaur card?", source, game)) { + TargetCardInHand target = new TargetCardInHand(0, 1, filter); + if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { + Cards cards = new CardsImpl(); + cards.addAll(target.getTargets()); + controller.revealCards(sourceObject.getIdName(), cards, game); + controller.gainLife(2, game); + return true; + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index e01192e098..6096a7d161 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -88,6 +88,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); + cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); From e94777ad7f1f7ede86f8f08e250cc7b9b48ebfa8 Mon Sep 17 00:00:00 2001 From: spjspj Date: Thu, 7 Sep 2017 23:18:56 +1000 Subject: [PATCH 083/100] Fix CrimsonHonorGuard (XLN) --- Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java index 137ec3a036..64938d9c4a 100644 --- a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java +++ b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java @@ -97,7 +97,7 @@ class CrimsonHonorGuardEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(game.getActivePlayerId()); if (player != null) { - int numCommanders = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size(); + int numCommanders = game.getBattlefield().getAllActivePermanents(filter, player.getId(), game).size(); if (numCommanders == 0) { player.damage(4, source.getSourceId(), game, false, true); return true; From 4f0991ae97a8822702e0030b0066072013dcb5d7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 09:27:18 -0400 Subject: [PATCH 084/100] Implemented Kopala, Warden of Waves --- .../src/mage/cards/e/ElderwoodScion.java | 6 +- .../src/mage/cards/k/KopalaWardenOfWaves.java | 184 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 3 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java diff --git a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java index 87361e6c49..c008357b67 100644 --- a/Mage.Sets/src/mage/cards/e/ElderwoodScion.java +++ b/Mage.Sets/src/mage/cards/e/ElderwoodScion.java @@ -51,7 +51,7 @@ import mage.util.CardUtil; public class ElderwoodScion extends CardImpl { public ElderwoodScion(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{W}"); this.subtype.add("Elemental"); this.power = new MageInt(4); @@ -139,13 +139,13 @@ class ElderwoodScionCostReductionEffect2 extends CostModificationEffectImpl { @Override public boolean apply(Game game, Ability source, Ability abilityToModify) { SpellAbility spellAbility = (SpellAbility) abilityToModify; - CardUtil.adjustCost(spellAbility, -2); + CardUtil.increaseCost(spellAbility, 2); return true; } @Override public boolean applies(Ability abilityToModify, Ability source, Game game) { - if (abilityToModify instanceof SpellAbility) { + if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED) { if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { for (Target target : abilityToModify.getTargets()) { for (UUID targetUUID : target.getTargets()) { diff --git a/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java new file mode 100644 index 0000000000..ed4a51b1fd --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KopalaWardenOfWaves.java @@ -0,0 +1,184 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.cost.CostModificationEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityType; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class KopalaWardenOfWaves extends CardImpl { + + public KopalaWardenOfWaves(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{U}"); + + addSuperType(SuperType.LEGENDARY); + this.subtype.add("Merfolk"); + this.subtype.add("Wizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Spells your opponents cast that target a Merfolk you control cost {2} more to cast. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KopalaWardenOfWavesCostReductionEffect())); + + // Abilities your opponents activate that target a Merfolk you control cost {2} more to activate. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KopalaWardenOfWavesCostReductionEffect2())); + } + + public KopalaWardenOfWaves(final KopalaWardenOfWaves card) { + super(card); + } + + @Override + public KopalaWardenOfWaves copy() { + return new KopalaWardenOfWaves(this); + } +} + +class KopalaWardenOfWavesCostReductionEffect extends CostModificationEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Merfolk you control"); + private static final String effectText = "Spells your opponents cast that target a Merfolk you control cost {2} more to cast"; + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + KopalaWardenOfWavesCostReductionEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = effectText; + } + + KopalaWardenOfWavesCostReductionEffect(KopalaWardenOfWavesCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + SpellAbility spellAbility = (SpellAbility) abilityToModify; + CardUtil.adjustCost(spellAbility, -2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getAbilityType() == AbilityType.SPELL) { + if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { + for (Target target : abilityToModify.getTargets()) { + for (UUID targetUUID : target.getTargets()) { + Permanent creature = game.getPermanent(targetUUID); + if (creature != null + && filter.match(creature, game) + && creature.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public KopalaWardenOfWavesCostReductionEffect copy() { + return new KopalaWardenOfWavesCostReductionEffect(this); + } + +} + +class KopalaWardenOfWavesCostReductionEffect2 extends CostModificationEffectImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Merfolk you control"); + private static final String effectText = "Abilities your opponents activate that target a Merfolk you control cost {2} more to activate"; + + static { + filter.add(new SubtypePredicate(SubType.MERFOLK)); + } + + KopalaWardenOfWavesCostReductionEffect2() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST); + staticText = effectText; + } + + KopalaWardenOfWavesCostReductionEffect2(KopalaWardenOfWavesCostReductionEffect2 effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + CardUtil.increaseCost(abilityToModify, 2); + return true; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED) { + if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) { + for (Target target : abilityToModify.getTargets()) { + for (UUID targetUUID : target.getTargets()) { + Permanent creature = game.getPermanent(targetUUID); + if (creature != null + && filter.match(creature, game) + && creature.getControllerId().equals(source.getControllerId())) { + return true; + } + } + } + } + } + return false; + } + + @Override + public KopalaWardenOfWavesCostReductionEffect2 copy() { + return new KopalaWardenOfWavesCostReductionEffect2(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index eea7a36826..697a38d885 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -79,6 +79,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Jace, Ingenious Mind-Mage", 280, Rarity.MYTHIC, mage.cards.j.JaceIngeniousMindMage.class)); cards.add(new SetCardInfo("Kinjalli's Sunwing", 19, Rarity.RARE, mage.cards.k.KinjallisSunwing.class)); cards.add(new SetCardInfo("Kitesail Freebooter", 110, Rarity.UNCOMMON, mage.cards.k.KitesailFreebooter.class)); + cards.add(new SetCardInfo("Kopala, Warden of Waves", 61, Rarity.RARE, mage.cards.k.KopalaWardenOfWaves.class)); cards.add(new SetCardInfo("Kumena's Speaker", 196, Rarity.UNCOMMON, mage.cards.k.KumenasSpeaker.class)); cards.add(new SetCardInfo("Lightning Strike", 149, Rarity.UNCOMMON, mage.cards.l.LightningStrike.class)); cards.add(new SetCardInfo("Marauding Looter", 225, Rarity.UNCOMMON, mage.cards.m.MaraudingLooter.class)); From c2e25fc51ff607b3b1bdee941f3dfe99f90aefb1 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 10:01:13 -0400 Subject: [PATCH 085/100] Implemented Hostage Taker --- Mage.Sets/src/mage/cards/h/HostageTaker.java | 225 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 226 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HostageTaker.java diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java new file mode 100644 index 0000000000..c4457ce74b --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java @@ -0,0 +1,225 @@ +/* + * 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 java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AsThoughEffectType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.ManaType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.ManaPoolItem; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author TheElk801 + */ +public class HostageTaker extends CardImpl { + + private final static FilterPermanent filter = new FilterPermanent("another target artifact or creature"); + + static { + filter.add(new AnotherPredicate()); + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.CREATURE))); + } + + public HostageTaker(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{B}"); + + this.subtype.add("Human"); + this.subtype.add("Pirate"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell. + Ability ability = new EntersBattlefieldTriggeredAbility(new HostageTakerExileEffect(filter.getMessage())); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + } + + public HostageTaker(final HostageTaker card) { + super(card); + } + + @Override + public HostageTaker copy() { + return new HostageTaker(this); + } +} + +class HostageTakerExileEffect extends OneShotEffect { + + public HostageTakerExileEffect(String targetName) { + super(Outcome.Benefit); + this.staticText = "exile another target artifact or creature until {this} leaves the battlefield. " + + "You may cast that card as long as it remains exiled, " + + "and you may spend mana as though it were mana of any type to cast that spell"; + } + + public HostageTakerExileEffect(final HostageTakerExileEffect effect) { + super(effect); + } + + @Override + public HostageTakerExileEffect copy() { + return new HostageTakerExileEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent card = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && card != null) { + Player controller = game.getPlayer(card.getControllerId()); + if (controller != null) { + // move card to exile + UUID exileId = CardUtil.getCardExileZoneId(game, source); + controller.moveCardToExileWithInfo(card, exileId, permanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true); + // allow to cast the card + ContinuousEffect effect = new HostageTakerCastFromExileEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + // and you may spend mana as though it were mana of any color to cast it + effect = new HostageTakerSpendAnyManaEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + } + return false; + } +} + +class HostageTakerCastFromExileEffect extends AsThoughEffectImpl { + + public HostageTakerCastFromExileEffect() { + super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); + staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell"; + } + + public HostageTakerCastFromExileEffect(final HostageTakerCastFromExileEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HostageTakerCastFromExileEffect copy() { + return new HostageTakerCastFromExileEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectId.equals(getTargetPointer().getFirst(game, source))) { + if (affectedControllerId.equals(source.getControllerId())) { + return true; + } + } else { + if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { + // object has moved zone so effect can be discarted + this.discard(); + } + } + return false; + } +} + +class HostageTakerSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + public HostageTakerSpendAnyManaEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.Custom, Outcome.Benefit); + staticText = "you may spend mana as though it were mana of any color to cast it"; + } + + public HostageTakerSpendAnyManaEffect(final HostageTakerSpendAnyManaEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public HostageTakerSpendAnyManaEffect copy() { + return new HostageTakerSpendAnyManaEffect(this); + } + + @Override + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + if (objectId.equals(((FixedTarget) getTargetPointer()).getTarget()) + && game.getState().getZoneChangeCounter(objectId) <= ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { + + if (affectedControllerId.equals(source.getControllerId())) { + // if the card moved from exile to spell the zone change counter is increased by 1 + if (game.getState().getZoneChangeCounter(objectId) == ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1) { + return true; + } + } + + } else { + if (((FixedTarget) getTargetPointer()).getTarget().equals(objectId)) { + // object has moved zone so effect can be discarted + this.discard(); + } + } + return false; + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 697a38d885..e0e164a55b 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -69,6 +69,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Grasping Current", 282, Rarity.RARE, mage.cards.g.GraspingCurrent.class)); cards.add(new SetCardInfo("Headwater Sentries", 58, Rarity.COMMON, mage.cards.h.HeadwaterSentries.class)); cards.add(new SetCardInfo("Herald of Secret Streams", 59, Rarity.RARE, mage.cards.h.HeraldOfSecretStreams.class)); + cards.add(new SetCardInfo("Hostage Taker", 223, Rarity.RARE, mage.cards.h.HostageTaker.class)); cards.add(new SetCardInfo("Huatli's Snubhorn", 286, Rarity.COMMON, mage.cards.h.HuatlisSnubhorn.class)); cards.add(new SetCardInfo("Huatli's Spurring", 287, Rarity.UNCOMMON, mage.cards.h.HuatlisSpurring.class)); cards.add(new SetCardInfo("Huatli, Dinosaur Knight", 285, Rarity.MYTHIC, mage.cards.h.HuatliDinosaurKnight.class)); From da7ff83478c1fbf87f48e0ade5c6230ef7015573 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 10:21:10 -0400 Subject: [PATCH 086/100] Implemented Ashes of the Abhorrent --- .../src/mage/cards/a/AshesOfTheAbhorrent.java | 110 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java diff --git a/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java new file mode 100644 index 0000000000..6591636360 --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AshesOfTheAbhorrent.java @@ -0,0 +1,110 @@ +/* + * 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.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.Card; +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.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author TheElk801 + */ +public class AshesOfTheAbhorrent extends CardImpl { + + public AshesOfTheAbhorrent(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + + // Players can't cast spells from graveyards or activate abilities from graveyards. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AshesOfTheAbhorrentEffect())); + + // Whenever a creature dies, you gain 1 life. + this.addAbility(new DiesCreatureTriggeredAbility(new GainLifeEffect(1), false)); + } + + public AshesOfTheAbhorrent(final AshesOfTheAbhorrent card) { + super(card); + } + + @Override + public AshesOfTheAbhorrent copy() { + return new AshesOfTheAbhorrent(this); + } +} + +class AshesOfTheAbhorrentEffect extends ContinuousRuleModifyingEffectImpl { + + public AshesOfTheAbhorrentEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "Players can't cast spells from graveyards or activate abilities from graveyards"; + } + + public AshesOfTheAbhorrentEffect(final AshesOfTheAbhorrentEffect effect) { + super(effect); + } + + @Override + public AshesOfTheAbhorrentEffect copy() { + return new AshesOfTheAbhorrentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.CAST_SPELL + || event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Card card = game.getCard(event.getSourceId()); + if (card != null) { + Zone zone = game.getState().getZone(card.getId()); + if (zone != null && (zone == Zone.GRAVEYARD)) { + return true; + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index e0e164a55b..41577003e7 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -33,6 +33,7 @@ public class Ixalan extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); From 8e464f89a7e10b79c4d97058a8e1ec24b8eb6b42 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 11:23:11 -0400 Subject: [PATCH 087/100] Implemented Boneyard Parley --- .../src/mage/cards/b/BoneyardParley.java | 162 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + Utils/mtg-cards-data.txt | 2 + 3 files changed, 166 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/b/BoneyardParley.java diff --git a/Mage.Sets/src/mage/cards/b/BoneyardParley.java b/Mage.Sets/src/mage/cards/b/BoneyardParley.java new file mode 100644 index 0000000000..74874f678a --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BoneyardParley.java @@ -0,0 +1,162 @@ +/* + * 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.b; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetCard; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetOpponent; + +/** + * + * @author TheElk801 + */ +public class BoneyardParley extends CardImpl { + + public BoneyardParley(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}"); + + // Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards. + this.getSpellAbility().addEffect(new BoneyardParleyEffect()); + this.getSpellAbility().addTarget(new TargetCardInGraveyard(0, 5, new FilterCard("cards from graveyards"))); + } + + public BoneyardParley(final BoneyardParley card) { + super(card); + } + + @Override + public BoneyardParley copy() { + return new BoneyardParley(this); + } +} + +class BoneyardParleyEffect extends OneShotEffect { + + BoneyardParleyEffect() { + super(Outcome.Benefit); + this.staticText = "Exile up to five target creature cards from graveyards. " + + "An opponent separates those cards into two piles. " + + "Put all cards from the pile of your choice onto the battlefield under your control " + + "and the rest into their owners' graveyards"; + } + + BoneyardParleyEffect(final BoneyardParleyEffect effect) { + super(effect); + } + + @Override + public BoneyardParleyEffect copy() { + return new BoneyardParleyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + Cards cards = new CardsImpl(); + for (Target target : source.getTargets()) { + for (UUID cardId : target.getTargets()) { + cards.add(cardId); + } + } + if (!cards.isEmpty() && player.moveCards(cards, Zone.EXILED, source, game)) { + TargetOpponent targetOpponent = new TargetOpponent(true); + if (player.choose(Outcome.Neutral, targetOpponent, source.getSourceId(), game)) { + Player opponent = game.getPlayer(targetOpponent.getFirstTarget()); + if (opponent != null) { + TargetCard targetCards = new TargetCard(0, cards.size(), Zone.EXILED, new FilterCard("cards to put in the first pile")); + List pile1 = new ArrayList<>(); + if (opponent.choose(Outcome.Neutral, cards, targetCards, game)) { + List targets = targetCards.getTargets(); + for (UUID targetId : targets) { + Card card = cards.get(targetId, game); + if (card != null) { + pile1.add(card); + cards.remove(card); + } + } + } + List pile2 = new ArrayList<>(); + pile2.addAll(cards.getCards(game)); + boolean choice = player.choosePile(outcome, "Choose a pile to put onto the battlefield.", pile1, pile2, game); + + Zone pile1Zone = Zone.GRAVEYARD; + Zone pile2Zone = Zone.BATTLEFIELD; + if (choice) { + pile1Zone = Zone.BATTLEFIELD; + pile2Zone = Zone.GRAVEYARD; + } + Set pile1Set = new HashSet<>(); + Set pile2Set = new HashSet<>(); + pile1Set.addAll(pile1); + pile2Set.addAll(pile2); + +// Cards toBattlefield = new CardsImpl(); +// Cards toGraveyard = new CardsImpl(); +// +// if (pile1Zone == Zone.BATTLEFIELD) { +// toBattlefield.addAll(pile1); +// toGraveyard.addAll(pile2); +// } else { +// toBattlefield.addAll(pile2); +// toGraveyard.addAll(pile1); +// } + player.moveCards(pile1Set, pile1Zone, source, game, false, false, false, null); + player.moveCards(pile2Set, pile2Zone, source, game, false, false, false, null); + +// StringBuilder sb = new StringBuilder("Pile 1, going to ").append(pile1Zone == Zone.BATTLEFIELD ? "Battlefield" : "Graveyard").append(": "); +// game.informPlayers(sb.toString()); +// sb = new StringBuilder("Pile 2, going to ").append(pile2Zone == Zone.BATTLEFIELD ? "Battlefield" : "Graveyard").append(':'); +// game.informPlayers(sb.toString()); + } + return true; + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 41577003e7..397cd0dc15 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -38,6 +38,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); + cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); cards.add(new SetCardInfo("Burning Sun's Avatar", 135, Rarity.RARE, mage.cards.b.BurningSunsAvatar.class)); cards.add(new SetCardInfo("Call to the Feast", 219, Rarity.UNCOMMON, mage.cards.c.CallToTheFeast.class)); cards.add(new SetCardInfo("Captain Lannery Storm", 136, Rarity.RARE, mage.cards.c.CaptainLanneryStorm.class)); @@ -113,6 +114,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); cards.add(new SetCardInfo("Spires of Orazca", 249, Rarity.RARE, mage.cards.s.SpiresOfOrazca.class)); + cards.add(new SetCardInfo("Spell Pierce", 81, Rarity.RARE, mage.cards.s.SpellPierce.class)); cards.add(new SetCardInfo("Star of Extinction", 161, Rarity.MYTHIC, mage.cards.s.StarOfExtinction.class)); cards.add(new SetCardInfo("Stone Quarry", 289, Rarity.COMMON, mage.cards.s.StoneQuarry.class)); cards.add(new SetCardInfo("Storm Fleet Aerialist", 63, Rarity.UNCOMMON, mage.cards.s.StormFleetAerialist.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index f7f1901c8e..870dd8a5d2 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32331,6 +32331,7 @@ Cinder Barrens|Hour of Devastation|209|C||Land|||Cinder Barrens enters the battl Ashes of the Abhorrent|Ixalan|2|R|{1}{W}|Enchantment|||Players can't cast spells from graveyards or activate abilities from graveyards.$Whenever a creature dies, you gain 1 life.| Bellowing Aegisaur|Ixalan|4|U|{5}{W}|Creature - Dinosaur|3|5|Enrage - Whenever Bellowing Aegisaur is dealt damage, put a +1/+1 counter on each other creature you control.| Bishop of Rebirth|Ixalan|5|R|Creature - Vampire Cleric|3|4|Vigilance$Whenever Bishop of Rebirth attacks, you may return target creature card with converted mana cost 3 or less from your graveyard to the battlefield.| +Duskborne Skymarcher|Ixalan|9|U|{W}|Creature - Vampire Cleric|1|1|Flying${W}, {T}: Target attacking vampire gets +1/+1 until end of turn.| Goring Ceratops|Ixalan|13|R|Creature - Dinosaur|3|3|Double strike$Whenever Goring Ceratops attacks, other creatures you control gain double strike until end of turn.| Ixalan's Binding|Ixalan|17|U|{3}{W}|Enchantment|||When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield.$Your opponents can't cast spells with the same name as the exiled card.| Kinjalli's Sunwing|Ixalan|19|R|{2}{W}|Creature - Dinosaur|2|3|Flying$Creatures your opponents control enter the battlefield tapped.| @@ -32357,6 +32358,7 @@ Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| From 7ad5b7efad27aaef9da31965420960cbe027f383 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 11:25:54 -0400 Subject: [PATCH 088/100] small fix --- Utils/mtg-cards-data.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 870dd8a5d2..275a951ed1 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32357,7 +32357,7 @@ Overflowing Insight|Ixalan|64|M|{4}{U}{U}{U}|Sorcery|||Target player draws seven Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| -Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| From 0656f97d7c6e7cf07c3d45add1f53787f71311ad Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 11:36:07 -0400 Subject: [PATCH 089/100] Merge branch 'master' of https://github.com/magefree/mage into magefree-master # Conflicts: # Utils/mtg-cards-data.txt --- .../cards/{m => b}/BelligerentBrontodon.java | 11 +- Mage.Sets/src/mage/cards/c/CoalitionFlag.java | 12 +- .../src/mage/cards/c/CrimsonHonorGuard.java | 2 +- .../cards/{t => d}/DuskLegionDreadnought.java | 5 +- .../src/mage/cards/n/NimDeathmantle.java | 12 +- Mage.Sets/src/mage/cards/o/OniPossession.java | 21 +- .../mage/cards/p/PriestOfTheWakeningSun.java | 140 ++++ .../src/mage/cards/s/SanguineSacrament.java | 81 +++ .../src/mage/cards/s/SirenStormtamer.java | 183 +++++ .../src/mage/cards/s/SunbirdsInvocation.java | 165 +++++ Mage.Sets/src/mage/sets/Ixalan.java | 8 +- .../SetCardSubtypeAttachedEffect.java | 20 +- .../src/main/java/mage/constants/SubType.java | 631 +++++++++--------- Mage/src/main/java/mage/util/SubTypeList.java | 22 +- 14 files changed, 958 insertions(+), 355 deletions(-) rename Mage.Sets/src/mage/cards/{m => b}/BelligerentBrontodon.java (94%) rename Mage.Sets/src/mage/cards/{t => d}/DuskLegionDreadnought.java (99%) create mode 100644 Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java create mode 100644 Mage.Sets/src/mage/cards/s/SanguineSacrament.java create mode 100644 Mage.Sets/src/mage/cards/s/SirenStormtamer.java create mode 100644 Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java diff --git a/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java similarity index 94% rename from Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java rename to Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java index 21527d441b..81647dab15 100644 --- a/Mage.Sets/src/mage/cards/m/BelligerentBrontodon.java +++ b/Mage.Sets/src/mage/cards/b/BelligerentBrontodon.java @@ -25,22 +25,17 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.cards.m; +package mage.cards.b; import java.util.UUID; + import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.SubLayer; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; diff --git a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java index e96f8e13bc..811512b53e 100644 --- a/Mage.Sets/src/mage/cards/c/CoalitionFlag.java +++ b/Mage.Sets/src/mage/cards/c/CoalitionFlag.java @@ -28,6 +28,7 @@ package mage.cards.c; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -36,7 +37,12 @@ import mage.abilities.effects.common.ruleModifying.TargetsHaveToTargetPermanentI import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -50,7 +56,7 @@ public class CoalitionFlag extends CardImpl { public CoalitionFlag(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature you control TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -60,7 +66,7 @@ public class CoalitionFlag extends CardImpl { this.addAbility(ability); // Enchanted creature is a Flagbearer. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.FLAGBEARER, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.FLAGBEARER))); // While choosing targets as part of casting a spell or activating an ability, your opponents must choose at least one Flagbearer on the battlefield if able. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TargetsHaveToTargetPermanentIfAbleEffect(new FilterPermanent(SubType.FLAGBEARER, "one Flagbearer")))); diff --git a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java index 137ec3a036..64938d9c4a 100644 --- a/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java +++ b/Mage.Sets/src/mage/cards/c/CrimsonHonorGuard.java @@ -97,7 +97,7 @@ class CrimsonHonorGuardEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(game.getActivePlayerId()); if (player != null) { - int numCommanders = game.getBattlefield().getActivePermanents(filter, player.getId(), game).size(); + int numCommanders = game.getBattlefield().getAllActivePermanents(filter, player.getId(), game).size(); if (numCommanders == 0) { player.damage(4, source.getSourceId(), game, false, true); return true; diff --git a/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java similarity index 99% rename from Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java rename to Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java index 3717aef2af..8af6045cd3 100644 --- a/Mage.Sets/src/mage/cards/t/DuskLegionDreadnought.java +++ b/Mage.Sets/src/mage/cards/d/DuskLegionDreadnought.java @@ -25,12 +25,13 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ -package mage.cards.t; +package mage.cards.d; import java.util.UUID; + import mage.MageInt; -import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.CrewAbility; +import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; diff --git a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java index add8f8fe35..968ba66159 100644 --- a/Mage.Sets/src/mage/cards/n/NimDeathmantle.java +++ b/Mage.Sets/src/mage/cards/n/NimDeathmantle.java @@ -28,6 +28,7 @@ package mage.cards.n; import java.util.UUID; + import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; @@ -44,7 +45,12 @@ import mage.abilities.keyword.IntimidateAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -62,7 +68,7 @@ public class NimDeathmantle extends CardImpl { public NimDeathmantle(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); - this.subtype.add("Equipment"); + this.subtype.add(SubType.EQUIPMENT); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4))); @@ -70,7 +76,7 @@ public class NimDeathmantle extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(SubType.ZOMBIE, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.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. this.addAbility(new NimDeathmantleTriggeredAbility()); diff --git a/Mage.Sets/src/mage/cards/o/OniPossession.java b/Mage.Sets/src/mage/cards/o/OniPossession.java index c68e5dab47..03473e8a04 100644 --- a/Mage.Sets/src/mage/cards/o/OniPossession.java +++ b/Mage.Sets/src/mage/cards/o/OniPossession.java @@ -27,9 +27,8 @@ */ package mage.cards.o; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; + import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -42,12 +41,7 @@ import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.AttachmentType; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.common.FilterControlledCreaturePermanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -58,16 +52,9 @@ import mage.target.common.TargetCreaturePermanent; */ public class OniPossession extends CardImpl { - private static final List setSubtypes = new ArrayList<>(); - - static { - setSubtypes.add("Demon"); - setSubtypes.add("Spirit"); - } - public OniPossession(UUID ownerId, CardSetInfo setInfo) { super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); - this.subtype.add("Aura"); + this.subtype.add(SubType.AURA); // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); @@ -84,7 +71,7 @@ public class OniPossession extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), AttachmentType.AURA))); // Enchanted creature is a Demon Spirit. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(setSubtypes, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA, SubType.DEMON, SubType.SPIRIT))); } public OniPossession(final OniPossession card) { diff --git a/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java new file mode 100644 index 0000000000..ee8ef721a6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PriestOfTheWakeningSun.java @@ -0,0 +1,140 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author spjspj + */ +public class PriestOfTheWakeningSun extends CardImpl { + + private static final FilterCard filter = new FilterCard("a Dinosaur card"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + public PriestOfTheWakeningSun(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, you may reveal a Dinosaur card from your hand. If you do, you gain 2 life. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new PriestOfTheWakeningSunEffect(), TargetController.YOU, true); + this.addAbility(ability); + + // {3}{W}{W}, Sacrifice Priest of the Wakening Sun: Search your library for a Dinosaur card, reveal it, put it into your hand, then shuffle your library. + TargetCardInLibrary target = new TargetCardInLibrary(0, 1, filter); + Ability ability2 = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SearchLibraryPutInHandEffect(new TargetCardInLibrary(target), true, true), new ManaCostsImpl("{3}{W}{W}")); + ability2.addCost(new SacrificeSourceCost()); + this.addAbility(ability2); + } + + public PriestOfTheWakeningSun(final PriestOfTheWakeningSun card) { + super(card); + } + + @Override + public PriestOfTheWakeningSun copy() { + return new PriestOfTheWakeningSun(this); + } +} + +class PriestOfTheWakeningSunEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("a Dinosaur card to reveal"); + + static { + filter.add(new SubtypePredicate(SubType.DINOSAUR)); + } + + PriestOfTheWakeningSunEffect() { + super(Outcome.Benefit); + this.staticText = "reveal a Dinosaur card from your hand. If you do, you gain 2 life"; + } + + PriestOfTheWakeningSunEffect(final PriestOfTheWakeningSunEffect effect) { + super(effect); + } + + @Override + public PriestOfTheWakeningSunEffect copy() { + return new PriestOfTheWakeningSunEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + + if (controller != null && sourceObject != null) { + if (controller.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) { + if (controller.chooseUse(outcome, "Reveal a Dinosaur card?", source, game)) { + TargetCardInHand target = new TargetCardInHand(0, 1, filter); + if (controller.chooseTarget(outcome, target, source, game) && !target.getTargets().isEmpty()) { + Cards cards = new CardsImpl(); + cards.addAll(target.getTargets()); + controller.revealCards(sourceObject.getIdName(), cards, game); + controller.gainLife(2, game); + return true; + } + } + } + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SanguineSacrament.java b/Mage.Sets/src/mage/cards/s/SanguineSacrament.java new file mode 100644 index 0000000000..ccf88fce75 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SanguineSacrament.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.s; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.ReturnToLibrarySpellEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.game.Game; + +/** + * + * @author spjspj + */ +public class SanguineSacrament extends CardImpl { + + public SanguineSacrament(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}{W}"); + + // You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library. + this.getSpellAbility().addEffect(new GainLifeEffect(new SanguineSacramentValue())); + this.getSpellAbility().addEffect(new ReturnToLibrarySpellEffect(false)); + } + + public SanguineSacrament(final SanguineSacrament card) { + super(card); + } + + @Override + public SanguineSacrament copy() { + return new SanguineSacrament(this); + } +} + +class SanguineSacramentValue extends ManacostVariableValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + return super.calculate(game, sourceAbility, effect) * 2; + } + + @Override + public SanguineSacramentValue copy() { + return new SanguineSacramentValue(); + } + + @Override + public String toString() { + return "twice X"; + } +} diff --git a/Mage.Sets/src/mage/cards/s/SirenStormtamer.java b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java new file mode 100644 index 0000000000..10f6b519fe --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SirenStormtamer.java @@ -0,0 +1,183 @@ +/* + * 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.s; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CounterTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.game.stack.StackAbility; +import mage.game.stack.StackObject; +import mage.target.Target; +import mage.target.TargetObject; +import mage.target.Targets; + +/** + * + * @author spjspj + */ +public class SirenStormtamer extends CardImpl { + + public SirenStormtamer(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}"); + + this.subtype.add("Siren"); + this.subtype.add("Pirate"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CounterTargetEffect(), new ManaCostsImpl("{U}")); + ability.addTarget(new SirenStormtamerTargetObject()); + ability.addCost(new SacrificeSourceCost()); + + this.addAbility(ability); + } + + public SirenStormtamer(final SirenStormtamer card) { + super(card); + } + + @Override + public SirenStormtamer copy() { + return new SirenStormtamer(this); + } +} + +class SirenStormtamerTargetObject extends TargetObject { + + public SirenStormtamerTargetObject() { + this.minNumberOfTargets = 1; + this.maxNumberOfTargets = 1; + this.zone = Zone.STACK; + this.targetName = "spell or ability that targets you or a creature you control"; + } + + public SirenStormtamerTargetObject(final SirenStormtamerTargetObject target) { + super(target); + } + + @Override + public boolean canTarget(UUID id, Ability source, Game game) { + StackObject stackObject = game.getStack().getStackObject(id); + return (stackObject instanceof Spell) || (stackObject instanceof StackAbility); + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + return canChoose(sourceControllerId, game); + } + + @Override + public boolean canChoose(UUID sourceControllerId, Game game) { + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + return true; + } + + if (sourceControllerId.equals(targetId)) { + return true; + } + + } + } + } + } + } + return false; + } + + @Override + public Set possibleTargets(UUID sourceId, UUID sourceControllerId, + Game game) { + return possibleTargets(sourceControllerId, game); + } + + @Override + public Set possibleTargets(UUID sourceControllerId, Game game) { + Set possibleTargets = new HashSet<>(); + for (StackObject stackObject : game.getStack()) { + if ((stackObject instanceof Spell) || (stackObject instanceof StackAbility)) { + Targets objectTargets = stackObject.getStackAbility().getTargets(); + if (!objectTargets.isEmpty()) { + for (Target target : objectTargets) { + for (UUID targetId : target.getTargets()) { + Permanent targetedPermanent = game.getPermanentOrLKIBattlefield(targetId); + if (targetedPermanent != null + && targetedPermanent.getControllerId().equals(sourceControllerId) + && targetedPermanent.isCreature()) { + possibleTargets.add(stackObject.getId()); + } + + if (sourceControllerId.equals(targetId)) { + possibleTargets.add(stackObject.getId()); + } + } + } + } + } + } + return possibleTargets; + } + + @Override + public SirenStormtamerTargetObject copy() { + return new SirenStormtamerTargetObject(this); + } + + @Override + public Filter getFilter() { + throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } +} diff --git a/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java new file mode 100644 index 0000000000..37f66ca4e6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunbirdsInvocation.java @@ -0,0 +1,165 @@ +/* + * 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.s; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.ComparisonType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.TargetCard; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author spjspj + */ +public class SunbirdsInvocation extends CardImpl { + + public SunbirdsInvocation(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}"); + + // Whenever you cast a spell from your hand, reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order. + this.addAbility(new SunbirdsInvocationTriggeredAbility()); + } + + public SunbirdsInvocation(final SunbirdsInvocation card) { + super(card); + } + + @Override + public SunbirdsInvocation copy() { + return new SunbirdsInvocation(this); + } +} + +class SunbirdsInvocationTriggeredAbility extends SpellCastControllerTriggeredAbility { + + public SunbirdsInvocationTriggeredAbility() { + super(new SunbirdsInvocationEffect(), false); + } + + public SunbirdsInvocationTriggeredAbility(SunbirdsInvocationTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getPlayerId().equals(this.getControllerId())) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getFromZone() == Zone.HAND) { + if (spell.getCard() != null) { + for (Effect effect : getEffects()) { + effect.setTargetPointer(new FixedTarget(spell.getId())); + } + return true; + } + } + } + return false; + } + + @Override + public SunbirdsInvocationTriggeredAbility copy() { + return new SunbirdsInvocationTriggeredAbility(this); + } +} + +class SunbirdsInvocationEffect extends OneShotEffect { + + public SunbirdsInvocationEffect() { + super(Outcome.PutCardInPlay); + staticText = "Reveal the top X cards of your library, where X is that spell's converted mana cost. You may cast a card revealed this way with converted mana cost X or less without paying its mana cost. Put the rest on the bottom of your library in a random order"; + } + + public SunbirdsInvocationEffect(final SunbirdsInvocationEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller == null || sourceObject == null) { + return false; + } + Cards cards = new CardsImpl(); + int xValue = game.getStack().getSpell(getTargetPointer().getFirst(game, source)).getConvertedManaCost(); + cards.addAll(controller.getLibrary().getTopCards(game, xValue)); + if (!cards.isEmpty()) { + controller.revealCards(sourceObject.getIdName(), cards, game); + + FilterCard filter = new FilterNonlandCard("card revealed this way with converted mana cost " + xValue + " or less"); + filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, xValue + 1)); + TargetCard target = new TargetCard(1, Zone.LIBRARY, filter); + + if (controller.chooseTarget(Outcome.PlayForFree, cards, target, source, game)) { + Card card = cards.get(target.getFirstTarget(), game); + if (card != null) { + if (controller.chooseUse(outcome, "Do you wish to cast " + card.getName(), source, game)) { + Card copy = game.copyCard(card, source, source.getControllerId()); + controller.cast(copy.getSpellAbility(), game, true); + } + return true; + } + } + } + + while (!cards.isEmpty()) { + Card card = cards.getRandom(game); + if (card != null) { + cards.remove(card); + card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); + } + } + + return true; + } + + @Override + public SunbirdsInvocationEffect copy() { + return new SunbirdsInvocationEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 397cd0dc15..4435fa2426 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -35,7 +35,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); - cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.m.BelligerentBrontodon.class)); + cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); cards.add(new SetCardInfo("Bellowing Aegisaur", 4, Rarity.UNCOMMON, mage.cards.b.BellowingAegisaur.class)); cards.add(new SetCardInfo("Bloodcrazed Paladin", 93, Rarity.RARE, mage.cards.b.BloodcrazedPaladin.class)); cards.add(new SetCardInfo("Boneyard Parley", 94, Rarity.MYTHIC, mage.cards.b.BoneyardParley.class)); @@ -60,7 +60,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Drover of the Mighty", 167, Rarity.UNCOMMON, mage.cards.d.DroverOfTheMighty.class)); cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); - cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.t.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); @@ -92,6 +92,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Overflowing Insight", 64, Rarity.MYTHIC, mage.cards.o.OverflowingInsight.class)); cards.add(new SetCardInfo("Pillar of Origins", 241, Rarity.UNCOMMON, mage.cards.p.PillarOfOrigins.class)); cards.add(new SetCardInfo("Pirate's Cutlass", 242, Rarity.COMMON, mage.cards.p.PiratesCutlass.class)); + cards.add(new SetCardInfo("Priest of the Wakening Sun", 27, Rarity.RARE, mage.cards.p.PriestOfTheWakeningSun.class)); cards.add(new SetCardInfo("Primal Amulet", 243, Rarity.RARE, mage.cards.p.PrimalAmulet.class)); cards.add(new SetCardInfo("Primal Wellspring", 243, Rarity.RARE, mage.cards.p.PrimalWellspring.class)); cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); @@ -105,11 +106,13 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Rowdy Crew", 159, Rarity.MYTHIC, mage.cards.r.RowdyCrew.class)); cards.add(new SetCardInfo("Ruin Raider", 118, Rarity.RARE, mage.cards.r.RuinRaider.class)); cards.add(new SetCardInfo("Sanctum Seeker", 120, Rarity.RARE, mage.cards.s.SanctumSeeker.class)); + cards.add(new SetCardInfo("Sanguine Sacrament", 33, Rarity.RARE, mage.cards.s.SanguineSacrament.class)); cards.add(new SetCardInfo("Savage Stomp", 205, Rarity.UNCOMMON, mage.cards.s.SavageStomp.class)); cards.add(new SetCardInfo("Sentinel Totem", 245, Rarity.UNCOMMON, mage.cards.s.SentinelTotem.class)); cards.add(new SetCardInfo("Settle the Wreckage", 34, Rarity.RARE, mage.cards.s.SettleTheWreckage.class)); cards.add(new SetCardInfo("Shapers of Nature", 228, Rarity.UNCOMMON, mage.cards.s.ShapersOfNature.class)); cards.add(new SetCardInfo("Shapers' Sanctuary", 206, Rarity.RARE, mage.cards.s.ShapersSanctuary.class)); + cards.add(new SetCardInfo("Siren Stormtamer", 79, Rarity.UNCOMMON, mage.cards.s.SirenStormtamer.class)); cards.add(new SetCardInfo("Sleek Schooner", 247, Rarity.UNCOMMON, mage.cards.s.SleekSchooner.class)); cards.add(new SetCardInfo("Slice in Twain", 207, Rarity.UNCOMMON, mage.cards.s.SliceinTwain.class)); cards.add(new SetCardInfo("Sorcerous Spyglass", 248, Rarity.RARE, mage.cards.s.SorcerousSpyglass.class)); @@ -121,6 +124,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Storm Fleet Arsonist", 162, Rarity.UNCOMMON, mage.cards.s.StormFleetArsonist.class)); cards.add(new SetCardInfo("Sun-Blessed Mount", 288, Rarity.RARE, mage.cards.s.SunBlessedMount.class)); cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); + cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java index fafe47f266..f68d71d251 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/SetCardSubtypeAttachedEffect.java @@ -29,13 +29,16 @@ package mage.abilities.effects.common.continuous; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.*; +import mage.constants.AttachmentType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.SubTypeList; -import java.util.List; - /** * @author nantuko */ @@ -44,7 +47,14 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { private SubTypeList setSubtypes = new SubTypeList(); private final AttachmentType attachmentType; - public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { + public SetCardSubtypeAttachedEffect(Duration duration, AttachmentType attachmentType, SubType... setSubtype) { + super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + this.setSubtypes.add(setSubtype); + this.attachmentType = attachmentType; + this.setText(); + } + + /*public SetCardSubtypeAttachedEffect(SubType setSubtype, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; @@ -56,7 +66,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { this.setSubtypes.addAll(setSubtypes); this.attachmentType = attachmentType; setText(); - } + }*/ public SetCardSubtypeAttachedEffect(final SetCardSubtypeAttachedEffect effect) { super(effect); diff --git a/Mage/src/main/java/mage/constants/SubType.java b/Mage/src/main/java/mage/constants/SubType.java index cd6edde011..9c597260dc 100644 --- a/Mage/src/main/java/mage/constants/SubType.java +++ b/Mage/src/main/java/mage/constants/SubType.java @@ -1,396 +1,410 @@ package mage.constants; -import mage.util.SubTypeList; - import java.util.Arrays; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; +import mage.util.SubTypeList; + public enum SubType { //205.3k Instants and sorceries share their lists of subtypes; these subtypes are called spell types. - ARCANE("Arcane", SubTypeSet.SpellType, false), - TRAP("Trap", SubTypeSet.SpellType, false), + ARCANE("Arcane", SubTypeSet.SpellType), + TRAP("Trap", SubTypeSet.SpellType), + // 205.3i: Lands have their own unique set of subtypes; these subtypes are called land types. // Of that list, Forest, Island, Mountain, Plains, and Swamp are the basic land types. - FOREST("Forest", SubTypeSet.BasicLandType, false), - ISLAND("Island", SubTypeSet.BasicLandType, false), - MOUNTAIN("Mountain", SubTypeSet.BasicLandType, false), - PLAINS("Plains", SubTypeSet.BasicLandType, false), - SWAMP("Swamp", SubTypeSet.BasicLandType, false), - DESERT("Desert", SubTypeSet.NonBasicLandType, false), - GATE("Gate", SubTypeSet.NonBasicLandType, false), - LAIR("Lair", SubTypeSet.NonBasicLandType, false), - LOCUS("Locus", SubTypeSet.NonBasicLandType, false), - URZAS("Urza's", SubTypeSet.NonBasicLandType, false), - MINE("Mine", SubTypeSet.NonBasicLandType, false), - POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType, false), - TOWER("Tower", SubTypeSet.NonBasicLandType, false), + FOREST("Forest", SubTypeSet.BasicLandType), + ISLAND("Island", SubTypeSet.BasicLandType), + MOUNTAIN("Mountain", SubTypeSet.BasicLandType), + PLAINS("Plains", SubTypeSet.BasicLandType), + SWAMP("Swamp", SubTypeSet.BasicLandType), + DESERT("Desert", SubTypeSet.NonBasicLandType), + GATE("Gate", SubTypeSet.NonBasicLandType), + LAIR("Lair", SubTypeSet.NonBasicLandType), + LOCUS("Locus", SubTypeSet.NonBasicLandType), + URZAS("Urza's", SubTypeSet.NonBasicLandType), + MINE("Mine", SubTypeSet.NonBasicLandType), + POWER_PLANT("Power-Plant", SubTypeSet.NonBasicLandType), + TOWER("Tower", SubTypeSet.NonBasicLandType), + // 205.3h Enchantments have their own unique set of subtypes; these subtypes are called enchantment types. - AURA("Aura", SubTypeSet.EnchantmentType, false), - CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType, false), - CURSE("Curse", SubTypeSet.EnchantmentType, false), - SHRINE("Shrine", SubTypeSet.EnchantmentType, false), + AURA("Aura", SubTypeSet.EnchantmentType), + CARTOUCHE("Cartouche", SubTypeSet.EnchantmentType), + CURSE("Curse", SubTypeSet.EnchantmentType), + SHRINE("Shrine", SubTypeSet.EnchantmentType), + // 205.3g: Artifacts have their own unique set of subtypes; these subtypes are called artifact types. - CLUE("Clue", SubTypeSet.ArtifactType, false), - CONTRAPTION("Contraption", SubTypeSet.ArtifactType, false), - EQUIPMENT("Equipment", SubTypeSet.ArtifactType, false), - FORTIFICATION("Fortification", SubTypeSet.ArtifactType, false), - TREASURE("Treasure", SubTypeSet.ArtifactType, false), - VEHICLE("Vehicle", SubTypeSet.ArtifactType, false), + CLUE("Clue", SubTypeSet.ArtifactType), + CONTRAPTION("Contraption", SubTypeSet.ArtifactType), + EQUIPMENT("Equipment", SubTypeSet.ArtifactType), + FORTIFICATION("Fortification", SubTypeSet.ArtifactType), + TREASURE("Treasure", SubTypeSet.ArtifactType), + VEHICLE("Vehicle", SubTypeSet.ArtifactType), + // 205.3m : Creatures and tribals share their lists of subtypes; these subtypes are called creature types. // A - ADVISOR("Advisor", SubTypeSet.CreatureType, false), - AETHERBORN("Aetherborn", SubTypeSet.CreatureType, false), - ALLY("Ally", SubTypeSet.CreatureType, false), - ANGEL("Angel", SubTypeSet.CreatureType, false), - ANTELOPE("Antelope", SubTypeSet.CreatureType, false), + ADVISOR("Advisor", SubTypeSet.CreatureType), + AETHERBORN("Aetherborn", SubTypeSet.CreatureType), + ALLY("Ally", SubTypeSet.CreatureType), + ANGEL("Angel", SubTypeSet.CreatureType), + ANTELOPE("Antelope", SubTypeSet.CreatureType), AQUALISH("Aqualish", SubTypeSet.CreatureType, true), // Star Wars - APE("Ape", SubTypeSet.CreatureType, false), + APE("Ape", SubTypeSet.CreatureType), ARCONA("Arcona", SubTypeSet.CreatureType, true), - ARCHER("Archer", SubTypeSet.CreatureType, false), - ARCHON("Archon", SubTypeSet.CreatureType, false), - ARTIFICER("Artificer", SubTypeSet.CreatureType, false), + ARCHER("Archer", SubTypeSet.CreatureType), + ARCHON("Archon", SubTypeSet.CreatureType), + ARTIFICER("Artificer", SubTypeSet.CreatureType), ARTIFICIER("Artificier", SubTypeSet.CreatureType, true), - ASSASSIN("Assassin", SubTypeSet.CreatureType, false), - ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType, false), - ATOG("Atog", SubTypeSet.CreatureType, false), + ASSASSIN("Assassin", SubTypeSet.CreatureType), + ASSEMBLY_WORKER("Assembly-Worker", SubTypeSet.CreatureType), + ATOG("Atog", SubTypeSet.CreatureType), ATAT("AT-AT", SubTypeSet.CreatureType, true), - AUROCHS("Aurochs", SubTypeSet.CreatureType, false), + AUROCHS("Aurochs", SubTypeSet.CreatureType), AUTOBOT("Autobot", SubTypeSet.CreatureType, true), // H17, Grimlock - AVATAR("Avatar", SubTypeSet.CreatureType, false), + AVATAR("Avatar", SubTypeSet.CreatureType), // B - BADGER("Badger", SubTypeSet.CreatureType, false), - BARBARIAN("Barbarian", SubTypeSet.CreatureType, false), - BASILISK("Basilisk", SubTypeSet.CreatureType, false), - BAT("Bat", SubTypeSet.CreatureType, false), - BEAR("Bear", SubTypeSet.CreatureType, false), - BEAST("Beast", SubTypeSet.CreatureType, false), - BEEBLE("Beeble", SubTypeSet.CreatureType, false), - BERSERKER("Berserker", SubTypeSet.CreatureType, false), - BIRD("Bird", SubTypeSet.CreatureType, false), + BADGER("Badger", SubTypeSet.CreatureType), + BARBARIAN("Barbarian", SubTypeSet.CreatureType), + BASILISK("Basilisk", SubTypeSet.CreatureType), + BAT("Bat", SubTypeSet.CreatureType), + BEAR("Bear", SubTypeSet.CreatureType), + BEAST("Beast", SubTypeSet.CreatureType), + BEEBLE("Beeble", SubTypeSet.CreatureType), + BERSERKER("Berserker", SubTypeSet.CreatureType), + BIRD("Bird", SubTypeSet.CreatureType), BITH("Bith", SubTypeSet.CreatureType, true), // Star Wars - BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType, false), - BOAR("Boar", SubTypeSet.CreatureType, false), - BRINGER("Bringer", SubTypeSet.CreatureType, false), - BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType, false), + BLINKMOTH("Blinkmoth", SubTypeSet.CreatureType), + BOAR("Boar", SubTypeSet.CreatureType), + BRINGER("Bringer", SubTypeSet.CreatureType), + BRUSHWAGG("Brushwagg", SubTypeSet.CreatureType), // C CALAMARI("Calamari", SubTypeSet.CreatureType, true), // Star Wars - CAMARID("Camarid", SubTypeSet.CreatureType, false), - CAMEL("Camel", SubTypeSet.CreatureType, false), - CARIBOU("Caribou", SubTypeSet.CreatureType, false), - CARRIER("Carrier", SubTypeSet.CreatureType, false), - CAT("Cat", SubTypeSet.CreatureType, false), - CENTAUR("Centaur", SubTypeSet.CreatureType, false), + CAMARID("Camarid", SubTypeSet.CreatureType), + CAMEL("Camel", SubTypeSet.CreatureType), + CARIBOU("Caribou", SubTypeSet.CreatureType), + CARRIER("Carrier", SubTypeSet.CreatureType), + CAT("Cat", SubTypeSet.CreatureType), + CENTAUR("Centaur", SubTypeSet.CreatureType), CEREAN("Cerean", SubTypeSet.CreatureType, true), // Star Wars - CEPHALID("Cephalid", SubTypeSet.CreatureType, false), - CHIMERA("Chimera", SubTypeSet.CreatureType, false), + CEPHALID("Cephalid", SubTypeSet.CreatureType), + CHIMERA("Chimera", SubTypeSet.CreatureType), CHISS("Chiss", SubTypeSet.CreatureType, true), - CITIZEN("Citizen", SubTypeSet.CreatureType, false), - CLERIC("Cleric", SubTypeSet.CreatureType, false), - COCKATRICE("Cockatrice", SubTypeSet.CreatureType, false), - CONSTRUCT("Construct", SubTypeSet.CreatureType, false), - COWARD("Coward", SubTypeSet.CreatureType, false), - CRAB("Crab", SubTypeSet.CreatureType, false), - CROCODILE("Crocodile", SubTypeSet.CreatureType, false), + CITIZEN("Citizen", SubTypeSet.CreatureType), + CLERIC("Cleric", SubTypeSet.CreatureType), + COCKATRICE("Cockatrice", SubTypeSet.CreatureType), + CONSTRUCT("Construct", SubTypeSet.CreatureType), + COWARD("Coward", SubTypeSet.CreatureType), + CRAB("Crab", SubTypeSet.CreatureType), + CROCODILE("Crocodile", SubTypeSet.CreatureType), CYBORG("Cyborg", SubTypeSet.CreatureType, true), // Star Wars - CYCLOPS("Cyclops", SubTypeSet.CreatureType, false), + CYCLOPS("Cyclops", SubTypeSet.CreatureType), // D DATHOMIRIAN("Dathomirian", SubTypeSet.CreatureType, true), // Star Wars - DAUTHI("Dauthi", SubTypeSet.CreatureType, false), - DEMON("Demon", SubTypeSet.CreatureType, false), - DESERTER("Deserter", SubTypeSet.CreatureType, false), - DEVIL("Devil", SubTypeSet.CreatureType, false), - DINOSAUR("Dinosaur", SubTypeSet.CreatureType, false), // With Ixalan now being spoiled, need this to be selectable - DJINN("Djinn", SubTypeSet.CreatureType, false), - DRAGON("Dragon", SubTypeSet.CreatureType, false), - DRAKE("Drake", SubTypeSet.CreatureType, false), - DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType, false), - DRONE("Drone", SubTypeSet.CreatureType, false), - DRUID("Druid", SubTypeSet.CreatureType, false), + DAUTHI("Dauthi", SubTypeSet.CreatureType), + DEMON("Demon", SubTypeSet.CreatureType), + DESERTER("Deserter", SubTypeSet.CreatureType), + DEVIL("Devil", SubTypeSet.CreatureType), + DINOSAUR("Dinosaur", SubTypeSet.CreatureType), // With Ixalan now being spoiled, need this to be selectable + DJINN("Djinn", SubTypeSet.CreatureType), + DRAGON("Dragon", SubTypeSet.CreatureType), + DRAKE("Drake", SubTypeSet.CreatureType), + DREADNOUGHT("Dreadnought", SubTypeSet.CreatureType), + DRONE("Drone", SubTypeSet.CreatureType), + DRUID("Druid", SubTypeSet.CreatureType), DROID("Droid", SubTypeSet.CreatureType, true), // Star Wars - DRYAD("Dryad", SubTypeSet.CreatureType, false), - DWARF("Dwarf", SubTypeSet.CreatureType, false), + DRYAD("Dryad", SubTypeSet.CreatureType), + DWARF("Dwarf", SubTypeSet.CreatureType), // E - EFREET("Efreet", SubTypeSet.CreatureType, false), - ELDER("Elder", SubTypeSet.CreatureType, false), - ELDRAZI("Eldrazi", SubTypeSet.CreatureType, false), - ELEMENTAL("Elemental", SubTypeSet.CreatureType, false), - ELEPHANT("Elephant", SubTypeSet.CreatureType, false), - ELF("Elf", SubTypeSet.CreatureType, false), - ELK("Elk", SubTypeSet.CreatureType, false), - EYE("Eye", SubTypeSet.CreatureType, false), + EFREET("Efreet", SubTypeSet.CreatureType), + ELDER("Elder", SubTypeSet.CreatureType), + ELDRAZI("Eldrazi", SubTypeSet.CreatureType), + ELEMENTAL("Elemental", SubTypeSet.CreatureType), + ELEPHANT("Elephant", SubTypeSet.CreatureType), + ELF("Elf", SubTypeSet.CreatureType), + ELK("Elk", SubTypeSet.CreatureType), + EYE("Eye", SubTypeSet.CreatureType), EWOK("Ewok", SubTypeSet.CreatureType, true), // Star Wars // F - FAERIE("Faerie", SubTypeSet.CreatureType, false), - FERRET("Ferret", SubTypeSet.CreatureType, false), - FISH("Fish", SubTypeSet.CreatureType, false), - FLAGBEARER("Flagbearer", SubTypeSet.CreatureType, false), - FOX("Fox", SubTypeSet.CreatureType, false), - FROG("Frog", SubTypeSet.CreatureType, false), - FUNGUS("Fungus", SubTypeSet.CreatureType, false), + FAERIE("Faerie", SubTypeSet.CreatureType), + FERRET("Ferret", SubTypeSet.CreatureType), + FISH("Fish", SubTypeSet.CreatureType), + FLAGBEARER("Flagbearer", SubTypeSet.CreatureType), + FOX("Fox", SubTypeSet.CreatureType), + FROG("Frog", SubTypeSet.CreatureType), + FUNGUS("Fungus", SubTypeSet.CreatureType), // G GAMORREAN("Gamorrean", SubTypeSet.CreatureType, true), // Star Wars GAND("Gand", SubTypeSet.CreatureType, true), // Star Wars - GARGOYLE("Gargoyle", SubTypeSet.CreatureType, false), - GERM("Germ", SubTypeSet.CreatureType, false), - GIANT("Giant", SubTypeSet.CreatureType, false), - GNOME("Gnome", SubTypeSet.CreatureType, false), - GOLEM("Golem", SubTypeSet.CreatureType, false), - GOAT("Goat", SubTypeSet.CreatureType, false), - GOBLIN("Goblin", SubTypeSet.CreatureType, false), - GOD("God", SubTypeSet.CreatureType, false), - GORGON("Gorgon", SubTypeSet.CreatureType, false), - GRAVEBORN("Graveborn", SubTypeSet.CreatureType, false), - GREMLIN("Gremlin", SubTypeSet.CreatureType, false), - GRIFFIN("Griffin", SubTypeSet.CreatureType, false), + GARGOYLE("Gargoyle", SubTypeSet.CreatureType), + GERM("Germ", SubTypeSet.CreatureType), + GIANT("Giant", SubTypeSet.CreatureType), + GNOME("Gnome", SubTypeSet.CreatureType), + GOLEM("Golem", SubTypeSet.CreatureType), + GOAT("Goat", SubTypeSet.CreatureType), + GOBLIN("Goblin", SubTypeSet.CreatureType), + GOD("God", SubTypeSet.CreatureType), + GORGON("Gorgon", SubTypeSet.CreatureType), + GRAVEBORN("Graveborn", SubTypeSet.CreatureType), + GREMLIN("Gremlin", SubTypeSet.CreatureType), + GRIFFIN("Griffin", SubTypeSet.CreatureType), GUNGAN("Gungan", SubTypeSet.CreatureType, true), // Star Wars // H - HAG("Hag", SubTypeSet.CreatureType, false), - HARPY("Harpy", SubTypeSet.CreatureType, false), - HELLION("Hellion", SubTypeSet.CreatureType, false), - HIPPO("Hippo", SubTypeSet.CreatureType, false), - HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType, false), - HOMARID("Homarid", SubTypeSet.CreatureType, false), - HOMUNCULUS("Homunculus", SubTypeSet.CreatureType, false), - HORROR("Horror", SubTypeSet.CreatureType, false), - HORSE("Horse", SubTypeSet.CreatureType, false), - HOUND("Hound", SubTypeSet.CreatureType, false), - HUMAN("Human", SubTypeSet.CreatureType, false), - HUNTER("Hunter", SubTypeSet.CreatureType, false), + HAG("Hag", SubTypeSet.CreatureType), + HARPY("Harpy", SubTypeSet.CreatureType), + HELLION("Hellion", SubTypeSet.CreatureType), + HIPPO("Hippo", SubTypeSet.CreatureType), + HIPPOGRIFF("Hippogriff", SubTypeSet.CreatureType), + HOMARID("Homarid", SubTypeSet.CreatureType), + HOMUNCULUS("Homunculus", SubTypeSet.CreatureType), + HORROR("Horror", SubTypeSet.CreatureType), + HORSE("Horse", SubTypeSet.CreatureType), + HOUND("Hound", SubTypeSet.CreatureType), + HUMAN("Human", SubTypeSet.CreatureType), + HUNTER("Hunter", SubTypeSet.CreatureType), HUTT("Hutt", SubTypeSet.CreatureType, true), // Star Wars - HYDRA("Hydra", SubTypeSet.CreatureType, false), - HYENA("Hyena", SubTypeSet.CreatureType, false), + HYDRA("Hydra", SubTypeSet.CreatureType), + HYENA("Hyena", SubTypeSet.CreatureType), // I - ILLUSION("Illusion", SubTypeSet.CreatureType, false), - IMP("Imp", SubTypeSet.CreatureType, false), - INCARNATION("Incarnation", SubTypeSet.CreatureType, false), - INSECT("Insect", SubTypeSet.CreatureType, false), + ILLUSION("Illusion", SubTypeSet.CreatureType), + IMP("Imp", SubTypeSet.CreatureType), + INCARNATION("Incarnation", SubTypeSet.CreatureType), + INSECT("Insect", SubTypeSet.CreatureType), ITHORIAN("Ithorian", SubTypeSet.CreatureType, true), // Star Wars // J - JACKAL("Jackal", SubTypeSet.CreatureType, false), + JACKAL("Jackal", SubTypeSet.CreatureType), JAWA("Jawa", SubTypeSet.CreatureType, true), JEDI("Jedi", SubTypeSet.CreatureType, true), // Star Wars - JELLYFISH("Jellyfish", SubTypeSet.CreatureType, false), - JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType, false), + JELLYFISH("Jellyfish", SubTypeSet.CreatureType), + JUGGERNAUT("Juggernaut", SubTypeSet.CreatureType), // K KALEESH("Kaleesh", SubTypeSet.CreatureType, true), // Star Wars - KAVU("Kavu", SubTypeSet.CreatureType, false), + KAVU("Kavu", SubTypeSet.CreatureType), KELDOR("KelDor", SubTypeSet.CreatureType, true), - KIRIN("Kirin", SubTypeSet.CreatureType, false), - KITHKIN("Kithkin", SubTypeSet.CreatureType, false), - KNIGHT("Knight", SubTypeSet.CreatureType, false), - KOBOLD("Kobold", SubTypeSet.CreatureType, false), + KIRIN("Kirin", SubTypeSet.CreatureType), + KITHKIN("Kithkin", SubTypeSet.CreatureType), + KNIGHT("Knight", SubTypeSet.CreatureType), + KOBOLD("Kobold", SubTypeSet.CreatureType), KOORIVAR("Koorivar", SubTypeSet.CreatureType, true), - KOR("Kor", SubTypeSet.CreatureType, false), - KRAKEN("Kraken", SubTypeSet.CreatureType, false), + KOR("Kor", SubTypeSet.CreatureType), + KRAKEN("Kraken", SubTypeSet.CreatureType), // L - LAMIA("Lamia", SubTypeSet.CreatureType, false), - LAMMASU("Lammasu", SubTypeSet.CreatureType, false), - LEECH("Leech", SubTypeSet.CreatureType, false), - LEVIATHAN("Leviathan", SubTypeSet.CreatureType, false), - LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType, false), - LICID("Licid", SubTypeSet.CreatureType, false), - LIZARD("Lizard", SubTypeSet.CreatureType, false), + LAMIA("Lamia", SubTypeSet.CreatureType), + LAMMASU("Lammasu", SubTypeSet.CreatureType), + LEECH("Leech", SubTypeSet.CreatureType), + LEVIATHAN("Leviathan", SubTypeSet.CreatureType), + LHURGOYF("Lhurgoyf", SubTypeSet.CreatureType), + LICID("Licid", SubTypeSet.CreatureType), + LIZARD("Lizard", SubTypeSet.CreatureType), // M MANTELLIAN("Mantellian", SubTypeSet.CreatureType, true), // Star Wars - MANTICORE("Manticore", SubTypeSet.CreatureType, false), - MASTICORE("Masticore", SubTypeSet.CreatureType, false), - MERCENARY("Mercenary", SubTypeSet.CreatureType, false), - MERFOLK("Merfolk", SubTypeSet.CreatureType, false), - METATHRAN("Metathran", SubTypeSet.CreatureType, false), - MINION("Minion", SubTypeSet.CreatureType, false), - MINOTAUR("Minotaur", SubTypeSet.CreatureType, false), + MANTICORE("Manticore", SubTypeSet.CreatureType), + MASTICORE("Masticore", SubTypeSet.CreatureType), + MERCENARY("Mercenary", SubTypeSet.CreatureType), + MERFOLK("Merfolk", SubTypeSet.CreatureType), + METATHRAN("Metathran", SubTypeSet.CreatureType), + MINION("Minion", SubTypeSet.CreatureType), + MINOTAUR("Minotaur", SubTypeSet.CreatureType), MIRIALAN("Mirialan", SubTypeSet.CreatureType, true), // Star Wars - MOLE("Mole", SubTypeSet.CreatureType, false), - MONGER("Monger", SubTypeSet.CreatureType, false), - MONGOOSE("Mongoose", SubTypeSet.CreatureType, false), - MONK("Monk", SubTypeSet.CreatureType, false), - MONKEY("Monkey", SubTypeSet.CreatureType, false), - MOONFOLK("Moonfolk", SubTypeSet.CreatureType, false), - MUTANT("Mutant", SubTypeSet.CreatureType, false), - MYR("Myr", SubTypeSet.CreatureType, false), - MYSTIC("Mystic", SubTypeSet.CreatureType, false), + MOLE("Mole", SubTypeSet.CreatureType), + MONGER("Monger", SubTypeSet.CreatureType), + MONGOOSE("Mongoose", SubTypeSet.CreatureType), + MONK("Monk", SubTypeSet.CreatureType), + MONKEY("Monkey", SubTypeSet.CreatureType), + MOONFOLK("Moonfolk", SubTypeSet.CreatureType), + MUTANT("Mutant", SubTypeSet.CreatureType), + MYR("Myr", SubTypeSet.CreatureType), + MYSTIC("Mystic", SubTypeSet.CreatureType), // N - NAGA("Naga", SubTypeSet.CreatureType, false), - NAUTILUS("Nautilus", SubTypeSet.CreatureType, false), + NAGA("Naga", SubTypeSet.CreatureType), + NAUTILUS("Nautilus", SubTypeSet.CreatureType), NAUTOLAN("Nautolan", SubTypeSet.CreatureType, true), // Star Wars NEIMOIDIAN("Neimoidian", SubTypeSet.CreatureType, true), // Star Wars - NEPHILIM("Nephilim", SubTypeSet.CreatureType, false), - NIGHTMARE("Nightmare", SubTypeSet.CreatureType, false), - NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType, false), - NINJA("Ninja", SubTypeSet.CreatureType, false), - NOGGLE("Noggle", SubTypeSet.CreatureType, false), - NOMAD("Nomad", SubTypeSet.CreatureType, false), - NYMPH("Nymph", SubTypeSet.CreatureType, false), + NEPHILIM("Nephilim", SubTypeSet.CreatureType), + NIGHTMARE("Nightmare", SubTypeSet.CreatureType), + NIGHTSTALKER("Nightstalker", SubTypeSet.CreatureType), + NINJA("Ninja", SubTypeSet.CreatureType), + NOGGLE("Noggle", SubTypeSet.CreatureType), + NOMAD("Nomad", SubTypeSet.CreatureType), + NYMPH("Nymph", SubTypeSet.CreatureType), // O - OCTOPUS("Octopus", SubTypeSet.CreatureType, false), - OGRE("Ogre", SubTypeSet.CreatureType, false), - OOZE("Ooze", SubTypeSet.CreatureType, false), - ORB("Orb", SubTypeSet.CreatureType, false), - ORC("Orc", SubTypeSet.CreatureType, false), - ORGG("Orgg", SubTypeSet.CreatureType, false), + OCTOPUS("Octopus", SubTypeSet.CreatureType), + OGRE("Ogre", SubTypeSet.CreatureType), + OOZE("Ooze", SubTypeSet.CreatureType), + ORB("Orb", SubTypeSet.CreatureType), + ORC("Orc", SubTypeSet.CreatureType), + ORGG("Orgg", SubTypeSet.CreatureType), ORTOLAN("Ortolan", SubTypeSet.CreatureType, true), - OUPHE("Ouphe", SubTypeSet.CreatureType, false), - OX("Ox", SubTypeSet.CreatureType, false), - OYSTER("Oyster", SubTypeSet.CreatureType, false), + OUPHE("Ouphe", SubTypeSet.CreatureType), + OX("Ox", SubTypeSet.CreatureType), + OYSTER("Oyster", SubTypeSet.CreatureType), // P - PEGASUS("Pegasus", SubTypeSet.CreatureType, false), - PENTAVITE("Pentavite", SubTypeSet.CreatureType, false), - PEST("Pest", SubTypeSet.CreatureType, false), - PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType, false), - PHOENIX("Phoenix", SubTypeSet.CreatureType, false), - PILOT("Pilot", SubTypeSet.CreatureType, false), - PINCHER("Pincher", SubTypeSet.CreatureType, false), - PIRATE("Pirate", SubTypeSet.CreatureType, false), - PLANT("Plant", SubTypeSet.CreatureType, false), - PRAETOR("Praetor", SubTypeSet.CreatureType, false), - PRISM("Prism", SubTypeSet.CreatureType, false), - PROCESSOR("Processor", SubTypeSet.CreatureType, false), + PEGASUS("Pegasus", SubTypeSet.CreatureType), + PENTAVITE("Pentavite", SubTypeSet.CreatureType), + PEST("Pest", SubTypeSet.CreatureType), + PHELDDAGRIF("Phelddagrif", SubTypeSet.CreatureType), + PHOENIX("Phoenix", SubTypeSet.CreatureType), + PILOT("Pilot", SubTypeSet.CreatureType), + PINCHER("Pincher", SubTypeSet.CreatureType), + PIRATE("Pirate", SubTypeSet.CreatureType), + PLANT("Plant", SubTypeSet.CreatureType), + PRAETOR("Praetor", SubTypeSet.CreatureType), + PRISM("Prism", SubTypeSet.CreatureType), + PROCESSOR("Processor", SubTypeSet.CreatureType), PUREBLOOD("Pureblood", SubTypeSet.CreatureType, true), // Q QUARREN("Quarren", SubTypeSet.CreatureType, true), // Star Wars // R - RABBIT("Rabbit", SubTypeSet.CreatureType, false), - RAT("Rat", SubTypeSet.CreatureType, false), - REBEL("Rebel", SubTypeSet.CreatureType, false), - REFLECTION("Reflection", SubTypeSet.CreatureType, false), - RHINO("Rhino", SubTypeSet.CreatureType, false), - RIGGER("Rigger", SubTypeSet.CreatureType, false), + RABBIT("Rabbit", SubTypeSet.CreatureType), + RAT("Rat", SubTypeSet.CreatureType), + REBEL("Rebel", SubTypeSet.CreatureType), + REFLECTION("Reflection", SubTypeSet.CreatureType), + RHINO("Rhino", SubTypeSet.CreatureType), + RIGGER("Rigger", SubTypeSet.CreatureType), RODIAN("Rodian", SubTypeSet.CreatureType, true), // Star Wars - ROGUE("Rogue", SubTypeSet.CreatureType, false), + ROGUE("Rogue", SubTypeSet.CreatureType), // S - SABLE("Sable", SubTypeSet.CreatureType, false), - SALAMANDER("Salamander", SubTypeSet.CreatureType, false), - SAMURAI("Samurai", SubTypeSet.CreatureType, false), - SAND("Sand", SubTypeSet.CreatureType, false), - SAPROLING("Saproling", SubTypeSet.CreatureType, false), - SATYR("Satyr", SubTypeSet.CreatureType, false), - SCARECROW("Scarecrow", SubTypeSet.CreatureType, false), - SCION("Scion", SubTypeSet.CreatureType, false), - SCORPION("Scorpion", SubTypeSet.CreatureType, false), - SCOUT("Scout", SubTypeSet.CreatureType, false), - SERF("Serf", SubTypeSet.CreatureType, false), - SERPENT("Serpent", SubTypeSet.CreatureType, false), - SERVO("Servo", SubTypeSet.CreatureType, false), - SHADE("Shade", SubTypeSet.CreatureType, false), - SHAMAN("Shaman", SubTypeSet.CreatureType, false), - SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType, false), - SHEEP("Sheep", SubTypeSet.CreatureType, false), - SIREN("Siren", SubTypeSet.CreatureType, false), - SITH("Sith", SubTypeSet.CreatureType, false), - SKELETON("Skeleton", SubTypeSet.CreatureType, false), - SLITH("Slith", SubTypeSet.CreatureType, false), - SLIVER("Sliver", SubTypeSet.CreatureType, false), - SLUG("Slug", SubTypeSet.CreatureType, false), - SNAKE("Snake", SubTypeSet.CreatureType, false), - SOLDIER("Soldier", SubTypeSet.CreatureType, false), - SOLTARI("Soltari", SubTypeSet.CreatureType, false), - SPAWN("Spawn", SubTypeSet.CreatureType, false), - SPECTER("Specter", SubTypeSet.CreatureType, false), - SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType, false), - SPHINX("Sphinx", SubTypeSet.CreatureType, false), - SPIDER("Spider", SubTypeSet.CreatureType, false), - SPIKE("Spike", SubTypeSet.CreatureType, false), - SPIRIT("Spirit", SubTypeSet.CreatureType, false), - SPLITTER("Splitter", SubTypeSet.CreatureType, false), - SPONGE("Sponge", SubTypeSet.CreatureType, false), - SQUID("Squid", SubTypeSet.CreatureType, false), - SQUIRREL("Squirrel", SubTypeSet.CreatureType, false), - STARFISH("Starfish", SubTypeSet.CreatureType, false), + SABLE("Sable", SubTypeSet.CreatureType), + SALAMANDER("Salamander", SubTypeSet.CreatureType), + SAMURAI("Samurai", SubTypeSet.CreatureType), + SAND("Sand", SubTypeSet.CreatureType), + SAPROLING("Saproling", SubTypeSet.CreatureType), + SATYR("Satyr", SubTypeSet.CreatureType), + SCARECROW("Scarecrow", SubTypeSet.CreatureType), + SCION("Scion", SubTypeSet.CreatureType), + SCORPION("Scorpion", SubTypeSet.CreatureType), + SCOUT("Scout", SubTypeSet.CreatureType), + SERF("Serf", SubTypeSet.CreatureType), + SERPENT("Serpent", SubTypeSet.CreatureType), + SERVO("Servo", SubTypeSet.CreatureType), + SHADE("Shade", SubTypeSet.CreatureType), + SHAMAN("Shaman", SubTypeSet.CreatureType), + SHAPESHIFTER("Shapeshifter", SubTypeSet.CreatureType), + SHEEP("Sheep", SubTypeSet.CreatureType), + SIREN("Siren", SubTypeSet.CreatureType), + SITH("Sith", SubTypeSet.CreatureType), + SKELETON("Skeleton", SubTypeSet.CreatureType), + SLITH("Slith", SubTypeSet.CreatureType), + SLIVER("Sliver", SubTypeSet.CreatureType), + SLUG("Slug", SubTypeSet.CreatureType), + SNAKE("Snake", SubTypeSet.CreatureType), + SOLDIER("Soldier", SubTypeSet.CreatureType), + SOLTARI("Soltari", SubTypeSet.CreatureType), + SPAWN("Spawn", SubTypeSet.CreatureType), + SPECTER("Specter", SubTypeSet.CreatureType), + SPELLSHAPER("Spellshaper", SubTypeSet.CreatureType), + SPHINX("Sphinx", SubTypeSet.CreatureType), + SPIDER("Spider", SubTypeSet.CreatureType), + SPIKE("Spike", SubTypeSet.CreatureType), + SPIRIT("Spirit", SubTypeSet.CreatureType), + SPLITTER("Splitter", SubTypeSet.CreatureType), + SPONGE("Sponge", SubTypeSet.CreatureType), + SQUID("Squid", SubTypeSet.CreatureType), + SQUIRREL("Squirrel", SubTypeSet.CreatureType), + STARFISH("Starfish", SubTypeSet.CreatureType), STARSHIP("Starship", SubTypeSet.CreatureType, true), // Star Wars SULLUSTAN("Sullustan", SubTypeSet.CreatureType, true), // Star Wars - SURRAKAR("Surrakar", SubTypeSet.CreatureType, false), - SURVIVOR("Survivor", SubTypeSet.CreatureType, false), + SURRAKAR("Surrakar", SubTypeSet.CreatureType), + SURVIVOR("Survivor", SubTypeSet.CreatureType), // T - TETRAVITE("Tetravite", SubTypeSet.CreatureType, false), - THALAKOS("Thalakos", SubTypeSet.CreatureType, false), - THOPTER("Thopter", SubTypeSet.CreatureType, false), + TETRAVITE("Tetravite", SubTypeSet.CreatureType), + THALAKOS("Thalakos", SubTypeSet.CreatureType), + THOPTER("Thopter", SubTypeSet.CreatureType), TRANDOSHAN("Trandoshan", SubTypeSet.CreatureType, true), // Star Wars - THRULL("Thrull", SubTypeSet.CreatureType, false), - TREEFOLK("Treefolk", SubTypeSet.CreatureType, false), - TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType, false), - TROLL("Troll", SubTypeSet.CreatureType, false), - TURTLE("Turtle", SubTypeSet.CreatureType, false), + THRULL("Thrull", SubTypeSet.CreatureType), + TREEFOLK("Treefolk", SubTypeSet.CreatureType), + TRISKELAVITE("Triskelavite", SubTypeSet.CreatureType), + TROLL("Troll", SubTypeSet.CreatureType), + TURTLE("Turtle", SubTypeSet.CreatureType), TROOPER("Trooper", SubTypeSet.CreatureType, true), // Star Wars TWILEK("Twi'lek", SubTypeSet.CreatureType, true), // Star Wars // U UGNAUGHT("Ugnaught", SubTypeSet.CreatureType, true), - UNICORN("Unicorn", SubTypeSet.CreatureType, false), + UNICORN("Unicorn", SubTypeSet.CreatureType), //V - VAMPIRE("Vampire", SubTypeSet.CreatureType, false), - VEDALKEN("Vedalken", SubTypeSet.CreatureType, false), - VIASHINO("Viashino", SubTypeSet.CreatureType, false), - VOLVER("Volver", SubTypeSet.CreatureType, false), + VAMPIRE("Vampire", SubTypeSet.CreatureType), + VEDALKEN("Vedalken", SubTypeSet.CreatureType), + VIASHINO("Viashino", SubTypeSet.CreatureType), + VOLVER("Volver", SubTypeSet.CreatureType), //W - WALL("Wall", SubTypeSet.CreatureType, false), - WARRIOR("Warrior", SubTypeSet.CreatureType, false), + WALL("Wall", SubTypeSet.CreatureType), + WARRIOR("Warrior", SubTypeSet.CreatureType), WEEQUAY("Weequay", SubTypeSet.CreatureType, true), - WEIRD("Weird", SubTypeSet.CreatureType, false), - WEREWOLF("Werewolf", SubTypeSet.CreatureType, false), - WHALE("Whale", SubTypeSet.CreatureType, false), - WIZARD("Wizard", SubTypeSet.CreatureType, false), - WOLF("Wolf", SubTypeSet.CreatureType, false), - WOLVERINE("Wolverine", SubTypeSet.CreatureType, false), - WOMBAT("Wombat", SubTypeSet.CreatureType, false), + WEIRD("Weird", SubTypeSet.CreatureType), + WEREWOLF("Werewolf", SubTypeSet.CreatureType), + WHALE("Whale", SubTypeSet.CreatureType), + WIZARD("Wizard", SubTypeSet.CreatureType), + WOLF("Wolf", SubTypeSet.CreatureType), + WOLVERINE("Wolverine", SubTypeSet.CreatureType), + WOMBAT("Wombat", SubTypeSet.CreatureType), WOOKIEE("Wookiee", SubTypeSet.CreatureType, true), // Star Wars - WORM("Worm", SubTypeSet.CreatureType, false), - WRAITH("Wraith", SubTypeSet.CreatureType, false), - WURM("Wurm", SubTypeSet.CreatureType, false), + WORM("Worm", SubTypeSet.CreatureType), + WRAITH("Wraith", SubTypeSet.CreatureType), + WURM("Wurm", SubTypeSet.CreatureType), // Y - YETI("Yeti", SubTypeSet.CreatureType, false), + YETI("Yeti", SubTypeSet.CreatureType), // Z ZABRAK("Zabrak", SubTypeSet.CreatureType, true), // Star Wars - ZOMBIE("Zombie", SubTypeSet.CreatureType, false), - ZUBERA("Zubera", SubTypeSet.CreatureType, false), + ZOMBIE("Zombie", SubTypeSet.CreatureType), + ZUBERA("Zubera", SubTypeSet.CreatureType), // Planeswalker - AJANI("Ajani", SubTypeSet.PlaneswalkerType, false), - ARLINN("Arlinn", SubTypeSet.PlaneswalkerType, false), - ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType, false), + AJANI("Ajani", SubTypeSet.PlaneswalkerType), + ARLINN("Arlinn", SubTypeSet.PlaneswalkerType), + ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType), AURRA("Aurra", SubTypeSet.PlaneswalkerType, true), // Star Wars - BOLAS("Bolas", SubTypeSet.PlaneswalkerType, false), - CHANDRA("Chandra", SubTypeSet.PlaneswalkerType, false), - DACK("Dack", SubTypeSet.PlaneswalkerType, false), - DARETTI("Daretti", SubTypeSet.PlaneswalkerType, false), - DOMRI("Domri", SubTypeSet.PlaneswalkerType, false), + BOLAS("Bolas", SubTypeSet.PlaneswalkerType), + CHANDRA("Chandra", SubTypeSet.PlaneswalkerType), + DACK("Dack", SubTypeSet.PlaneswalkerType), + DARETTI("Daretti", SubTypeSet.PlaneswalkerType), + DOMRI("Domri", SubTypeSet.PlaneswalkerType), DOOKU("Dooku", SubTypeSet.PlaneswalkerType, true), // Star Wars - DOVIN("Dovin", SubTypeSet.PlaneswalkerType, false), - ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType, false), - FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType, false), - GARRUK("Garruk", SubTypeSet.PlaneswalkerType, false), - GIDEON("Gideon", SubTypeSet.PlaneswalkerType, false), - HUATLI("Huatli", SubTypeSet.PlaneswalkerType, false), - JACE("Jace", SubTypeSet.PlaneswalkerType, false), - KARN("Karn", SubTypeSet.PlaneswalkerType, false), - KAYA("Kaya", SubTypeSet.PlaneswalkerType, false), - KIORA("Kiora", SubTypeSet.PlaneswalkerType, false), - KOTH("Koth", SubTypeSet.PlaneswalkerType, false), - LILIANA("Liliana", SubTypeSet.PlaneswalkerType, false), - NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType, false), - NARSET("Narset", SubTypeSet.PlaneswalkerType, false), - NISSA("Nissa", SubTypeSet.PlaneswalkerType, false), - NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType, false), + DOVIN("Dovin", SubTypeSet.PlaneswalkerType), + ELSPETH("Elspeth", SubTypeSet.PlaneswalkerType), + FREYALISE("Freyalise", SubTypeSet.PlaneswalkerType), + GARRUK("Garruk", SubTypeSet.PlaneswalkerType), + GIDEON("Gideon", SubTypeSet.PlaneswalkerType), + HUATLI("Huatli", SubTypeSet.PlaneswalkerType), + JACE("Jace", SubTypeSet.PlaneswalkerType), + KARN("Karn", SubTypeSet.PlaneswalkerType), + KAYA("Kaya", SubTypeSet.PlaneswalkerType), + KIORA("Kiora", SubTypeSet.PlaneswalkerType), + KOTH("Koth", SubTypeSet.PlaneswalkerType), + LILIANA("Liliana", SubTypeSet.PlaneswalkerType), + NAHIRI("Nahiri", SubTypeSet.PlaneswalkerType), + NARSET("Narset", SubTypeSet.PlaneswalkerType), + NISSA("Nissa", SubTypeSet.PlaneswalkerType), + NIXILIS("Nixilis", SubTypeSet.PlaneswalkerType), OBI_WAN("Obi-Wan", SubTypeSet.PlaneswalkerType, true), // Star Wars - RAL("Ral", SubTypeSet.PlaneswalkerType, false), - SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType, false), - SAMUT("Samut", SubTypeSet.PlaneswalkerType, false), - SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType, false), + RAL("Ral", SubTypeSet.PlaneswalkerType), + SAHEELI("Saheeli", SubTypeSet.PlaneswalkerType), + SAMUT("Samut", SubTypeSet.PlaneswalkerType), + SARKHAN("Sarkhan", SubTypeSet.PlaneswalkerType), SIDIOUS("Sidious", SubTypeSet.PlaneswalkerType, true), // Star Wars - SORIN("Sorin", SubTypeSet.PlaneswalkerType, false), - TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType, false), - TEFERI("Teferi", SubTypeSet.PlaneswalkerType, false), - TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType, false), - TIBALT("Tibalt", SubTypeSet.PlaneswalkerType, false), - UGIN("Ugin", SubTypeSet.PlaneswalkerType, false), - VENSER("Venser", SubTypeSet.PlaneswalkerType, false), - VRASKA("Vraska", SubTypeSet.PlaneswalkerType, false), - XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType, false), + SORIN("Sorin", SubTypeSet.PlaneswalkerType), + TAMIYO("Tamiyo", SubTypeSet.PlaneswalkerType), + TEFERI("Teferi", SubTypeSet.PlaneswalkerType), + TEZZERET("Tezzeret", SubTypeSet.PlaneswalkerType), + TIBALT("Tibalt", SubTypeSet.PlaneswalkerType), + UGIN("Ugin", SubTypeSet.PlaneswalkerType), + VENSER("Venser", SubTypeSet.PlaneswalkerType), + VRASKA("Vraska", SubTypeSet.PlaneswalkerType), + XENAGOS("Xenagos", SubTypeSet.PlaneswalkerType), YODA("Yoda", SubTypeSet.PlaneswalkerType, true); // Star Wars private final SubTypeSet subTypeSet; + SubType(String description, SubTypeSet subTypeSet) { + this(description, subTypeSet, false); + } + + SubType(String description, SubTypeSet subTypeSet, boolean customSet) { + this.description = description; + this.subTypeSet = subTypeSet; + this.customSet = customSet; + } + public String getDescription() { return description; } @@ -404,12 +418,6 @@ public enum SubType { return description; } - SubType(String description, SubTypeSet subTypeSet, boolean customSet) { - this.description = description; - this.subTypeSet = subTypeSet; - this.customSet = customSet; - } - public static SubType byDescription(String subType) { for (SubType s : values()) { if (s.getDescription().equals(subType)) { @@ -434,7 +442,10 @@ public enum SubType { } public static Set getBasicLands(boolean customSet) { - return Arrays.stream(values()).filter(s -> s.customSet == customSet).filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType).collect(Collectors.toSet()); + return Arrays.stream(values()) + .filter(p -> p.getSubTypeSet() == SubTypeSet.BasicLandType) + .filter(s -> s.customSet == customSet) + .collect(Collectors.toSet()); } public static SubTypeList getLandTypes(boolean customSet) { diff --git a/Mage/src/main/java/mage/util/SubTypeList.java b/Mage/src/main/java/mage/util/SubTypeList.java index 71d920983d..8f90b17a8b 100644 --- a/Mage/src/main/java/mage/util/SubTypeList.java +++ b/Mage/src/main/java/mage/util/SubTypeList.java @@ -1,20 +1,27 @@ package mage.util; -import mage.constants.SubType; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import mage.constants.SubType; + public class SubTypeList extends ArrayList { + @Deprecated public boolean addAll(List subtypes) { - return addAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return addAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } + @Deprecated public boolean removeAll(List subtypes){ - return removeAll(subtypes.stream().map(SubType::byDescription).collect(Collectors.toList())); + return removeAll(subtypes.stream() + .map(SubType::byDescription) + .collect(Collectors.toList())); } @@ -22,10 +29,17 @@ public class SubTypeList extends ArrayList { return Collections.addAll(this, subTypes); } + public boolean removeAll(SubType... subTypes) { + return super.removeAll(Arrays.stream(subTypes) + .collect(Collectors.toList())); + } + + @Deprecated public boolean add(String s) { return add(SubType.byDescription(s)); } + @Deprecated public boolean contains(String s) { return contains(SubType.byDescription(s)); } From 3086f535c4c547401457de44d02b0c8601e5b720 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 11:48:53 -0400 Subject: [PATCH 090/100] Update XLN spoiler --- Utils/mtg-cards-data.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 1483be239f..50e35b8647 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32358,6 +32358,7 @@ Opt|Ixalan|65|C|{U}|Instant|||Scry 1.$Draw a card.| Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperous Pirates enters the battlefield, create two colorless Treasure artifact tokens with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."| River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| +Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| @@ -32377,6 +32378,7 @@ Angrath's Marauders|Ixalan|132|R|{5}{R}{R}|Creature - Human Pirate|4|4|If a sour Burning Sun's Avatar|Ixalan|135|R|{3}{R}{R}{R}|Creature - Dinosaur Avatar|6|6|When Burning Sun's Avatar enters the battlefield, it deals 3 damage to target opponent and 3 damage to up to one target creature.| Captain Lannery Storm|Ixalan|136|R|{2}{R}|Legendary Creature - Human Pirate|2|2|Haste$Whenever Captain lannery Storm attacks, create a colorless Treasure artifact token with "{T}, Sacrifice this artifact: Add one mana of any color to your mana pool."$Whenever you sacrifice a Treasure, Captain Lannery Storm gets +1/+0 until end of turn.| Lightning Strike|Ixalan|149|U|{1}{R}|Instant|||Lightning Strike deals 3 damage to target creature or player.| +Raptor Hatchling|Ixalan|149|U|{1}{R}|Creature - Dinosaur|1|1|Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample.| Rowdy Crew|Ixalan|159|M|{2}{R}{R}|Creature - Human Pirate|3|3|Trample$When Rowdy Crew enters the battlefield, draw three cards, then discard two cards at random. If two cards that share a card type are discarded this way, put two +1/+1 counters on Rowdy Crew.| Star of Extinction|Ixalan|161|M|{5}{R}{R}|Sorcery|||Destroy target land. Star of Extinction deals 20 damage to each creature and each planeswalker.| Storm Fleet Arsonist|Ixalan|162|U|{4}{R}|Creature - Orc Pirate|4|4|Raid - When Storm Fleet Arsonist enters the battlefield, if you attacked with a creature this turn, target opponent sacrifices a permanent.| @@ -32392,6 +32394,8 @@ Deeproot Champion|Ixalan|185|R|{1}{G}|Creature - Merfolk Shaman|1|1|Whenever you Emperor's Vanguard|Ixalan|189|R|{3}{G}|Creature - Human Scout|4|3|Whenever Emperor's Vanguard deals combat damage to a player, it explores.| Kumena's Speaker|Ixalan|196|U|{G}|Creature - Merfolk|1|1|Kumena's Speaker gets +1/+1 as long as you control another Merfolk or an Island.| Old-Growth Dryads|Ixalan|199|R|{G}|Creature - Dryad|3|3|When Old-Growth Dryads enters the battlefield, each opponent may search his or her library for a basic land card, put it onto the battlefield tapped, then shuffle his or her library.| +Ranging Raptors|Ixalan|201|U|{2}{G}|Creature - Dinosaur|2|3|Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library.| +Ravenous Daggertooth|Ixalan|202|C|{2}{G}|Creature - Dinosaur|3|2|Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life.| Ripjaw Raptor|Ixalan|203|R|{2}{G}{G}|Creature - Dinosaur|4|5|Enrage — Whenever Ripjaw Raptor is dealt damage, draw a card.| Savage Stomp|Ixalan|205|U|{2}{G}|Sorcery|||Savage Stomp cost {2} less to cast if it targets a Dinosaur you control.$Put a +1/+1 counter on target creature you control. Then that creature fights target creature you don't control.| Shapers' Sanctuary|Ixalan|206|R|{G}|Enchantment|||Whenever a creature you control becomes the target of a spell or ability an opponent controls, you may draw a card.| From 1d74000903ad1a7404d68bf871d9fe6d02adc26f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 14:23:31 -0400 Subject: [PATCH 091/100] Implemented Ranging Raptors --- .../src/mage/cards/r/RangingRaptors.java | 72 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 73 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RangingRaptors.java diff --git a/Mage.Sets/src/mage/cards/r/RangingRaptors.java b/Mage.Sets/src/mage/cards/r/RangingRaptors.java new file mode 100644 index 0000000000..6dd035fb8d --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RangingRaptors.java @@ -0,0 +1,72 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.StaticFilters; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author TheElk801 + */ +public class RangingRaptors extends CardImpl { + + public RangingRaptors(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Enrage - Whenever Ranging Raptors is dealt damage, you may search your library for a basic land card, put it onto the battlefield, then shuffle your library. + Ability ability = new DealtDamageToSourceTriggeredAbility( + Zone.BATTLEFIELD, + new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD), true), + true, + true); + this.addAbility(ability); + } + + public RangingRaptors(final RangingRaptors card) { + super(card); + } + + @Override + public RangingRaptors copy() { + return new RangingRaptors(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4435fa2426..65d1a37d3c 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -98,6 +98,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Prosperous Pirates", 69, Rarity.COMMON, mage.cards.p.ProsperousPirates.class)); cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); + cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); From e9f9eb1cea7ee4f47f36076cf73b38a13ad91b3c Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 14:25:15 -0400 Subject: [PATCH 092/100] Implemented Raptor Hatchling --- .../src/mage/cards/r/RaptorHatchling.java | 66 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RaptorHatchling.java diff --git a/Mage.Sets/src/mage/cards/r/RaptorHatchling.java b/Mage.Sets/src/mage/cards/r/RaptorHatchling.java new file mode 100644 index 0000000000..b19be5c2f1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RaptorHatchling.java @@ -0,0 +1,66 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.permanent.token.DinosaurToken; + +/** + * + * @author TheElk801 + */ +public class RaptorHatchling extends CardImpl { + + public RaptorHatchling(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Enrage - Whenever Raptor Hatchling is dealt damage, create a 3/3 green Dinosaur creature token with trample. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new DinosaurToken()), false, true); + this.addAbility(ability); } + + public RaptorHatchling(final RaptorHatchling card) { + super(card); + } + + @Override + public RaptorHatchling copy() { + return new RaptorHatchling(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 65d1a37d3c..4cb4badcee 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -99,6 +99,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Queen's Bay Soldier", 115, Rarity.COMMON, mage.cards.q.QueensBaySoldier.class)); cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); + cards.add(new SetCardInfo("Raptor Hatchling", 149, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); From 207ffe7c572db2cd3c2f48c84d34eea771e8e8c7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 14:26:21 -0400 Subject: [PATCH 093/100] Implemented Ravenous Daggertooth --- .../src/mage/cards/r/RavenousDaggertooth.java | 66 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java diff --git a/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java b/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java new file mode 100644 index 0000000000..15e0794523 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RavenousDaggertooth.java @@ -0,0 +1,66 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class RavenousDaggertooth extends CardImpl { + + public RavenousDaggertooth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}"); + + this.subtype.add("Dinosaur"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Enrage - Whenever Ravenous Daggertooth is dealt damage, you gain 2 life. + Ability ability = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), false, true); + this.addAbility(ability); + } + + public RavenousDaggertooth(final RavenousDaggertooth card) { + super(card); + } + + @Override + public RavenousDaggertooth copy() { + return new RavenousDaggertooth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 4cb4badcee..0e741b7256 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -100,6 +100,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Raging Swordtooth", 226, Rarity.UNCOMMON, mage.cards.r.RagingSwordtooth.class)); cards.add(new SetCardInfo("Ranging Raptors", 201, Rarity.UNCOMMON, mage.cards.r.RangingRaptors.class)); cards.add(new SetCardInfo("Raptor Hatchling", 149, Rarity.UNCOMMON, mage.cards.r.RaptorHatchling.class)); + cards.add(new SetCardInfo("Ravenous Daggertooth", 202, Rarity.COMMON, mage.cards.r.RavenousDaggertooth.class)); cards.add(new SetCardInfo("Regisaur Alpha", 227, Rarity.RARE, mage.cards.r.RegisaurAlpha.class)); cards.add(new SetCardInfo("Revel in Riches", 117, Rarity.RARE, mage.cards.r.RevelInRiches.class)); cards.add(new SetCardInfo("Ripjaw Raptor", 203, Rarity.RARE, mage.cards.r.RipjawRaptor.class)); From abc71defd0fd5b111312a153a389664eb12664db Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 14:34:54 -0400 Subject: [PATCH 094/100] Implemented Duskborne Skymarcher --- .../src/mage/cards/d/DuskborneSkymarcher.java | 86 +++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 1 + 2 files changed, 87 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java diff --git a/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java new file mode 100644 index 0000000000..43b9623fc8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DuskborneSkymarcher.java @@ -0,0 +1,86 @@ +/* + * 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.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class DuskborneSkymarcher extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(SubType.VAMPIRE, "attacking Vampire"); + + static { + filter.add(new AttackingPredicate()); + } + + public DuskborneSkymarcher(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}"); + + this.subtype.add("Vampire"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {W}, {T}: Target attacking vampire gets +1/+1 until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{W}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public DuskborneSkymarcher(final DuskborneSkymarcher card) { + super(card); + } + + @Override + public DuskborneSkymarcher copy() { + return new DuskborneSkymarcher(this); + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 0e741b7256..85442f0c7a 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -61,6 +61,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Drowned Catacomb", 253, Rarity.RARE, mage.cards.d.DrownedCatacomb.class)); cards.add(new SetCardInfo("Duress", 105, Rarity.COMMON, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Dusk Legion Dreadnought", 236, Rarity.UNCOMMON, mage.cards.d.DuskLegionDreadnought.class)); + cards.add(new SetCardInfo("Duskborne Skymarcher", 9, Rarity.UNCOMMON, mage.cards.d.DuskborneSkymarcher.class)); cards.add(new SetCardInfo("Emperor's Vanguard", 189, Rarity.RARE, mage.cards.e.EmperorsVanguard.class)); cards.add(new SetCardInfo("Entrancing Melody", 55, Rarity.RARE, mage.cards.e.EntrancingMelody.class)); cards.add(new SetCardInfo("Fathom Fleet Captain", 106, Rarity.RARE, mage.cards.f.FathomFleetCaptain.class)); From 6a1c2f933f7a15bb676e7cd2c820c991c386720b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 14:47:13 -0400 Subject: [PATCH 095/100] updated XLN spoiler --- Utils/mtg-cards-data.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index 50e35b8647..d8eb918bfd 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32359,6 +32359,8 @@ Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperou River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| +Arguel’s Blood Fast|Ixalan|90|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel’s Blood Fast.| +Temple of Aclazotz|Ixalan|90|R||Legendary Land|||{T}: Add {B} to your mana pool${T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| Deadeye Tormentor|Ixalan|98|C|{2}{B}|Creature - Human Pirate|2|2|Raid — When Deadeye Tormentor enters the battlefield, if you attacked with a creature this turn, target opponent discards a card.| From 935eefcf010036d1a35824b6f471754ed2ee46e7 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 15:04:19 -0400 Subject: [PATCH 096/100] Implemented Arguel's Blood Fast/Temple of Aclazotz --- .../src/mage/cards/a/ArguelsBloodFast.java | 84 +++++++++++++ .../src/mage/cards/t/TempleOfAclazotz.java | 112 ++++++++++++++++++ Mage.Sets/src/mage/sets/Ixalan.java | 2 + Utils/mtg-cards-data.txt | 2 +- 4 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java create mode 100644 Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java diff --git a/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java new file mode 100644 index 0000000000..5ad32f20df --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/ArguelsBloodFast.java @@ -0,0 +1,84 @@ +/* + * 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.a; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.FatefulHourCondition; +import mage.abilities.costs.common.PayLifeCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.t.TempleOfAclazotz; +import mage.constants.CardType; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author TheElk801 + */ +public class ArguelsBloodFast extends CardImpl { + + public ArguelsBloodFast(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + + addSuperType(SuperType.LEGENDARY); + this.transformable = true; + this.secondSideCardClazz = TempleOfAclazotz.class; + + // {1}{B}, Pay 2 life: Draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}{B}")); + ability.addCost(new PayLifeCost(2)); + this.addAbility(ability); + + // At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast. + this.addAbility(new TransformAbility()); + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.YOU, true), + FatefulHourCondition.instance, + "At the beginning of your upkeep, if you have 5 or less life, you may transform {this}" + )); + } + + public ArguelsBloodFast(final ArguelsBloodFast card) { + super(card); + } + + @Override + public ArguelsBloodFast copy() { + return new ArguelsBloodFast(this); + } +} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java new file mode 100644 index 0000000000..ea8908af27 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java @@ -0,0 +1,112 @@ +/* + * 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.t; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.mana.BlackManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author TheElk801 + */ +public class TempleOfAclazotz extends CardImpl { + + public TempleOfAclazotz(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + addSuperType(SuperType.LEGENDARY); + this.nightCard = true; + + // {T}: Add {B} to your mana pool + this.addAbility(new BlackManaAbility()); + + // {T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MirenTheMoallEffect(), new TapSourceCost()); + ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature"), true))); + this.addAbility(ability); + } + + public TempleOfAclazotz(final TempleOfAclazotz card) { + super(card); + } + + @Override + public TempleOfAclazotz copy() { + return new TempleOfAclazotz(this); + } +} + +class MirenTheMoallEffect extends OneShotEffect { + + public MirenTheMoallEffect() { + super(Outcome.GainLife); + this.staticText = "You gain life equal to the sacrificed creature's toughness"; + } + + public MirenTheMoallEffect(final MirenTheMoallEffect effect) { + super(effect); + } + + @Override + public MirenTheMoallEffect copy() { + return new MirenTheMoallEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + for (Cost cost : source.getCosts()) { + if (cost instanceof SacrificeTargetCost) { + int amount = ((SacrificeTargetCost) cost).getPermanents().get(0).getToughness().getValue(); + if (amount > 0) { + controller.gainLife(amount, game); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Ixalan.java b/Mage.Sets/src/mage/sets/Ixalan.java index 85442f0c7a..5ec8f519e2 100644 --- a/Mage.Sets/src/mage/sets/Ixalan.java +++ b/Mage.Sets/src/mage/sets/Ixalan.java @@ -33,6 +33,7 @@ public class Ixalan extends ExpansionSet { this.ratioBoosterMythic = 8; cards.add(new SetCardInfo("Admiral Beckett Brass", 217, Rarity.MYTHIC, mage.cards.a.AdmiralBeckettBrass.class)); cards.add(new SetCardInfo("Angrath's Marauders", 132, Rarity.RARE, mage.cards.a.AngrathsMarauders.class)); + cards.add(new SetCardInfo("Arguel's Blood Fast", 90, Rarity.RARE, mage.cards.a.ArguelsBloodFast.class)); cards.add(new SetCardInfo("Ashes of the Abhorrent", 2, Rarity.RARE, mage.cards.a.AshesOfTheAbhorrent.class)); cards.add(new SetCardInfo("Bishop of Rebirth", 5, Rarity.RARE, mage.cards.b.BishopOfRebirth.class)); cards.add(new SetCardInfo("Belligerent Brontodon", 218, Rarity.UNCOMMON, mage.cards.b.BelligerentBrontodon.class)); @@ -130,6 +131,7 @@ public class Ixalan extends ExpansionSet { cards.add(new SetCardInfo("Sun-Crowned Hunters", 164, Rarity.COMMON, mage.cards.s.SunCrownedHunters.class)); cards.add(new SetCardInfo("Sunbird's Invocation", 165, Rarity.RARE, mage.cards.s.SunbirdsInvocation.class)); cards.add(new SetCardInfo("Sunpetal Grove", 257, Rarity.RARE, mage.cards.s.SunpetalGrove.class)); + cards.add(new SetCardInfo("Temple of Aclazotz", 90, Rarity.RARE, mage.cards.t.TempleOfAclazotz.class)); cards.add(new SetCardInfo("Thaumatic Compass", 249, Rarity.RARE, mage.cards.t.ThaumaticCompass.class)); cards.add(new SetCardInfo("Tilonalli's Skinshifter", 170, Rarity.RARE, mage.cards.t.TilonallisSkinshifter.class)); cards.add(new SetCardInfo("Tishana's Wayfinder", 211, Rarity.COMMON, mage.cards.t.TishanasWayfinder.class)); diff --git a/Utils/mtg-cards-data.txt b/Utils/mtg-cards-data.txt index d8eb918bfd..5471170848 100644 --- a/Utils/mtg-cards-data.txt +++ b/Utils/mtg-cards-data.txt @@ -32359,7 +32359,7 @@ Prosperous Pirates|Ixalan|69|C|{4}{U}|Creature - Human Pirate|3|4|When Prosperou River's Rebuke|Ixalan|71|R|{4}{U}{U}|Sorcery|||Return all nonland permanents target player controls to their owner's hand.| Siren Stormtamer|Ixalan|79|U|{U}|Creature - Siren Pirate Wizard|1|1|Flying${U}, Sacrifice Siren Stormtamer: Counter target spell or ability that targets you or a creature you control.| Spell Pierce|Ixalan|81|C|{U}|Instant|||Counter target noncreature spell unless its controller pays {2}.| -Arguel’s Blood Fast|Ixalan|90|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel’s Blood Fast.| +Arguel's Blood Fast|Ixalan|90|R|{1}{B}|Legendary Enchantment|||{1}{B}, Pay 2 life: Draw a card.$At the beginning of your upkeep, if you have 5 or less life, you may transform Arguel's Blood Fast.| Temple of Aclazotz|Ixalan|90|R||Legendary Land|||{T}: Add {B} to your mana pool${T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness.| Bloodcrazed Paladin|Ixalan|93|R|{1}{B}|Creature - Vampire Knight|1|1|Flash$Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.| Boneyard Parley|Ixalan|94|M|{5}{B}{B}|Sorcery|||Exile up to five target creature cards from graveyards. An opponent separates those cards into two piles. Put all cards from the pile of your choice onto the battlefield under your control and the rest into their owners' graveyards.| From e27d302e9ddaba0ece757888a6317e4c09931d8a Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 15:58:55 -0400 Subject: [PATCH 097/100] updated card generation template for subtype enum --- Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java | 5 +++-- Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java | 12 ++++++------ Utils/cardClass.tmpl | 3 +++ Utils/gen-card.pl | 5 ++++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java index 5ea7d6a700..74a2c6ea24 100644 --- a/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java +++ b/Mage.Sets/src/mage/cards/h/HuatlisSnubhorn.java @@ -29,6 +29,7 @@ package mage.cards.h; import java.util.UUID; import mage.MageInt; +import mage.constants.SubType; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -42,8 +43,8 @@ public class HuatlisSnubhorn extends CardImpl { public HuatlisSnubhorn(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); - - this.subtype.add("Dinosaur"); + + this.subtype.add(SubType.DINOSAUR); this.power = new MageInt(2); this.toughness = new MageInt(2); diff --git a/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java index ea8908af27..456e62b94c 100644 --- a/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java +++ b/Mage.Sets/src/mage/cards/t/TempleOfAclazotz.java @@ -62,7 +62,7 @@ public class TempleOfAclazotz extends CardImpl { this.addAbility(new BlackManaAbility()); // {T}, Sacrifice a creature: You gain life equal to the sacrificed creature’s toughness. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MirenTheMoallEffect(), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TempleOfAclazotzEffect(), new TapSourceCost()); ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature"), true))); this.addAbility(ability); } @@ -77,20 +77,20 @@ public class TempleOfAclazotz extends CardImpl { } } -class MirenTheMoallEffect extends OneShotEffect { +class TempleOfAclazotzEffect extends OneShotEffect { - public MirenTheMoallEffect() { + public TempleOfAclazotzEffect() { super(Outcome.GainLife); this.staticText = "You gain life equal to the sacrificed creature's toughness"; } - public MirenTheMoallEffect(final MirenTheMoallEffect effect) { + public TempleOfAclazotzEffect(final TempleOfAclazotzEffect effect) { super(effect); } @Override - public MirenTheMoallEffect copy() { - return new MirenTheMoallEffect(this); + public TempleOfAclazotzEffect copy() { + return new TempleOfAclazotzEffect(this); } @Override diff --git a/Utils/cardClass.tmpl b/Utils/cardClass.tmpl index e5afa68f0a..587020011c 100644 --- a/Utils/cardClass.tmpl +++ b/Utils/cardClass.tmpl @@ -34,6 +34,9 @@ if ($power || $power eq 0) { }else { $OUT .= "\nimport mage.MageInt;" } +if ($hasSubTypes eq 'true') { + $OUT .="\nimport mage.constants.SubType;" +} } =][=$abilitiesImports=] import mage.cards.CardImpl; diff --git a/Utils/gen-card.pl b/Utils/gen-card.pl index 9f011e081f..b39fc0bbbc 100755 --- a/Utils/gen-card.pl +++ b/Utils/gen-card.pl @@ -186,6 +186,7 @@ $vars{'toughness'} = $card[7]; my @types; $vars{'planeswalker'} = 'false'; $vars{'subType'} = ''; +$vars{'hasSubTypes'} = 'false'; my $cardAbilities = $card[8]; my $type = $card[5]; while ($type =~ m/([a-zA-Z]+)( )*/g) { @@ -197,7 +198,9 @@ while ($type =~ m/([a-zA-Z]+)( )*/g) { } } else { if (@types) { - $vars{'subType'} .= "\n this.subtype.add(\"$1\");"; + my $st = uc($1); + $vars{'subType'} .= "\n this.subtype.add(SubType.$st);"; + $vars{'hasSubTypes'} = 'true'; } else { my $st = uc($1); $vars{'subType'} .= "\n addSuperType(SuperType.$st);"; From c150c1adae89ba6c7a4f7318f0630409294330d2 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Thu, 7 Sep 2017 16:02:23 -0400 Subject: [PATCH 098/100] small change --- Utils/gen-card.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Utils/gen-card.pl b/Utils/gen-card.pl index b39fc0bbbc..7a2646f1cb 100755 --- a/Utils/gen-card.pl +++ b/Utils/gen-card.pl @@ -187,6 +187,7 @@ my @types; $vars{'planeswalker'} = 'false'; $vars{'subType'} = ''; $vars{'hasSubTypes'} = 'false'; +$vars{'hasSuperTypes'} = 'false'; my $cardAbilities = $card[8]; my $type = $card[5]; while ($type =~ m/([a-zA-Z]+)( )*/g) { @@ -203,7 +204,8 @@ while ($type =~ m/([a-zA-Z]+)( )*/g) { $vars{'hasSubTypes'} = 'true'; } else { my $st = uc($1); - $vars{'subType'} .= "\n addSuperType(SuperType.$st);"; + $vars{'subType'} .= "\n this.addSuperType(SuperType.$st);"; + $vars{'hasSuperTypes'} = 'true'; } } } From 66c4aec499de2fdc38b1b95e1ccf818498cb1cda Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 8 Sep 2017 12:14:18 +0200 Subject: [PATCH 099/100] * Conspiracy - Fixed that it doesn't revert creature types of non-permanent cards when it leaves the battlefield (fixes #3911). --- .../SubTypeChangingEffectsTest.java | 174 ++++++++++++++++++ .../main/java/mage/game/CardAttribute.java | 25 +-- 2 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java new file mode 100644 index 0000000000..3e6a254819 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/continuous/SubTypeChangingEffectsTest.java @@ -0,0 +1,174 @@ +/* + * 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.continuous; + +import mage.cards.Card; +import mage.constants.PhaseStep; +import mage.constants.SubType; +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 SubTypeChangingEffectsTest extends CardTestPlayerBase { + + @Test + public void testConspiracyGiveType() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Conspiracy", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + silvercoatLion = getPermanent("Silvercoat Lion", playerB); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should not have CAT type", false, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + for (Card card : playerB.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAR type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerB.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + } + } + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should have ORC type", true, card.getSubtype(currentGame).contains(SubType.ORC)); + } + + } + for (Card card : playerB.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + + } + } + + } + + /** + * Conspiracy doesn't revert creature types of non-permanent cards when it + * leaves the battlefield + */ + @Test + public void testConspiracyIsRestCorrectly() { + // As Conspiracy enters the battlefield, choose a creature type. + // Creature cards you own that aren't on the battlefield, creature spells you control, and creatures you control are the chosen type. + addCard(Zone.HAND, playerA, "Conspiracy", 1); // Enchantment {3}{B}{B} + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5); + + addCard(Zone.HAND, playerA, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + addCard(Zone.HAND, playerB, "Disenchant", 1); // Instant + addCard(Zone.BATTLEFIELD, playerB, "Plains", 2); + + addCard(Zone.HAND, playerB, "Silvercoat Lion"); + addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion"); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Conspiracy"); + setChoice(playerA, "Orc"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Disenchant", "Conspiracy"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Conspiracy", 1); + assertGraveyardCount(playerB, "Disenchant", 1); + + Permanent silvercoatLion = getPermanent("Silvercoat Lion", playerA); + Assert.assertEquals(true, silvercoatLion.getSubtype(currentGame).contains(SubType.CAT)); + Assert.assertEquals(false, silvercoatLion.getSubtype(currentGame).contains(SubType.ORC)); + + for (Card card : playerA.getLibrary().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getHand().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + } + + for (Card card : playerA.getGraveyard().getCards(currentGame)) { + if (card.isCreature()) { + Assert.assertEquals(card.getName() + " should not have ORC type", false, card.getSubtype(currentGame).contains(SubType.ORC)); + Assert.assertEquals(card.getName() + " should have CAT type", true, card.getSubtype(currentGame).contains(SubType.CAT)); + } + + } + + } +} diff --git a/Mage/src/main/java/mage/game/CardAttribute.java b/Mage/src/main/java/mage/game/CardAttribute.java index 5aa24b9e5f..7a5908c5f7 100644 --- a/Mage/src/main/java/mage/game/CardAttribute.java +++ b/Mage/src/main/java/mage/game/CardAttribute.java @@ -5,42 +5,43 @@ */ package mage.game; +import java.io.Serializable; import mage.ObjectColor; import mage.cards.Card; import mage.util.SubTypeList; -import java.io.Serializable; - /** - * This class saves changed attributes of cards (e.g. in graveyard, exile or player hands or libraries). - * + * This class saves changed attributes of cards (e.g. in graveyard, exile or + * player hands or libraries). + * * @author LevelX2 */ -public class CardAttribute implements Serializable { - +public class CardAttribute implements Serializable { + protected ObjectColor color; protected SubTypeList subtype; public CardAttribute(Card card) { color = card.getColor(null).copy(); - subtype = card.getSubtype(null); + subtype = new SubTypeList(); + subtype.addAll(subtype); } public CardAttribute(CardAttribute cardAttribute) { this.color = cardAttribute.color; this.subtype = cardAttribute.subtype; } - + public CardAttribute copy() { return new CardAttribute(this); } - + public ObjectColor getColor() { - return color; + return color; } - + public SubTypeList getSubtype() { return subtype; } - + } From 2355d35e0478791dfbd1da1cfeba037b7f9e03b3 Mon Sep 17 00:00:00 2001 From: igoudt Date: Fri, 8 Sep 2017 13:11:58 +0200 Subject: [PATCH 100/100] small fixes --- Mage.Sets/src/mage/cards/f/FrenziedGoblin.java | 5 +++-- Mage.Sets/src/mage/cards/l/LilianaVess.java | 9 +++++---- Mage.Sets/src/mage/cards/n/NaturesLore.java | 5 +++-- Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java | 7 ++++--- Mage.Sets/src/mage/cards/r/RecklessSpite.java | 5 +++-- Mage.Sets/src/mage/cards/s/SylvanRanger.java | 2 +- Mage.Sets/src/mage/cards/t/TrueConviction.java | 9 +++++---- Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java | 5 +++-- .../AttacksCreatureYouControlTriggeredAbility.java | 2 +- .../mage/abilities/common/EntersBattlefieldAbility.java | 4 ++-- .../mage/abilities/effects/common/CreateTokenEffect.java | 7 ++++--- .../ReturnToHandChosenControlledPermanentEffect.java | 7 ++++++- 12 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java index fbaae28128..d1e29fd869 100644 --- a/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java +++ b/Mage.Sets/src/mage/cards/f/FrenziedGoblin.java @@ -27,7 +27,6 @@ */ package mage.cards.f; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; @@ -41,6 +40,8 @@ import mage.constants.Duration; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -57,7 +58,7 @@ public class FrenziedGoblin extends CardImpl { // Whenever Frenzied Goblin attacks, you may pay {R}. If you do, target creature can't block this turn. Ability ability = new AttacksTriggeredAbility(new DoIfCostPaid(new CantBlockTargetEffect(Duration.EndOfTurn), new ManaCostsImpl("{R}")),false, - "Whenever {this} attacks you may pay {R}. If you do, target creature can't block this turn."); + "Whenever {this} attacks you, may pay {R}. If you do, target creature can't block this turn."); Target target = new TargetCreaturePermanent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/l/LilianaVess.java b/Mage.Sets/src/mage/cards/l/LilianaVess.java index 193f718a78..7e2681a93b 100644 --- a/Mage.Sets/src/mage/cards/l/LilianaVess.java +++ b/Mage.Sets/src/mage/cards/l/LilianaVess.java @@ -27,9 +27,6 @@ */ package mage.cards.l; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; @@ -49,6 +46,10 @@ import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -89,7 +90,7 @@ class LilianaVessEffect extends OneShotEffect { public LilianaVessEffect() { super(Outcome.PutCreatureInPlay); - staticText = "Put all creature cards in all graveyards onto the battlefield under your control"; + staticText = "Put all creature cards from all graveyards onto the battlefield under your control"; } public LilianaVessEffect(final LilianaVessEffect effect) { diff --git a/Mage.Sets/src/mage/cards/n/NaturesLore.java b/Mage.Sets/src/mage/cards/n/NaturesLore.java index c07a21d454..1f73d2deaa 100644 --- a/Mage.Sets/src/mage/cards/n/NaturesLore.java +++ b/Mage.Sets/src/mage/cards/n/NaturesLore.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,13 +36,15 @@ import mage.filter.FilterCard; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** * * @author LevelX2 */ public class NaturesLore extends CardImpl { - private static final FilterCard filter = new FilterCard("a Forest card"); + private static final FilterCard filter = new FilterCard("Forest card"); static { filter.add(new SubtypePredicate(SubType.FOREST)); diff --git a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java index 7936a68083..1558de8636 100644 --- a/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java +++ b/Mage.Sets/src/mage/cards/n/NazahnReveredBladesmith.java @@ -27,7 +27,6 @@ */ package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; @@ -54,13 +53,15 @@ import mage.game.permanent.Permanent; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author spjspj */ public class NazahnReveredBladesmith extends CardImpl { - private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creatures you control"); + private static final FilterControlledCreaturePermanent equippedFilter = new FilterControlledCreaturePermanent("equipped creature you control"); static { equippedFilter.add(new EquippedPredicate()); @@ -88,7 +89,7 @@ public class NazahnReveredBladesmith extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandOrOnBattlefieldEffect(target, true, true, "Hammer of Nazahn"), true)); // Whenever an equipped creature you control attacks, you may tap target creature defending player controls. - Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), false, equippedFilter, true); + Ability ability = new AttacksCreatureYouControlTriggeredAbility(new NazahnTapEffect(), true, equippedFilter, true); ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature defending player controls"))); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RecklessSpite.java b/Mage.Sets/src/mage/cards/r/RecklessSpite.java index c2b1f67de8..040b7de848 100644 --- a/Mage.Sets/src/mage/cards/r/RecklessSpite.java +++ b/Mage.Sets/src/mage/cards/r/RecklessSpite.java @@ -27,7 +27,6 @@ */ package mage.cards.r; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; @@ -39,13 +38,15 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** * * @author Loki */ public class RecklessSpite extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creatures"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); diff --git a/Mage.Sets/src/mage/cards/s/SylvanRanger.java b/Mage.Sets/src/mage/cards/s/SylvanRanger.java index f3adf52350..9ffcb4728b 100644 --- a/Mage.Sets/src/mage/cards/s/SylvanRanger.java +++ b/Mage.Sets/src/mage/cards/s/SylvanRanger.java @@ -55,7 +55,7 @@ public class SylvanRanger extends CardImpl { // When Sylvan Ranger enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_BASIC_LAND_CARD); - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true))); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(target, true, true), true)); } public SylvanRanger(final SylvanRanger card) { diff --git a/Mage.Sets/src/mage/cards/t/TrueConviction.java b/Mage.Sets/src/mage/cards/t/TrueConviction.java index 9e3e4051f4..66a2312b49 100644 --- a/Mage.Sets/src/mage/cards/t/TrueConviction.java +++ b/Mage.Sets/src/mage/cards/t/TrueConviction.java @@ -27,7 +27,6 @@ */ package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; @@ -39,7 +38,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Zone; -import mage.filter.common.FilterCreaturePermanent; +import mage.filter.StaticFilters; + +import java.util.UUID; /** * @@ -51,8 +52,8 @@ public class TrueConviction extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}{W}"); // Creatures you control have double strike and lifelink. - Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent())); - Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent()); + Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES)); + Effect effect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURES); effect.setText(" and lifelink"); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java index ca0b759851..1d87a743ab 100644 --- a/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java +++ b/Mage.Sets/src/mage/cards/w/WalkerOfSecretWays.java @@ -27,7 +27,6 @@ */ package mage.cards.w; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ActivateIfConditionActivatedAbility; @@ -49,6 +48,8 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetControlledCreaturePermanent; +import java.util.UUID; + /** * * @author LevelX2 @@ -72,7 +73,7 @@ public class WalkerOfSecretWays extends CardImpl { this.addAbility(new NinjutsuAbility(new ManaCostsImpl("{1}{U}"))); // Whenever Walker of Secret Ways deals combat damage to a player, look at that player's hand. - this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), true, true)); + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new WalkerOfSecretWaysEffect(), false, true)); // {1}{U}: Return target Ninja you control to its owner's hand. Activate this ability only during your turn. Ability ability = new ActivateIfConditionActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{1}{U}"), MyTurnCondition.instance); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java index 2445b391bb..1649cc3ab5 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksCreatureYouControlTriggeredAbility.java @@ -97,7 +97,7 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI @Override public String getRule() { - return "Whenever a " + filter.getMessage() + " attacks, " + super.getRule(); + return "Whenever a" + (filter.getMessage().startsWith("a") ? "n " : " ") + " attacks, " + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java index a7cb368a6c..5dc4dd0e8e 100644 --- a/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/EntersBattlefieldAbility.java @@ -95,7 +95,7 @@ public class EntersBattlefieldAbility extends StaticAbility { return; } } - super.addEffect(effect); //To change body of generated methods, choose Tools | Templates. + super.addEffect(effect); } @Override @@ -108,6 +108,6 @@ public class EntersBattlefieldAbility extends StaticAbility { if (abilityRule != null && !abilityRule.isEmpty()) { return abilityRule; } - return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield " + super.getRule(); + return (optional ? "you may have " : "") + "{this} enter" + (optional ? "" : "s") + " the battlefield" + super.getRule(); } } diff --git a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java index 025cebb7ac..c2d2623af4 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CreateTokenEffect.java @@ -27,8 +27,6 @@ */ package mage.abilities.effects.common; -import java.util.ArrayList; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; @@ -43,6 +41,9 @@ import mage.game.permanent.token.Token; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import java.util.ArrayList; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -151,7 +152,7 @@ public class CreateTokenEffect extends OneShotEffect { } sb.append(token.getDescription()); if (token.getDescription().endsWith("token")) { - sb.append("s "); + sb.append("s"); } } if (attacking) { diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java index 6a6949d37e..dced11b2a7 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandChosenControlledPermanentEffect.java @@ -66,7 +66,12 @@ public class ReturnToHandChosenControlledPermanentEffect extends ReturnToHandCho protected String getText() { StringBuilder sb = new StringBuilder("return "); if (!filter.getMessage().startsWith("another")) { - sb.append(CardUtil.numberToText(number, "a")); + if(filter.getMessage().startsWith("a")){ + sb.append("an"); + } + else { + sb.append(CardUtil.numberToText(number, "a")); + } } sb.append(' ').append(filter.getMessage()); if (number > 1) {