diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/AbandonReason.java b/Mage.Sets/src/mage/sets/eldritchmoon/AbandonReason.java new file mode 100644 index 0000000000..5afbf0d49d --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/AbandonReason.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class AbandonReason extends CardImpl { + + public AbandonReason(UUID ownerId) { + super(ownerId, 115, "Abandon Reason", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{R}"); + this.expansionSetCode = "EMN"; + + // Up to two target creatures each get +1/+0 and gain first strike until end of turn. + Effect effect = new BoostTargetEffect(1, 0, Duration.EndOfTurn); + effect.setText("Up to two target creatures each get +1/+0"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, "and gain first strike until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + + // Madness {1}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}"))); + } + + public AbandonReason(final AbandonReason card) { + super(card); + } + + @Override + public AbandonReason copy() { + return new AbandonReason(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/AlchemistsGreeting.java b/Mage.Sets/src/mage/sets/eldritchmoon/AlchemistsGreeting.java new file mode 100644 index 0000000000..199719a612 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/AlchemistsGreeting.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class AlchemistsGreeting extends CardImpl { + + public AlchemistsGreeting(UUID ownerId) { + super(ownerId, 116, "Alchemist's Greeting", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{4}{R}"); + this.expansionSetCode = "EMN"; + + // Alchemist's Greeting deals 4 damage to target creature. + this.getSpellAbility().addEffect(new DamageTargetEffect(4)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + // Madness {1}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{1}{R}"))); + } + + public AlchemistsGreeting(final AlchemistsGreeting card) { + super(card); + } + + @Override + public AlchemistsGreeting copy() { + return new AlchemistsGreeting(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/BloodMist.java b/Mage.Sets/src/mage/sets/eldritchmoon/BloodMist.java new file mode 100644 index 0000000000..c2553d87a3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/BloodMist.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class BloodMist extends CardImpl { + + public BloodMist(UUID ownerId) { + super(ownerId, 119, "Blood Mist", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}"); + this.expansionSetCode = "EMN"; + + // At the beginning of combat on your turn, target creature you control gains double strike until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), TargetController.YOU, false); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + + } + + public BloodMist(final BloodMist card) { + super(card); + } + + @Override + public BloodMist copy() { + return new BloodMist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/BoldImpaler.java b/Mage.Sets/src/mage/sets/eldritchmoon/BoldImpaler.java new file mode 100644 index 0000000000..a541e9c8e2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/BoldImpaler.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class BoldImpaler extends CardImpl { + + public BoldImpaler(UUID ownerId) { + super(ownerId, 120, "Bold Impaler", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Vampire"); + this.subtype.add("Knight"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // {2}{R}: Bold Impaler gets +2/+0 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl("{2}{R}"))); + } + + public BoldImpaler(final BoldImpaler card) { + super(card); + } + + @Override + public BoldImpaler copy() { + return new BoldImpaler(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/BorrowedHostility.java b/Mage.Sets/src/mage/sets/eldritchmoon/BorrowedHostility.java new file mode 100644 index 0000000000..f5b7a485ba --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/BorrowedHostility.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.EscalateAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class BorrowedHostility extends CardImpl { + + public BorrowedHostility(UUID ownerId) { + super(ownerId, 121, "Borrowed Hostility", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "EMN"; + + // Escalate {3} + this.addAbility(new EscalateAbility(new ManaCostsImpl<>("{3}"))); + // Choose one or both — + this.getSpellAbility().getModes().setMinModes(1); + this.getSpellAbility().getModes().setMaxModes(2); + + // Target creature gets +3/+0 until end of turn.; + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new BoostControlledEffect(3, 0, Duration.EndOfTurn)); + + // Target creature gains first strike until end of turn. + Mode mode = new Mode(); + mode.getEffects().add(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn)); + mode.getTargets().add(new TargetCreaturePermanent()); + this.getSpellAbility().addMode(mode); + } + + public BorrowedHostility(final BorrowedHostility card) { + super(card); + } + + @Override + public BorrowedHostility copy() { + return new BorrowedHostility(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/BrazenWolves.java b/Mage.Sets/src/mage/sets/eldritchmoon/BrazenWolves.java new file mode 100644 index 0000000000..c6dbf92990 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/BrazenWolves.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class BrazenWolves extends CardImpl { + + public BrazenWolves(UUID ownerId) { + super(ownerId, 122, "Brazen Wolves", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Wolf"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Whenever Brazen Wolves attacks, it gets +2/+0 until end of turn. + Effect effect = new BoostSourceEffect(2, 0, Duration.EndOfTurn); + effect.setText("it gets +2/+0 until end of turn"); + this.addAbility(new AttacksTriggeredAbility(effect, false)); + } + + public BrazenWolves(final BrazenWolves card) { + super(card); + } + + @Override + public BrazenWolves copy() { + return new BrazenWolves(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfEmrakul.java b/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfEmrakul.java new file mode 100644 index 0000000000..f437ff1d60 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfEmrakul.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.Mana; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfMainPhaseDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AddManaToManaPoolSourceControllerEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class ConduitOfEmrakul extends CardImpl { + + public ConduitOfEmrakul(UUID ownerId) { + super(ownerId, 124, "Conduit of Emrakul", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, ""); + this.expansionSetCode = "EMN"; + this.subtype.add("Eldrazi"); + this.subtype.add("Werewolf"); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // this card is the second face of double-faced card + this.nightCard = true; + + // Whenever Conduit of Emrakul attacks, add {C}{C} to your mana pool at the beginning of your next main phase this turn. + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfMainPhaseDelayedTriggeredAbility( + new AddManaToManaPoolSourceControllerEffect(Mana.GenericMana(2)), false, TargetController.YOU, AtTheBeginOfMainPhaseDelayedTriggeredAbility.PhaseSelection.NEXT_MAIN_THIS_TURN)); + effect.setText("add {C}{C} to your mana pool at the beginning of your next main phase this turn"); + this.addAbility(new AttacksTriggeredAbility(effect, false)); + } + + public ConduitOfEmrakul(final ConduitOfEmrakul card) { + super(card); + } + + @Override + public ConduitOfEmrakul copy() { + return new ConduitOfEmrakul(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfStorms.java b/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfStorms.java new file mode 100644 index 0000000000..e0103de6b2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/ConduitOfStorms.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.Mana; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfMainPhaseDelayedTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AddManaToManaPoolSourceControllerEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class ConduitOfStorms extends CardImpl { + + public ConduitOfStorms(UUID ownerId) { + super(ownerId, 124, "Conduit of Storms", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Werewolf"); + this.subtype.add("Horror"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + this.canTransform = true; + this.secondSideCard = new ConduitOfEmrakul(ownerId); + + // Whenever Conduit of Storms attacks, add {R} to your mana pool at the beginning of your next main phase this turn. + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheBeginOfMainPhaseDelayedTriggeredAbility( + new AddManaToManaPoolSourceControllerEffect(Mana.RedMana(1)), false, TargetController.YOU, AtTheBeginOfMainPhaseDelayedTriggeredAbility.PhaseSelection.NEXT_MAIN_THIS_TURN)); + effect.setText("add {R} to your mana pool at the beginning of your next main phase this turn"); + this.addAbility(new AttacksTriggeredAbility(effect, false)); + // {3}{R}{R}: Transform Conduit of Storms. + this.addAbility(new TransformAbility()); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), new ManaCostsImpl("{3}{R}{R}"))); + } + + public ConduitOfStorms(final ConduitOfStorms card) { + super(card); + } + + @Override + public ConduitOfStorms copy() { + return new ConduitOfStorms(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/DerangedWhelp.java b/Mage.Sets/src/mage/sets/eldritchmoon/DerangedWhelp.java new file mode 100644 index 0000000000..894bcf6176 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/DerangedWhelp.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.MenaceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class DerangedWhelp extends CardImpl { + + public DerangedWhelp(UUID ownerId) { + super(ownerId, 125, "Deranged Whelp", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Wolf"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Menace + this.addAbility(new MenaceAbility()); + } + + public DerangedWhelp(final DerangedWhelp card) { + super(card); + } + + @Override + public DerangedWhelp copy() { + return new DerangedWhelp(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/DistemperOfTheBlood.java b/Mage.Sets/src/mage/sets/eldritchmoon/DistemperOfTheBlood.java new file mode 100644 index 0000000000..117590492e --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/DistemperOfTheBlood.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class DistemperOfTheBlood extends CardImpl { + + public DistemperOfTheBlood(UUID ownerId) { + super(ownerId, 126, "Distemper of the Blood", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{R}"); + this.expansionSetCode = "EMN"; + + // Target creature gets +2/+2 and gains trample until end of turn. + Effect effect = new BoostTargetEffect(2, 2, Duration.EndOfTurn); + effect.setText("Target creature gets +2/+2"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains trample until end of turn"); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + + // Madness {R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{R}"))); + } + + public DistemperOfTheBlood(final DistemperOfTheBlood card) { + super(card); + } + + @Override + public DistemperOfTheBlood copy() { + return new DistemperOfTheBlood(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/FurybladeVampire.java b/Mage.Sets/src/mage/sets/eldritchmoon/FurybladeVampire.java new file mode 100644 index 0000000000..ad624cef30 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/FurybladeVampire.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class FurybladeVampire extends CardImpl { + + public FurybladeVampire(UUID ownerId) { + super(ownerId, 128, "Furyblade Vampire", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Vampire"); + this.subtype.add("Berserker"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // At the beginning of combat on your turn, you may discard a card. If you do, Furyblade Vampire gets +3/+0 until end of turn. + Ability ability = new BeginningOfCombatTriggeredAbility(Zone.BATTLEFIELD, + new DoIfCostPaid(new BoostSourceEffect(3, 0, Duration.EndOfTurn), new DiscardCardCost(), "Discard a card to get {this} +3/+0 until end of turn?", true), TargetController.YOU, false, false); + this.addAbility(ability); + } + + public FurybladeVampire(final FurybladeVampire card) { + super(card); + } + + @Override + public FurybladeVampire copy() { + return new FurybladeVampire(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/HanweirTheWrithingTownship.java b/Mage.Sets/src/mage/sets/eldritchmoon/HanweirTheWrithingTownship.java new file mode 100644 index 0000000000..72073e82dc --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/HanweirTheWrithingTownship.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class HanweirTheWrithingTownship extends CardImpl { + + public HanweirTheWrithingTownship(UUID ownerId) { + super(ownerId, 130, "Hanweir, the Writhing Township", Rarity.RARE, new CardType[]{CardType.CREATURE}, ""); + this.expansionSetCode = "EMN"; + this.supertype.add("Legendary"); + this.subtype.add("Eldrazi"); + this.subtype.add("Ooze"); + this.power = new MageInt(7); + this.toughness = new MageInt(4); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Haste + this.addAbility(HasteAbility.getInstance()); + // Whenever Hanweir, the Writhing Township attacks, put two 3/2 colorless Eldrazi Horror creature tokens onto the battlefield tapped and attacking. + this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new EldraziHorrorToken(), 2, true, true), false)); + } + + public HanweirTheWrithingTownship(final HanweirTheWrithingTownship card) { + super(card); + } + + @Override + public HanweirTheWrithingTownship copy() { + return new HanweirTheWrithingTownship(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/ImpetuousDevils.java b/Mage.Sets/src/mage/sets/eldritchmoon/ImpetuousDevils.java new file mode 100644 index 0000000000..146d89560b --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/ImpetuousDevils.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.combat.MustBeBlockedByTargetSourceEffect; +import mage.abilities.keyword.HasteAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class ImpetuousDevils extends CardImpl { + + public ImpetuousDevils(UUID ownerId) { + super(ownerId, 132, "Impetuous Devils", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Devil"); + this.power = new MageInt(6); + this.toughness = new MageInt(1); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Haste + this.addAbility(HasteAbility.getInstance()); + // When Impetuous Devils attacks, up to one target creature defending player controls blocks it this combat if able. + this.addAbility(new ImpetuousDevilsAbility()); + + // At the beginning of the end step, sacrifice Impetuous Devils. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new SacrificeSourceEffect(), TargetController.NEXT, false)); + } + + public ImpetuousDevils(final ImpetuousDevils card) { + super(card); + } + + @Override + public ImpetuousDevils copy() { + return new ImpetuousDevils(this); + } +} + +class ImpetuousDevilsAbility extends TriggeredAbilityImpl { + + public ImpetuousDevilsAbility() { + super(Zone.BATTLEFIELD, new MustBeBlockedByTargetSourceEffect(Duration.EndOfCombat), false); + } + + public ImpetuousDevilsAbility(final ImpetuousDevilsAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ATTACKER_DECLARED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getSourceId().equals(this.getSourceId())) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + UUID defenderId = game.getCombat().getDefendingPlayerId(sourceId, game); + filter.add(new ControllerIdPredicate(defenderId)); + + this.getTargets().clear(); + TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1, filter, false); + this.addTarget(target); + return true; + } + return false; + } + + @Override + public String getRule() { + return "When {this} attacks, up to one target creature defending player controls blocks it this combat if able."; + } + + @Override + public ImpetuousDevilsAbility copy() { + return new ImpetuousDevilsAbility(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/InsatiableGorgers.java b/Mage.Sets/src/mage/sets/eldritchmoon/InsatiableGorgers.java new file mode 100644 index 0000000000..eeeb9a69c7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/InsatiableGorgers.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksEachCombatStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class InsatiableGorgers extends CardImpl { + + public InsatiableGorgers(UUID ownerId) { + super(ownerId, 134, "Insatiable Gorgers", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Vampire"); + this.subtype.add("Berserker"); + this.power = new MageInt(5); + this.toughness = new MageInt(3); + + // Insatiable Gorgers attacks each combat if able. + this.addAbility(new AttacksEachCombatStaticAbility()); + + // Madness {3}{R} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{3}{R}"))); + } + + public InsatiableGorgers(final InsatiableGorgers card) { + super(card); + } + + @Override + public InsatiableGorgers copy() { + return new InsatiableGorgers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/MirrorwingDragon.java b/Mage.Sets/src/mage/sets/eldritchmoon/MirrorwingDragon.java new file mode 100644 index 0000000000..0fe6cb84b2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/MirrorwingDragon.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.CopySpellForEachItCouldTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterInPlay; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.Target; +import mage.util.TargetAddress; + +/** + * + * @author LevelX2 + */ +public class MirrorwingDragon extends CardImpl { + + public MirrorwingDragon(UUID ownerId) { + super(ownerId, 136, "Mirrorwing Dragon", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{R}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Dragon"); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever a player casts an instant or sorcery spell that targets only Mirrorwing Dragon, + // that player copies that spell for each other creature he or she controls that the spell could target. + // Each copy targets a different one of those creatures. + this.addAbility(new MirrorwingDragonCopyTriggeredAbility()); + } + + public MirrorwingDragon(final MirrorwingDragon card) { + super(card); + } + + @Override + public MirrorwingDragon copy() { + return new MirrorwingDragon(this); + } +} + +class MirrorwingDragonCopyTriggeredAbility extends TriggeredAbilityImpl { + + MirrorwingDragonCopyTriggeredAbility() { + super(Zone.BATTLEFIELD, new MirrorwingDragonCopySpellEffect(), false); + } + + MirrorwingDragonCopyTriggeredAbility(final MirrorwingDragonCopyTriggeredAbility ability) { + super(ability); + } + + @Override + public MirrorwingDragonCopyTriggeredAbility copy() { + return new MirrorwingDragonCopyTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + Spell spell = game.getStack().getSpell(event.getTargetId()); + return checkSpell(spell, game); + } + + private boolean checkSpell(Spell spell, Game game) { + if (spell != null + && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { + for (TargetAddress addr : TargetAddress.walk(spell)) { + Target targetInstance = addr.getTarget(spell); + for (UUID target : targetInstance.getTargets()) { + Permanent permanent = game.getPermanent(target); + if (permanent == null || !permanent.getId().equals(getSourceId())) { + return false; + } + } + } + getEffects().get(0).setValue("triggeringSpell", spell); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever a player casts an instant or sorcery spell that targets only {this}, " + + "that player copies that spell for each creature he or she controls that the spell could target. " + + "Each copy targets a different one of those creatures."; + } +} + +class MirrorwingDragonCopySpellEffect extends CopySpellForEachItCouldTargetEffect { + + public MirrorwingDragonCopySpellEffect() { + this(new FilterControlledCreaturePermanent()); + this.staticText = "that player copies that spell for each creature he or she controls that the spell could target. Each copy targets a different one of those creatures."; + } + + public MirrorwingDragonCopySpellEffect(MirrorwingDragonCopySpellEffect effect) { + super(effect); + } + + private MirrorwingDragonCopySpellEffect(FilterInPlay filter) { + super(filter); + } + + @Override + protected Player getPlayer(Game game, Ability source) { + Spell spell = getSpell(game, source); + if (spell != null) { + return game.getPlayer(spell.getControllerId()); + } + return null; + } + + @Override + protected Spell getSpell(Game game, Ability source) { + return (Spell) getValue("triggeringSpell"); + } + + @Override + protected boolean changeTarget(Target target, Game game, Ability source) { + return true; + } + + @Override + protected void modifyCopy(Spell copy, Game game, Ability source) { + } + + @Override + public MirrorwingDragonCopySpellEffect copy() { + return new MirrorwingDragonCopySpellEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/NahirisWrath.java b/Mage.Sets/src/mage/sets/eldritchmoon/NahirisWrath.java new file mode 100644 index 0000000000..259352bd21 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/NahirisWrath.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.VariableCost; +import mage.abilities.costs.VariableCostImpl; +import mage.abilities.costs.common.DiscardTargetCost; +import mage.abilities.dynamicvalue.common.DiscardCostCardConvertedMana; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreatureOrPlaneswalker; + +/** + * + * @author LevelX2 + */ +public class NahirisWrath extends CardImpl { + + public NahirisWrath(UUID ownerId) { + super(ownerId, 137, "Nahiri's Wrath", Rarity.MYTHIC, new CardType[]{CardType.SORCERY}, "{2}{R}"); + this.expansionSetCode = "EMN"; + + // As an additional cost to cast Nahiri's Wrath, discard X cards. + this.getSpellAbility().addCost(new NahirisWrathAdditionalCost()); + + // Nahiri's Wrath deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers. + Effect effect = new DamageTargetEffect(new DiscardCostCardConvertedMana()); + effect.setText("{this} deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers"); + this.getSpellAbility().addEffect(effect); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + ability.getTargets().clear(); + int numTargets = 0; + for (VariableCost cost : ability.getCosts().getVariableCosts()) { + if (cost instanceof NahirisWrathAdditionalCost) { + numTargets = ((NahirisWrathAdditionalCost) cost).getAmount(); + break; + } + } + if (numTargets > 0) { + ability.addTarget(new TargetCreatureOrPlaneswalker(0, numTargets, new FilterCreatureOrPlaneswalkerPermanent(), false)); + } + } + + public NahirisWrath(final NahirisWrath card) { + super(card); + } + + @Override + public NahirisWrath copy() { + return new NahirisWrath(this); + } +} + +class NahirisWrathAdditionalCost extends VariableCostImpl { + + NahirisWrathAdditionalCost() { + super("cards to discard"); + this.text = "As an additional cost to cast {this}, discard X cards"; + } + + NahirisWrathAdditionalCost(final NahirisWrathAdditionalCost cost) { + super(cost); + } + + @Override + public NahirisWrathAdditionalCost copy() { + return new NahirisWrathAdditionalCost(this); + } + + @Override + public int getMaxValue(Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + return controller.getHand().size(); + } + return 0; + } + + @Override + public Cost getFixedCostsFromAnnouncedValue(int xValue) { + TargetCardInHand target = new TargetCardInHand(xValue, new FilterCard()); + return new DiscardTargetCost(target); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/OtherworldlyOutburst.java b/Mage.Sets/src/mage/sets/eldritchmoon/OtherworldlyOutburst.java new file mode 100644 index 0000000000..6c3c1f7629 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/OtherworldlyOutburst.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ZoneChangeEvent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class OtherworldlyOutburst extends CardImpl { + + public OtherworldlyOutburst(UUID ownerId) { + super(ownerId, 138, "Otherworldly Outburst", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "EMN"; + + // Target creature gets +1/+0 until end of turn. When that creature dies this turn, put a 3/2 colorless Eldrazi Horror creature token onto the battlefield. + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new BoostTargetEffect(1, 0, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new OtherworldlyOutburstEffect()); + } + + public OtherworldlyOutburst(final OtherworldlyOutburst card) { + super(card); + } + + @Override + public OtherworldlyOutburst copy() { + return new OtherworldlyOutburst(this); + } +} + +class OtherworldlyOutburstEffect extends OneShotEffect { + + public OtherworldlyOutburstEffect() { + super(Outcome.UnboostCreature); + this.staticText = "When that creature dies this turn, put a 3/2 colorless Eldrazi Horror creature token onto the battlefield"; + } + + public OtherworldlyOutburstEffect(final OtherworldlyOutburstEffect effect) { + super(effect); + } + + @Override + public OtherworldlyOutburstEffect copy() { + return new OtherworldlyOutburstEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + DelayedTriggeredAbility delayedAbility = new OtherworldlyOutburstDelayedTriggeredAbility(source.getFirstTarget()); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.setSourceObject(source.getSourceObject(game), game); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } +} + +class OtherworldlyOutburstDelayedTriggeredAbility extends DelayedTriggeredAbility { + + private final UUID target; + + public OtherworldlyOutburstDelayedTriggeredAbility(UUID target) { + super(new CreateTokenEffect(new EldraziHorrorToken()), Duration.EndOfTurn); + this.target = target; + } + + public OtherworldlyOutburstDelayedTriggeredAbility(OtherworldlyOutburstDelayedTriggeredAbility ability) { + super(ability); + this.target = ability.target; + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.ZONE_CHANGE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getTargetId().equals(target)) { + ZoneChangeEvent zEvent = (ZoneChangeEvent) event; + if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) { + return true; + } + } + return false; + } + + @Override + public OtherworldlyOutburstDelayedTriggeredAbility copy() { + return new OtherworldlyOutburstDelayedTriggeredAbility(this); + } + + @Override + public String getRule() { + return "When that creature dies this turn, put a 3/2 colorless Eldrazi Horror creature token onto the battlefield."; + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/PropheticRavings.java b/Mage.Sets/src/mage/sets/eldritchmoon/PropheticRavings.java new file mode 100644 index 0000000000..4251138ac6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/PropheticRavings.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class PropheticRavings extends CardImpl { + + public PropheticRavings(UUID ownerId) { + super(ownerId, 139, "Prophetic Ravings", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + this.expansionSetCode = "EMN"; + 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); + + // Enchanted creature has haste and "{T}, Discard a card: Draw a card." + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA)); + Ability abilityToGain = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), new TapSourceCost()); + abilityToGain.addCost(new DiscardCardCost()); + Effect effect = new GainAbilityAttachedEffect(abilityToGain, AttachmentType.AURA); + effect.setText("and \"{T}, Discard a card: Draw a card.\""); + ability.addEffect(effect); + this.addAbility(ability); + } + + public PropheticRavings(final PropheticRavings card) { + super(card); + } + + @Override + public PropheticRavings copy() { + return new PropheticRavings(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/SavageAlliance.java b/Mage.Sets/src/mage/sets/eldritchmoon/SavageAlliance.java new file mode 100644 index 0000000000..d484b0c3a6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/SavageAlliance.java @@ -0,0 +1,159 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.EscalateAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class SavageAlliance extends CardImpl { + + public SavageAlliance(UUID ownerId) { + super(ownerId, 140, "Savage Alliance", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{R}"); + this.expansionSetCode = "EMN"; + + // Escalate {1} + this.addAbility(new EscalateAbility(new GenericManaCost(1))); + + // Choose one or more — + this.getSpellAbility().getModes().setMinModes(1); + this.getSpellAbility().getModes().setMaxModes(3); + + // Creatures target player controls gain trample until end of turn. + this.getSpellAbility().addEffect(new SavageAllianceGainTrampleEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + + // Savage Alliance deals 2 damage to target creature.; + Mode mode = new Mode(); + mode.getEffects().add(new DamageTargetEffect(2)); + mode.getTargets().add(new TargetCreaturePermanent()); + this.getSpellAbility().addMode(mode); + + // Savage Alliance deals 1 damage to each creature target opponent controls. + mode = new Mode(); + mode.getEffects().add(new SavageAllianceDamageEffect()); + mode.getTargets().add(new TargetOpponent()); + this.getSpellAbility().addMode(mode); + } + + public SavageAlliance(final SavageAlliance card) { + super(card); + } + + @Override + public SavageAlliance copy() { + return new SavageAlliance(this); + } +} + +class SavageAllianceGainTrampleEffect extends OneShotEffect { + + public SavageAllianceGainTrampleEffect() { + super(Outcome.AddAbility); + staticText = "Creatures target player controls gain trample until end of turn"; + } + + public SavageAllianceGainTrampleEffect(final SavageAllianceGainTrampleEffect effect) { + super(effect); + } + + @java.lang.Override + public SavageAllianceGainTrampleEffect copy() { + return new SavageAllianceGainTrampleEffect(this); + } + + @java.lang.Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (player != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerIdPredicate((player.getId()))); + ContinuousEffect effect = new GainAbilityAllEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter); + game.addEffect(effect, source); + return true; + } + return false; + } +} + +class SavageAllianceDamageEffect extends OneShotEffect { + + public SavageAllianceDamageEffect() { + super(Outcome.Damage); + this.staticText = "{this} deals 1 damage to each creature target opponent controls"; + } + + public SavageAllianceDamageEffect(final SavageAllianceDamageEffect effect) { + super(effect); + } + + @Override + public SavageAllianceDamageEffect copy() { + return new SavageAllianceDamageEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent(); + filter.add(new ControllerIdPredicate(player.getId())); + List creatures = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); + for (Permanent creature : creatures) { + creature.damage(1, source.getSourceId(), game, false, true); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/ShredsOfSanity.java b/Mage.Sets/src/mage/sets/eldritchmoon/ShredsOfSanity.java new file mode 100644 index 0000000000..48cb179042 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/ShredsOfSanity.java @@ -0,0 +1,118 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileSourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; + +/** + * + * @author LevelX2 + */ +public class ShredsOfSanity extends CardImpl { + + private final static FilterCard filterInstant = new FilterCard(); + private final static FilterCard filterSorcery = new FilterCard(); + + static { + filterInstant.add(new CardTypePredicate(CardType.INSTANT)); + filterSorcery.add(new CardTypePredicate(CardType.SORCERY)); + } + + public ShredsOfSanity(UUID ownerId) { + super(ownerId, 141, "Shreds of Sanity", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{R}"); + this.expansionSetCode = "EMN"; + + // Return up to one target instant card and up to one target sorcery card from your graveyard to your hand, then discard a card. Exile Shreds of Sanity. + this.getSpellAbility().addEffect(new ShredsOfSanityEffect()); + this.getSpellAbility().addTarget(new TargetCard(0, 1, Zone.GRAVEYARD, filterInstant)); + this.getSpellAbility().addTarget(new TargetCard(0, 1, Zone.GRAVEYARD, filterSorcery)); + this.getSpellAbility().addEffect(new ExileSourceEffect()); + } + + public ShredsOfSanity(final ShredsOfSanity card) { + super(card); + } + + @Override + public ShredsOfSanity copy() { + return new ShredsOfSanity(this); + } +} + +class ShredsOfSanityEffect extends OneShotEffect { + + public ShredsOfSanityEffect() { + super(Outcome.Benefit); + this.staticText = "return up to one target instant card and up to one target sorcery card from your graveyard to your hand, then discard a card"; + } + + public ShredsOfSanityEffect(final ShredsOfSanityEffect effect) { + super(effect); + } + + @Override + public ShredsOfSanityEffect copy() { + return new ShredsOfSanityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cardsToHand = new CardsImpl(); + Card card = game.getCard(getTargetPointer().getFirst(game, source)); + if (card != null) { + cardsToHand.add(card); + } + card = game.getCard(source.getTargets().get(1).getFirstTarget()); + if (card != null) { + cardsToHand.add(card); + } + controller.moveCards(cardsToHand, Zone.HAND, source, game); + controller.discardOne(false, source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/SpreadingFlames.java b/Mage.Sets/src/mage/sets/eldritchmoon/SpreadingFlames.java new file mode 100644 index 0000000000..6548566a5a --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/SpreadingFlames.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.effects.common.DamageMultiEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetCreatureOrPlayerAmount; + +/** + * + * @author LevelX2 + */ +public class SpreadingFlames extends CardImpl { + + public SpreadingFlames(UUID ownerId) { + super(ownerId, 143, "Spreading Flames", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{6}{R}"); + this.expansionSetCode = "EMN"; + + // Spreading Flames deals 6 damage divided as you choose among any number of target creatures. + this.getSpellAbility().addEffect(new DamageMultiEffect(6)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayerAmount(6)); + } + + public SpreadingFlames(final SpreadingFlames card) { + super(card); + } + + @Override + public SpreadingFlames copy() { + return new SpreadingFlames(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/StensiaBanquet.java b/Mage.Sets/src/mage/sets/eldritchmoon/StensiaBanquet.java new file mode 100644 index 0000000000..4978bda5c3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/StensiaBanquet.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetOpponent; + +/** + * + * @author LevelX2 + */ +public class StensiaBanquet extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("Vampires you control"); + + static { + filter.add(new SubtypePredicate("Vampires")); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public StensiaBanquet(UUID ownerId) { + super(ownerId, 144, "Stensia Banquet", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{R}"); + this.expansionSetCode = "EMN"; + + // Stensia Banquet deals damage to target opponent equal to the number of Vampires you control. + this.getSpellAbility().addEffect(new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter))); + this.getSpellAbility().addTarget(new TargetOpponent()); + + // Draw a card. + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); + } + + public StensiaBanquet(final StensiaBanquet card) { + super(card); + } + + @Override + public StensiaBanquet copy() { + return new StensiaBanquet(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/StensiaInnkeeper.java b/Mage.Sets/src/mage/sets/eldritchmoon/StensiaInnkeeper.java new file mode 100644 index 0000000000..6644070f91 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/StensiaInnkeeper.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class StensiaInnkeeper extends CardImpl { + + private final static FilterLandPermanent filter = new FilterLandPermanent("land an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public StensiaInnkeeper(UUID ownerId) { + super(ownerId, 145, "Stensia Innkeeper", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Vampire"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Stensia Innkeeper enters the battlefield, tap target land an opponent controls. That land doesn't untap during its controller's next untap step. + Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect(), false); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("That land")); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + } + + public StensiaInnkeeper(final StensiaInnkeeper card) { + super(card); + } + + @Override + public StensiaInnkeeper copy() { + return new StensiaInnkeeper(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/ThermoAlchemist.java b/Mage.Sets/src/mage/sets/eldritchmoon/ThermoAlchemist.java new file mode 100644 index 0000000000..14a4015e7b --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/ThermoAlchemist.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterInstantOrSorcerySpell; + +/** + * + * @author LevelX2 + */ +public class ThermoAlchemist extends CardImpl { + + public ThermoAlchemist(UUID ownerId) { + super(ownerId, 147, "Thermo-Alchemist", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(0); + this.toughness = new MageInt(3); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + // {T}: Thermo-Alchemist deals 1 damage to each opponent. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT), new TapSourceCost()); + this.addAbility(ability); + // Whenever you cast an instant or sorcery spell, untap Thermo-Alchemist. + this.addAbility(new SpellCastControllerTriggeredAbility(new UntapSourceEffect(), new FilterInstantOrSorcerySpell(), false)); + } + + public ThermoAlchemist(final ThermoAlchemist card) { + super(card); + } + + @Override + public ThermoAlchemist copy() { + return new ThermoAlchemist(this); + } +} diff --git a/Mage.Sets/src/mage/sets/eldritchmoon/WeaverOfLightning.java b/Mage.Sets/src/mage/sets/eldritchmoon/WeaverOfLightning.java new file mode 100644 index 0000000000..fc51080873 --- /dev/null +++ b/Mage.Sets/src/mage/sets/eldritchmoon/WeaverOfLightning.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.sets.eldritchmoon; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.common.FilterInstantOrSorcerySpell; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class WeaverOfLightning extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public WeaverOfLightning(UUID ownerId) { + super(ownerId, 149, "Weaver of Lightning", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "EMN"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Reach + this.addAbility(ReachAbility.getInstance()); + // Whenever you cast an instant or sorcery spell, Weaver of Lightning deals 1 damage to target creature an opponent controls. + Ability ability = new SpellCastControllerTriggeredAbility(new DamageTargetEffect(1), new FilterInstantOrSorcerySpell(), false); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(ability); + } + + public WeaverOfLightning(final WeaverOfLightning card) { + super(card); + } + + @Override + public WeaverOfLightning copy() { + return new WeaverOfLightning(this); + } +} diff --git a/Mage.Sets/src/mage/sets/guildpact/InkTreaderNephilim.java b/Mage.Sets/src/mage/sets/guildpact/InkTreaderNephilim.java index b1fb65c808..5b257415d0 100644 --- a/Mage.Sets/src/mage/sets/guildpact/InkTreaderNephilim.java +++ b/Mage.Sets/src/mage/sets/guildpact/InkTreaderNephilim.java @@ -44,6 +44,7 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; import mage.game.stack.Spell; +import mage.players.Player; import mage.target.Target; import mage.util.TargetAddress; @@ -97,8 +98,8 @@ class InkTreaderNephilimTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && - (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))){ + if (spell != null + && (spell.getCardType().contains(CardType.INSTANT) || spell.getCardType().contains(CardType.SORCERY))) { for (Effect effect : getEffects()) { effect.setValue("triggeringSpell", spell); } @@ -133,7 +134,6 @@ class InkTreaderNephilimTriggeredAbility extends TriggeredAbilityImpl { } } - class InkTreaderNephilimEffect extends CopySpellForEachItCouldTargetEffect { public InkTreaderNephilimEffect() { @@ -148,6 +148,11 @@ class InkTreaderNephilimEffect extends CopySpellForEachItCouldTargetEffect filter) { super(filter); } - + + @Override + protected Player getPlayer(Game game, Ability source) { + return game.getPlayer(source.getControllerId()); + } + @Override protected Spell getSpell(Game game, Ability source) { return (Spell) getValue("triggeringSpell"); diff --git a/Mage.Sets/src/mage/sets/tempest/LightningBlast.java b/Mage.Sets/src/mage/sets/tempest/LightningBlast.java index 9790a07e14..bd977cb86b 100644 --- a/Mage.Sets/src/mage/sets/tempest/LightningBlast.java +++ b/Mage.Sets/src/mage/sets/tempest/LightningBlast.java @@ -28,10 +28,10 @@ package mage.sets.tempest; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.target.common.TargetCreatureOrPlayer; /** @@ -44,6 +44,7 @@ public class LightningBlast extends CardImpl { super(ownerId, 185, "Lightning Blast", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{R}"); this.expansionSetCode = "TMP"; + // Lightning Blast deals 4 damage to target creature. this.getSpellAbility().addEffect(new DamageTargetEffect(4)); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); } diff --git a/Mage.Sets/src/mage/sets/torment/Radiate.java b/Mage.Sets/src/mage/sets/torment/Radiate.java index 85a52897a8..c4d3d99a22 100644 --- a/Mage.Sets/src/mage/sets/torment/Radiate.java +++ b/Mage.Sets/src/mage/sets/torment/Radiate.java @@ -44,11 +44,11 @@ import mage.filter.predicate.ObjectPlayerPredicate; import mage.game.Game; import mage.game.stack.Spell; import mage.game.stack.StackObject; +import mage.players.Player; import mage.target.Target; import mage.target.TargetSpell; import mage.util.TargetAddress; - /** * @author duncant */ @@ -61,7 +61,7 @@ public class Radiate extends CardImpl { filter.add(new SpellWithOnlyPermanentOrPlayerTargetsPredicate()); filter.setMessage("instant or sorcery spell that targets only a single permanent or player"); } - + public Radiate(UUID ownerId) { super(ownerId, 113, "Radiate", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{R}{R}"); this.expansionSetCode = "TOR"; @@ -82,6 +82,7 @@ public class Radiate extends CardImpl { } class SpellWithOnlySingleTargetPredicate implements ObjectPlayerPredicate> { + @Override public boolean apply(ObjectPlayer input, Game game) { Spell spell = input.getObject(); @@ -104,6 +105,7 @@ class SpellWithOnlySingleTargetPredicate implements ObjectPlayerPredicate> { + @Override public boolean apply(ObjectPlayer input, Game game) { Spell spell = input.getObject(); @@ -114,7 +116,7 @@ class SpellWithOnlyPermanentOrPlayerTargetsPredicate implements ObjectPlayerPred Target targetInstance = addr.getTarget(spell); for (UUID targetId : targetInstance.getTargets()) { if (game.getPermanent(targetId) == null - && game.getPlayer(targetId) == null) { + && game.getPlayer(targetId) == null) { return false; } } @@ -122,15 +124,13 @@ class SpellWithOnlyPermanentOrPlayerTargetsPredicate implements ObjectPlayerPred return true; } } - - class RadiateEffect extends CopySpellForEachItCouldTargetEffect { public RadiateEffect() { this(new FilterPermanentOrPlayer()); } - + public RadiateEffect(RadiateEffect effect) { super(effect); } @@ -143,7 +143,12 @@ class RadiateEffect extends CopySpellForEachItCouldTargetEffect { public String getText(Mode mode) { return "Choose target instant or sorcery spell that targets only a single permanent or player. Copy that spell for each other permanent or player the spell could target. Each copy targets a different one of those permanents and players."; } - + + @Override + protected Player getPlayer(Game game, Ability source) { + return game.getPlayer(source.getControllerId()); + } + @Override protected Spell getSpell(Game game, Ability source) { StackObject ret = game.getStack().getStackObject(targetPointer.getFirst(game, source)); diff --git a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java index d1cd7427c4..0a871fa052 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/AtTheBeginOfMainPhaseDelayedTriggeredAbility.java @@ -27,10 +27,10 @@ */ package mage.abilities.common.delayed; -import mage.constants.TargetController; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.constants.Duration; +import mage.constants.TargetController; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -44,9 +44,10 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger public enum PhaseSelection { - NEXT_PRECOMBAT_MAIN("next precombat"), - NEXT_POSTCOMAT_MAIN("next postcombat"), - NEXT_MAIN("next"); + NEXT_PRECOMBAT_MAIN("next precombat main phase"), + NEXT_POSTCOMAT_MAIN("next postcombat main phase"), + NEXT_MAIN("next main phase"), + NEXT_MAIN_THIS_TURN("next main phase this turn"); private final String text; @@ -63,7 +64,6 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger private final TargetController targetController; private final PhaseSelection phaseSelection; - public AtTheBeginOfMainPhaseDelayedTriggeredAbility(Effect effect, boolean optional, TargetController targetController, PhaseSelection phaseSelection) { super(effect, Duration.EndOfGame, true, optional); this.targetController = targetController; @@ -116,6 +116,7 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger private boolean checkPhase(EventType eventType) { switch (phaseSelection) { case NEXT_MAIN: + case NEXT_MAIN_THIS_TURN: return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType) || EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType); case NEXT_POSTCOMAT_MAIN: return EventType.POSTCOMBAT_MAIN_PHASE_PRE.equals(eventType); @@ -131,16 +132,16 @@ public class AtTheBeginOfMainPhaseDelayedTriggeredAbility extends DelayedTrigger StringBuilder sb = new StringBuilder(); switch (targetController) { case YOU: - sb.append("At the beginning of your ").append(phaseSelection.toString()).append(" main phase, "); + sb.append("At the beginning of your ").append(phaseSelection.toString()).append(", "); break; case OPPONENT: - sb.append("At the beginning of an opponent's ").append(phaseSelection.toString()).append(" main phase, "); + sb.append("At the beginning of an opponent's ").append(phaseSelection.toString()).append(", "); break; case ANY: - sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase, "); + sb.append("At the beginning of the ").append(phaseSelection.toString()).append(", "); break; case CONTROLLER_ATTACHED_TO: - sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase of enchanted creature's controller, "); + sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" of enchanted creature's controller, "); break; } sb.append(getEffects().getText(modes.getMode())); diff --git a/Mage/src/main/java/mage/abilities/effects/common/CopySpellForEachItCouldTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/CopySpellForEachItCouldTargetEffect.java index 4fcf18e9eb..543a407086 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/CopySpellForEachItCouldTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/CopySpellForEachItCouldTargetEffect.java @@ -72,6 +72,8 @@ public abstract class CopySpellForEachItCouldTargetEffect ex protected abstract Spell getSpell(Game game, Ability source); + protected abstract Player getPlayer(Game game, Ability source); + protected abstract boolean changeTarget(Target target, Game game, Ability source); protected abstract void modifyCopy(Spell copy, Game game, Ability source); @@ -82,8 +84,8 @@ public abstract class CopySpellForEachItCouldTargetEffect ex @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { + Player actingPlayer = getPlayer(game, source); + if (actingPlayer == null) { return false; } Spell spell = getSpell(game, source); @@ -111,7 +113,7 @@ public abstract class CopySpellForEachItCouldTargetEffect ex sampleTarget.setNotTarget(true); Map> playerTargetCopyMap = new HashMap<>(); - for (UUID objId : sampleTarget.possibleTargets(controller.getId(), game)) { + for (UUID objId : sampleTarget.possibleTargets(actingPlayer.getId(), game)) { MageItem obj = game.getObject(objId); if (obj == null) { obj = game.getPlayer(objId); @@ -131,7 +133,7 @@ public abstract class CopySpellForEachItCouldTargetEffect ex for (TargetAddress addr : targetsToBeChanged) { // potential target must be legal for all targets that we're about to change Target targetInstance = addr.getTarget(copy); - legal &= targetInstance.canTarget(objId, addr.getSpellAbility(copy), game); + legal &= targetInstance.canTarget(actingPlayer.getId(), objId, addr.getSpellAbility(copy), game); if (!legal) { break; } diff --git a/Mage/src/main/java/mage/util/TargetAddress.java b/Mage/src/main/java/mage/util/TargetAddress.java index e4e89d1832..57bdddc23b 100644 --- a/Mage/src/main/java/mage/util/TargetAddress.java +++ b/Mage/src/main/java/mage/util/TargetAddress.java @@ -28,6 +28,7 @@ package mage.util; import java.util.Iterator; +import java.util.Objects; import java.util.UUID; import mage.abilities.Mode; import mage.abilities.Modes; @@ -59,6 +60,7 @@ public class TargetAddress { this.card = card; } + @Override public Iterator iterator() { return new TargetAddressIterator(card); } @@ -87,10 +89,12 @@ public class TargetAddress { calcNext(); } + @Override public boolean hasNext() { return lastTargetIndex != null; } + @Override public TargetAddress next() { TargetAddress ret = new TargetAddress(lastSpellAbilityIndex, lastMode, @@ -100,6 +104,7 @@ public class TargetAddress { } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -188,4 +193,25 @@ public class TargetAddress { public int hashCode() { return spellAbilityIndex ^ mode.hashCode() ^ targetIndex; } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final TargetAddress other = (TargetAddress) obj; + if (this.spellAbilityIndex != other.spellAbilityIndex) { + return false; + } + if (this.targetIndex != other.targetIndex) { + return false; + } + return Objects.equals(this.mode, other.mode); + } }