From ec9daf26a8021106b898dc6112078ed27a56c216 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 20 Oct 2015 12:45:31 +0300 Subject: [PATCH 1/7] Fix Thirst's card number --- Mage.Sets/src/mage/sets/mirage/Thirst.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/mirage/Thirst.java b/Mage.Sets/src/mage/sets/mirage/Thirst.java index db2df103b70..bf3c47fce7b 100644 --- a/Mage.Sets/src/mage/sets/mirage/Thirst.java +++ b/Mage.Sets/src/mage/sets/mirage/Thirst.java @@ -53,7 +53,7 @@ import mage.target.common.TargetCreaturePermanent; public class Thirst extends CardImpl { public Thirst(UUID ownerId) { - super(ownerId, 104, "Thirst", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + super(ownerId, 99, "Thirst", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); this.expansionSetCode = "MIR"; this.subtype.add("Aura"); From a62222dab1d80decde59ef6cc4adc53921fcea06 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 20 Oct 2015 12:46:10 +0300 Subject: [PATCH 2/7] Extract SacrificeIfCastAtInstantTimeTriggeredAbility from Necromancy to its own file. Implement the cycle of Auras from Mirage that use it. --- .../src/mage/sets/mirage/ArmorOfThorns.java | 89 +++++++++++++++++++ .../src/mage/sets/mirage/GraveServitude.java | 87 ++++++++++++++++++ .../mage/sets/mirage/LightningReflexes.java | 87 ++++++++++++++++++ Mage.Sets/src/mage/sets/mirage/Soar.java | 87 ++++++++++++++++++ .../src/mage/sets/mirage/WardOfLights.java | 83 +++++++++++++++++ .../sets/vintagemasters/ArmorOfThorns.java | 52 +++++++++++ .../src/mage/sets/visions/Necromancy.java | 85 ++---------------- ...ceIfCastAtInstantTimeTriggeredAbility.java | 82 +++++++++++++++++ 8 files changed, 572 insertions(+), 80 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/mirage/ArmorOfThorns.java create mode 100644 Mage.Sets/src/mage/sets/mirage/GraveServitude.java create mode 100644 Mage.Sets/src/mage/sets/mirage/LightningReflexes.java create mode 100644 Mage.Sets/src/mage/sets/mirage/Soar.java create mode 100644 Mage.Sets/src/mage/sets/mirage/WardOfLights.java create mode 100644 Mage.Sets/src/mage/sets/vintagemasters/ArmorOfThorns.java create mode 100644 Mage/src/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java diff --git a/Mage.Sets/src/mage/sets/mirage/ArmorOfThorns.java b/Mage.Sets/src/mage/sets/mirage/ArmorOfThorns.java new file mode 100644 index 00000000000..5fff4649089 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/ArmorOfThorns.java @@ -0,0 +1,89 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirage; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.keyword.EnchantAbility; +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.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class ArmorOfThorns extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public ArmorOfThorns(UUID ownerId) { + super(ownerId, 104, "Armor of Thorns", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Aura"); + + // You may cast Armor of Thorns as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // Enchant nonblack creature + TargetPermanent auraTarget = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature gets +2/+2. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); + } + + public ArmorOfThorns(final ArmorOfThorns card) { + super(card); + } + + @Override + public ArmorOfThorns copy() { + return new ArmorOfThorns(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/GraveServitude.java b/Mage.Sets/src/mage/sets/mirage/GraveServitude.java new file mode 100644 index 00000000000..e162e3aae2d --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/GraveServitude.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.mirage; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.SetCardColorAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class GraveServitude extends CardImpl { + + public GraveServitude(UUID ownerId) { + super(ownerId, 24, "Grave Servitude", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Aura"); + + // You may cast Grave Servitude as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // 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 gets +3/-1 and is black. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, -1, Duration.WhileOnBattlefield)); + Effect effect = new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.AURA); + effect.setText("and is black"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public GraveServitude(final GraveServitude card) { + super(card); + } + + @Override + public GraveServitude copy() { + return new GraveServitude(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/LightningReflexes.java b/Mage.Sets/src/mage/sets/mirage/LightningReflexes.java new file mode 100644 index 00000000000..627c87926b3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/LightningReflexes.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.mirage; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class LightningReflexes extends CardImpl { + + public LightningReflexes(UUID ownerId) { + super(ownerId, 186, "Lightning Reflexes", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Aura"); + + // You may cast Lightning Reflexes as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // 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 gets +1/+0 and has first strike. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 0, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(FirstStrikeAbility.getInstance(), AttachmentType.AURA); + effect.setText("and has first strike"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public LightningReflexes(final LightningReflexes card) { + super(card); + } + + @Override + public LightningReflexes copy() { + return new LightningReflexes(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/Soar.java b/Mage.Sets/src/mage/sets/mirage/Soar.java new file mode 100644 index 00000000000..bcdd172fccd --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/Soar.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.mirage; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class Soar extends CardImpl { + + public Soar(UUID ownerId) { + super(ownerId, 93, "Soar", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Aura"); + + // You may cast Soar as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // 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 gets +0/+1 and has flying. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0, 1, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA); + effect.setText("and has flying"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public Soar(final Soar card) { + super(card); + } + + @Override + public Soar copy() { + return new Soar(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/WardOfLights.java b/Mage.Sets/src/mage/sets/mirage/WardOfLights.java new file mode 100644 index 00000000000..844d498701f --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/WardOfLights.java @@ -0,0 +1,83 @@ +/* + * 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.mirage; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.keyword.ProtectionChosenColorAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +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.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class WardOfLights extends CardImpl { + + public WardOfLights(UUID ownerId) { + super(ownerId, 251, "Ward of Lights", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Aura"); + + // You may cast Ward of Lights as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // As Ward of Lights enters the battlefield, choose a color. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseColorEffect(Outcome.Benefit))); + // Enchanted creature has protection from the chosen color. This effect doesn't remove Ward of Lights. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ProtectionChosenColorAttachedEffect(true))); + } + + public WardOfLights(final WardOfLights card) { + super(card); + } + + @Override + public WardOfLights copy() { + return new WardOfLights(this); + } +} diff --git a/Mage.Sets/src/mage/sets/vintagemasters/ArmorOfThorns.java b/Mage.Sets/src/mage/sets/vintagemasters/ArmorOfThorns.java new file mode 100644 index 00000000000..5935dd45b28 --- /dev/null +++ b/Mage.Sets/src/mage/sets/vintagemasters/ArmorOfThorns.java @@ -0,0 +1,52 @@ +/* + * 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.vintagemasters; + +import java.util.UUID; + +/** + * + * @author LoneFox + */ +public class ArmorOfThorns extends mage.sets.mirage.ArmorOfThorns { + + public ArmorOfThorns(UUID ownerId) { + super(ownerId); + this.cardNumber = 194; + this.expansionSetCode = "VMA"; + } + + public ArmorOfThorns(final ArmorOfThorns card) { + super(card); + } + + @Override + public ArmorOfThorns copy() { + return new ArmorOfThorns(this); + } +} diff --git a/Mage.Sets/src/mage/sets/visions/Necromancy.java b/Mage.Sets/src/mage/sets/visions/Necromancy.java index 89910cb3ab9..13d1bb76169 100644 --- a/Mage.Sets/src/mage/sets/visions/Necromancy.java +++ b/Mage.Sets/src/mage/sets/visions/Necromancy.java @@ -30,23 +30,19 @@ package mage.sets.visions; import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.LeavesBattlefieldTriggeredAbility; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextCleanupDelayedTriggeredAbility; import mage.abilities.condition.common.SourceOnBattlefieldCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; -import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; -import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; import mage.abilities.effects.common.continuous.SourceEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.DependencyType; import mage.constants.Duration; @@ -59,10 +55,7 @@ import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.PermanentIdPredicate; 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.target.common.TargetCardInGraveyard; @@ -79,8 +72,8 @@ public class Necromancy extends CardImpl { this.expansionSetCode = "VIS"; // You may cast Necromancy as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. - this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastSourceAsThoughItHadFlashEffect(this, Duration.EndOfGame, true))); - this.addAbility(new CastAtInstantTimeTriggeredAbility()); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); // When Necromancy enters the battlefield, if it's on the battlefield, it becomes an Aura with "enchant creature put onto the battlefield with Necromancy." // Put target creature card from a graveyard onto the battlefield under your control and attach Necromancy to it. @@ -104,75 +97,6 @@ public class Necromancy extends CardImpl { } } -class CastSourceAsThoughItHadFlashEffect extends AsThoughEffectImpl { - - private final boolean sacrificeIfCastAsInstant; - - public CastSourceAsThoughItHadFlashEffect(Card card, Duration duration, boolean sacrificeIfCastAsInstant) { - super(AsThoughEffectType.CAST_AS_INSTANT, duration, Outcome.Benefit); - this.sacrificeIfCastAsInstant = sacrificeIfCastAsInstant; - staticText = "You may cast {this} as though it had flash"; - } - - public CastSourceAsThoughItHadFlashEffect(final CastSourceAsThoughItHadFlashEffect effect) { - super(effect); - this.sacrificeIfCastAsInstant = effect.sacrificeIfCastAsInstant; - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public CastSourceAsThoughItHadFlashEffect copy() { - return new CastSourceAsThoughItHadFlashEffect(this); - } - - @Override - public boolean applies(UUID affectedSpellId, Ability source, UUID affectedControllerId, Game game) { - return source.getSourceId().equals(affectedSpellId); - } - -} - -class CastAtInstantTimeTriggeredAbility extends TriggeredAbilityImpl { - - public CastAtInstantTimeTriggeredAbility() { - super(Zone.STACK, new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextCleanupDelayedTriggeredAbility(new SacrificeSourceEffect()))); - } - - public CastAtInstantTimeTriggeredAbility(final CastAtInstantTimeTriggeredAbility ability) { - super(ability); - } - - @Override - public CastAtInstantTimeTriggeredAbility copy() { - return new CastAtInstantTimeTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.SPELL_CAST; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - // The sacrifice occurs only if you cast it using its own ability. If you cast it using some other - // effect (for instance, if it gained flash from Vedalken Orrery), then it won't be sacrificed. - // CHECK - Spell spell = game.getStack().getSpell(event.getTargetId()); - if (spell != null && spell.getSourceId().equals(getSourceId())) { - return !(game.isMainPhase() && game.getActivePlayerId().equals(event.getPlayerId()) && game.getStack().size() == 1); - } - return false; - } - - @Override - public String getRule() { - return "If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step."; - } -} class NecromancyReAttachEffect extends OneShotEffect { @@ -246,6 +170,7 @@ class NecromancyLeavesBattlefieldTriggeredEffect extends OneShotEffect { } } + class NecromancyChangeAbilityEffect extends ContinuousEffectImpl implements SourceEffect { private final static Ability newAbility = new EnchantAbility("creature put onto the battlefield with Necromancy"); diff --git a/Mage/src/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java b/Mage/src/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java new file mode 100644 index 00000000000..6941a1b66b1 --- /dev/null +++ b/Mage/src/mage/abilities/common/SacrificeIfCastAtInstantTimeTriggeredAbility.java @@ -0,0 +1,82 @@ +/* + * 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.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.delayed.AtTheBeginOfNextCleanupDelayedTriggeredAbility; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent.EventType; +import mage.game.events.GameEvent; +import mage.game.stack.Spell; + +/** + * + * @author Lonefox + */ +public class SacrificeIfCastAtInstantTimeTriggeredAbility extends TriggeredAbilityImpl { + + public SacrificeIfCastAtInstantTimeTriggeredAbility() { + super(Zone.STACK, new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextCleanupDelayedTriggeredAbility(new SacrificeSourceEffect()))); + } + + public SacrificeIfCastAtInstantTimeTriggeredAbility(final SacrificeIfCastAtInstantTimeTriggeredAbility ability) { + super(ability); + } + + @Override + public SacrificeIfCastAtInstantTimeTriggeredAbility copy() { + return new SacrificeIfCastAtInstantTimeTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + // The sacrifice occurs only if you cast it using its own ability. If you cast it using some other + // effect (for instance, if it gained flash from Vedalken Orrery), then it won't be sacrificed. + // CHECK + Spell spell = game.getStack().getSpell(event.getTargetId()); + if (spell != null && spell.getSourceId().equals(getSourceId())) { + return !(game.isMainPhase() && game.getActivePlayerId().equals(event.getPlayerId()) && game.getStack().size() == 1); + } + return false; + } + + @Override + public String getRule() { + return "If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step."; + } +} + From 4c75c50082e7fae56b6ae08e8c5b706debfc18b9 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 20 Oct 2015 13:29:04 +0300 Subject: [PATCH 3/7] Implement cards: Mystic Veil, Parapet, Relic Ward, and Spider Climb --- .../src/mage/sets/visions/MysticVeil.java | 82 +++++++++++++++++ Mage.Sets/src/mage/sets/visions/Parapet.java | 66 ++++++++++++++ .../src/mage/sets/visions/RelicWard.java | 80 +++++++++++++++++ .../src/mage/sets/visions/SpiderClimb.java | 87 +++++++++++++++++++ 4 files changed, 315 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/visions/MysticVeil.java create mode 100644 Mage.Sets/src/mage/sets/visions/Parapet.java create mode 100644 Mage.Sets/src/mage/sets/visions/RelicWard.java create mode 100644 Mage.Sets/src/mage/sets/visions/SpiderClimb.java diff --git a/Mage.Sets/src/mage/sets/visions/MysticVeil.java b/Mage.Sets/src/mage/sets/visions/MysticVeil.java new file mode 100644 index 00000000000..bfcb4210d71 --- /dev/null +++ b/Mage.Sets/src/mage/sets/visions/MysticVeil.java @@ -0,0 +1,82 @@ +/* + * 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.visions; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + + * + * @author LoneFox + */ +public class MysticVeil extends CardImpl { + + public MysticVeil(UUID ownerId) { + super(ownerId, 38, "Mystic Veil", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + this.expansionSetCode = "VIS"; + this.subtype.add("Aura"); + + // You may cast Mystic Veil as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted creature has shroud. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.AURA))); + } + + public MysticVeil(final MysticVeil card) { + super(card); + } + + @Override + public MysticVeil copy() { + return new MysticVeil(this); + } +} diff --git a/Mage.Sets/src/mage/sets/visions/Parapet.java b/Mage.Sets/src/mage/sets/visions/Parapet.java new file mode 100644 index 00000000000..d05703ebca6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/visions/Parapet.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.visions; + +import java.util.UUID; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class Parapet extends CardImpl { + + public Parapet(UUID ownerId) { + super(ownerId, 114, "Parapet", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + this.expansionSetCode = "VIS"; + + // You may cast Parapet as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // Creatures you control get +0/+1. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(0, 1, Duration.WhileOnBattlefield))); + } + + public Parapet(final Parapet card) { + super(card); + } + + @Override + public Parapet copy() { + return new Parapet(this); + } +} diff --git a/Mage.Sets/src/mage/sets/visions/RelicWard.java b/Mage.Sets/src/mage/sets/visions/RelicWard.java new file mode 100644 index 00000000000..122cf167927 --- /dev/null +++ b/Mage.Sets/src/mage/sets/visions/RelicWard.java @@ -0,0 +1,80 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.visions; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; +/** + * + * @author LoneFox + */ +public class RelicWard extends CardImpl { + + public RelicWard(UUID ownerId) { + super(ownerId, 116, "Relic Ward", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}"); + this.expansionSetCode = "VIS"; + this.subtype.add("Aura"); + + // You may cast Relic Ward as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // Enchant artifact + TargetPermanent auraTarget = new TargetArtifactPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Enchanted artifact has shroud. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ShroudAbility.getInstance(), AttachmentType.AURA))); + } + + public RelicWard(final RelicWard card) { + super(card); + } + + @Override + public RelicWard copy() { + return new RelicWard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/visions/SpiderClimb.java b/Mage.Sets/src/mage/sets/visions/SpiderClimb.java new file mode 100644 index 00000000000..bdccf5912c6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/visions/SpiderClimb.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.visions; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SacrificeIfCastAtInstantTimeTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostEnchantedEffect; +import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.ReachAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class SpiderClimb extends CardImpl { + + public SpiderClimb(UUID ownerId) { + super(ownerId, 70, "Spider Climb", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + this.expansionSetCode = "VIS"; + this.subtype.add("Aura"); + + // You may cast Spider Climb as though it had flash. If you cast it any time a sorcery couldn't have been cast, the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step. + this.addAbility(new SimpleStaticAbility(Zone.ALL, new CastAsThoughItHadFlashSourceEffect(Duration.EndOfGame))); + this.addAbility(new SacrificeIfCastAtInstantTimeTriggeredAbility()); + // 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 gets +0/+3 and has reach. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0, 3, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(ReachAbility.getInstance(), AttachmentType.AURA); + effect.setText("and has reach"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public SpiderClimb(final SpiderClimb card) { + super(card); + } + + @Override + public SpiderClimb copy() { + return new SpiderClimb(this); + } +} From bab173e8672f46329ceb1f4df325fffbcd26b7df Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 20 Oct 2015 13:40:16 +0300 Subject: [PATCH 4/7] Fix Call to Serve: Add missing non-black filter (was coded but not applied) and combine effects to one ability. --- .../mage/sets/avacynrestored/CallToServe.java | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/sets/avacynrestored/CallToServe.java b/Mage.Sets/src/mage/sets/avacynrestored/CallToServe.java index a0453080103..72e5a85d72f 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/CallToServe.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/CallToServe.java @@ -28,11 +28,10 @@ package mage.sets.avacynrestored; import java.util.UUID; - -import mage.constants.*; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.AddCardSubtypeAttachedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; @@ -40,6 +39,12 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; @@ -51,6 +56,7 @@ import mage.target.common.TargetCreaturePermanent; * @author Loki */ public class CallToServe extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); static { @@ -62,18 +68,22 @@ public class CallToServe extends CardImpl { this.expansionSetCode = "AVR"; this.subtype.add("Aura"); - // Enchant nonblack creature - TargetPermanent auraTarget = new TargetCreaturePermanent(); + TargetPermanent auraTarget = new TargetCreaturePermanent(filter); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // Enchanted creature gets +1/+2, has flying, and is an Angel in addition to its other types. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 2, Duration.WhileOnBattlefield))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA))); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AddCardSubtypeAttachedEffect("Angel", Duration.WhileOnBattlefield, AttachmentType.AURA))); + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 2, Duration.WhileOnBattlefield)); + Effect effect = new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA); + effect.setText(", has flying"); + ability.addEffect(effect); + effect = new AddCardSubtypeAttachedEffect("Angel", Duration.WhileOnBattlefield, AttachmentType.AURA); + effect.setText(", and is an Angel in addition to its other types"); + ability.addEffect(effect); + this.addAbility(ability); } public CallToServe(final CallToServe card) { From 67c64bbe9ef42dcd4b96156422e883aeab92b3f0 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 20 Oct 2015 14:19:04 +0300 Subject: [PATCH 5/7] Fix some tooltip texts --- .../mage/sets/fifthedition/Shatterstorm.java | 2 +- .../mage/sets/fourthedition/EbonyHorse.java | 23 +++++++++++++------ .../src/mage/sets/iceage/FanaticalFever.java | 9 ++++++-- .../mage/sets/iceage/OrcishCannoneers.java | 5 +++- Mage.Sets/src/mage/sets/iceage/SnowHound.java | 4 ++-- .../mage/sets/masterseditionii/TimeBomb.java | 7 +++--- 6 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Mage.Sets/src/mage/sets/fifthedition/Shatterstorm.java b/Mage.Sets/src/mage/sets/fifthedition/Shatterstorm.java index 8b7a9885776..ef14823483b 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/Shatterstorm.java +++ b/Mage.Sets/src/mage/sets/fifthedition/Shatterstorm.java @@ -46,7 +46,7 @@ public class Shatterstorm extends CardImpl { // Destroy all artifacts. They can't be regenerated. - this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterArtifactPermanent(), true)); + this.getSpellAbility().addEffect(new DestroyAllEffect(new FilterArtifactPermanent("artifacts"), true)); } public Shatterstorm(final Shatterstorm card) { diff --git a/Mage.Sets/src/mage/sets/fourthedition/EbonyHorse.java b/Mage.Sets/src/mage/sets/fourthedition/EbonyHorse.java index 943eb139161..c2601f3b37e 100644 --- a/Mage.Sets/src/mage/sets/fourthedition/EbonyHorse.java +++ b/Mage.Sets/src/mage/sets/fourthedition/EbonyHorse.java @@ -33,13 +33,19 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.common.*; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventCombatDamageBySourceEffect; +import mage.abilities.effects.common.PreventCombatDamageToSourceEffect; +import mage.abilities.effects.common.UntapTargetEffect; import mage.cards.CardImpl; -import mage.constants.*; +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.AttackingPredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.target.Target; import mage.target.common.TargetCreaturePermanent; /** @@ -61,10 +67,13 @@ public class EbonyHorse extends CardImpl { // {2}, {tap}: Untap target attacking creature you control. Prevent all combat damage that would be dealt to and dealt by that creature this turn. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapTargetEffect(), new GenericManaCost(2)); ability.addCost(new TapSourceCost()); - ability.addEffect(new PreventCombatDamageToSourceEffect(Duration.EndOfTurn)); - ability.addEffect(new PreventCombatDamageBySourceEffect(Duration.EndOfTurn)); - Target target = new TargetCreaturePermanent(filter); - ability.addTarget(target); + Effect effect = new PreventCombatDamageToSourceEffect(Duration.EndOfTurn); + effect.setText("Prevent all combat damage that would be dealt to"); + ability.addEffect(effect); + effect = new PreventCombatDamageBySourceEffect(Duration.EndOfTurn); + effect.setText("and dealt by that creature this turn"); + ability.addEffect(effect); + ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/iceage/FanaticalFever.java b/Mage.Sets/src/mage/sets/iceage/FanaticalFever.java index 82ecfeef4ca..c6e4ebcab53 100644 --- a/Mage.Sets/src/mage/sets/iceage/FanaticalFever.java +++ b/Mage.Sets/src/mage/sets/iceage/FanaticalFever.java @@ -28,6 +28,7 @@ package mage.sets.iceage; import java.util.UUID; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.TrampleAbility; @@ -48,8 +49,12 @@ public class FanaticalFever extends CardImpl { this.expansionSetCode = "ICE"; // Target creature gets +3/+0 and gains trample until end of turn. - this.getSpellAbility().addEffect(new BoostTargetEffect(3, 0, Duration.EndOfTurn)); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)); + Effect effect = new BoostTargetEffect(3, 0, Duration.EndOfTurn); + effect.setText("Target creature gets +3/+0"); + 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()); } diff --git a/Mage.Sets/src/mage/sets/iceage/OrcishCannoneers.java b/Mage.Sets/src/mage/sets/iceage/OrcishCannoneers.java index ef0cebf67d2..644e2eeb821 100644 --- a/Mage.Sets/src/mage/sets/iceage/OrcishCannoneers.java +++ b/Mage.Sets/src/mage/sets/iceage/OrcishCannoneers.java @@ -32,6 +32,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageControllerEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.cards.CardImpl; @@ -57,7 +58,9 @@ public class OrcishCannoneers extends CardImpl { // {tap}: Orcish Cannoneers deals 2 damage to target creature or player and 3 damage to you. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new TapSourceCost()); ability.addTarget(new TargetCreatureOrPlayer()); - ability.addEffect(new DamageControllerEffect(3)); + Effect effect = new DamageControllerEffect(3); + effect.setText("and 3 damage to you"); + ability.addEffect(effect); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/iceage/SnowHound.java b/Mage.Sets/src/mage/sets/iceage/SnowHound.java index fb95474fb9c..bd828411862 100644 --- a/Mage.Sets/src/mage/sets/iceage/SnowHound.java +++ b/Mage.Sets/src/mage/sets/iceage/SnowHound.java @@ -67,11 +67,11 @@ public class SnowHound extends CardImpl { // {1}, {tap}: Return Snow Hound and target green or blue creature you control to their owner's hand. Effect effect = new ReturnToHandSourceEffect(true); - effect.setText("Return Snow Hound"); + effect.setText("Return Snow Hound"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}")); ability.addCost(new TapSourceCost()); effect = new ReturnToHandTargetEffect(); - effect.setText("and green or blue creature you control to their owners' hands"); + effect.setText("and target green or blue creature you control to their owners' hands"); ability.addTarget(new TargetControlledCreaturePermanent(filter)); ability.addEffect(effect); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/masterseditionii/TimeBomb.java b/Mage.Sets/src/mage/sets/masterseditionii/TimeBomb.java index d71d59a7ea7..1777a4ad542 100644 --- a/Mage.Sets/src/mage/sets/masterseditionii/TimeBomb.java +++ b/Mage.Sets/src/mage/sets/masterseditionii/TimeBomb.java @@ -35,6 +35,7 @@ import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.dynamicvalue.common.CountersCount; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.DamageEverythingEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; @@ -59,9 +60,9 @@ public class TimeBomb extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.TIME.createInstance(), true), TargetController.YOU, false)); // {1}, {tap}, Sacrifice Time Bomb: Time Bomb deals damage equal to the number of time counters on it to each creature and each player. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new DamageEverythingEffect(new CountersCount(CounterType.TIME), new FilterCreaturePermanent()), - new GenericManaCost(1)); + Effect effect = new DamageEverythingEffect(new CountersCount(CounterType.TIME), new FilterCreaturePermanent()); + effect.setText("{this} deals damage equal to the number of time counters on it to each creature and each player"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1)); ability.addCost(new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); this.addAbility(ability); From 317f18220b19620dfd274c2fb8d753001ccfe992 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Fri, 23 Oct 2015 08:50:32 +0300 Subject: [PATCH 6/7] Implement cards: Elvish Vanguard, Lys Alana Scarblade, Prowess of the Fair, and Symbiotic Elf --- .../mage/sets/lorwyn/LysAlanaScarblade.java | 90 +++++++++++++++++++ .../mage/sets/lorwyn/ProwessOfTheFair.java | 75 ++++++++++++++++ .../mage/sets/onslaught/ElvishVanguard.java | 75 ++++++++++++++++ .../src/mage/sets/onslaught/SymbioticElf.java | 64 +++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/lorwyn/LysAlanaScarblade.java create mode 100644 Mage.Sets/src/mage/sets/lorwyn/ProwessOfTheFair.java create mode 100644 Mage.Sets/src/mage/sets/onslaught/ElvishVanguard.java create mode 100644 Mage.Sets/src/mage/sets/onslaught/SymbioticElf.java diff --git a/Mage.Sets/src/mage/sets/lorwyn/LysAlanaScarblade.java b/Mage.Sets/src/mage/sets/lorwyn/LysAlanaScarblade.java new file mode 100644 index 00000000000..5cdc7019042 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/LysAlanaScarblade.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.DiscardCardCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.SignInversionDynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class LysAlanaScarblade extends CardImpl { + + private static final FilterControlledPermanent filter1 = new FilterControlledPermanent(); + private static final FilterCard filter2 = new FilterCard("an Elf card"); + + static { + filter1.add(new SubtypePredicate("Elf")); + filter2.add(new SubtypePredicate("Elf")); + } + + public LysAlanaScarblade(UUID ownerId) { + super(ownerId, 122, "Lys Alana Scarblade", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Elf"); + this.subtype.add("Assassin"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {tap}, Discard an Elf card: Target creature gets -X/-X until end of turn, where X is the number of Elves you control. + SignInversionDynamicValue count = new SignInversionDynamicValue(new PermanentsOnBattlefieldCount(filter1)); + Effect effect = new BoostTargetEffect(count, count, Duration.EndOfTurn); + effect.setText("target creature gets -X/-X until end of turn, where X is the number of Elves you control"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); + ability.addCost(new DiscardCardCost(filter2)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public LysAlanaScarblade(final LysAlanaScarblade card) { + super(card); + } + + @Override + public LysAlanaScarblade copy() { + return new LysAlanaScarblade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/ProwessOfTheFair.java b/Mage.Sets/src/mage/sets/lorwyn/ProwessOfTheFair.java new file mode 100644 index 00000000000..09eb350a4b8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/ProwessOfTheFair.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.lorwyn; + +import java.util.UUID; +import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.permanent.token.ElfToken; + +/** + * + * @author LoneFox + */ +public class ProwessOfTheFair extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another nontoken Elf"); + + static { + filter.add(new SubtypePredicate("Elf")); + filter.add(new AnotherPredicate()); + filter.add(Predicates.not(new TokenPredicate())); + } + + public ProwessOfTheFair(UUID ownerId) { + super(ownerId, 136, "Prowess of the Fair", Rarity.UNCOMMON, new CardType[]{CardType.TRIBAL, CardType.ENCHANTMENT}, "{1}{B}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Elf"); + + // Whenever another nontoken Elf is put into your graveyard from the battlefield, you may put a 1/1 green Elf Warrior creature token onto the battlefield. + this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new CreateTokenEffect(new ElfToken()), + true, filter, false, true)); + } + + public ProwessOfTheFair(final ProwessOfTheFair card) { + super(card); + } + + @Override + public ProwessOfTheFair copy() { + return new ProwessOfTheFair(this); + } +} diff --git a/Mage.Sets/src/mage/sets/onslaught/ElvishVanguard.java b/Mage.Sets/src/mage/sets/onslaught/ElvishVanguard.java new file mode 100644 index 00000000000..1f876e83614 --- /dev/null +++ b/Mage.Sets/src/mage/sets/onslaught/ElvishVanguard.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.onslaught; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LoneFox + */ +public class ElvishVanguard extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("another Elf"); + + static { + filter.add(new SubtypePredicate("Elf")); + filter.add(new AnotherPredicate()); + } + + public ElvishVanguard(UUID ownerId) { + super(ownerId, 259, "Elvish Vanguard", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "ONS"; + this.subtype.add("Elf"); + this.subtype.add("Warrior"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever another Elf enters the battlefield, put a +1/+1 counter on Elvish Vanguard. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter)); + } + + public ElvishVanguard(final ElvishVanguard card) { + super(card); + } + + @Override + public ElvishVanguard copy() { + return new ElvishVanguard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/onslaught/SymbioticElf.java b/Mage.Sets/src/mage/sets/onslaught/SymbioticElf.java new file mode 100644 index 00000000000..4ad72947189 --- /dev/null +++ b/Mage.Sets/src/mage/sets/onslaught/SymbioticElf.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.onslaught; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.game.permanent.token.InsectToken; + +/** + * + * @author LoneFox + */ +public class SymbioticElf extends CardImpl { + + public SymbioticElf(UUID ownerId) { + super(ownerId, 288, "Symbiotic Elf", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.expansionSetCode = "ONS"; + this.subtype.add("Elf"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Symbiotic Elf dies, put two 1/1 green Insect creature tokens onto the battlefield. + this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new InsectToken(), 2))); + } + + public SymbioticElf(final SymbioticElf card) { + super(card); + } + + @Override + public SymbioticElf copy() { + return new SymbioticElf(this); + } +} From 4b18825c96e0f418cc393eaa9c8255a42e94c9a1 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Sat, 24 Oct 2015 07:32:03 +0300 Subject: [PATCH 7/7] Implement cards: Cenn's Heir, Kinsbaile Borderguard, Kithkin Harbinger, and Kithkin Mourncaller Note: Currently Kithkin Mourncaller does not work due to missing LKI about attacking. --- Mage.Sets/src/mage/sets/lorwyn/CennsHeir.java | 77 ++++++++++++ .../mage/sets/lorwyn/KithkinHarbinger.java | 73 +++++++++++ .../mage/sets/lorwyn/KithkinMourncaller.java | 74 +++++++++++ .../morningtide/KinsbaileBorderguard.java | 117 ++++++++++++++++++ 4 files changed, 341 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/lorwyn/CennsHeir.java create mode 100644 Mage.Sets/src/mage/sets/lorwyn/KithkinHarbinger.java create mode 100644 Mage.Sets/src/mage/sets/lorwyn/KithkinMourncaller.java create mode 100644 Mage.Sets/src/mage/sets/morningtide/KinsbaileBorderguard.java diff --git a/Mage.Sets/src/mage/sets/lorwyn/CennsHeir.java b/Mage.Sets/src/mage/sets/lorwyn/CennsHeir.java new file mode 100644 index 00000000000..558b973c1ab --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/CennsHeir.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.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LoneFox + */ +public class CennsHeir extends CardImpl { + + private static final FilterAttackingCreature filter = new FilterAttackingCreature("other attacking Kithkin"); + + static { + filter.add(new SubtypePredicate("Kithkin")); + filter.add(new AnotherPredicate()); + } + + public CennsHeir(UUID ownerId) { + super(ownerId, 8, "Cenn's Heir", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Kithkin"); + this.subtype.add("Soldier"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Cenn's Heir attacks, it gets +1/+1 until end of turn for each other attacking Kithkin. + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new AttacksTriggeredAbility(new BoostSourceEffect(count, count, Duration.EndOfTurn, true), false)); + } + + public CennsHeir(final CennsHeir card) { + super(card); + } + + @Override + public CennsHeir copy() { + return new CennsHeir(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/KithkinHarbinger.java b/Mage.Sets/src/mage/sets/lorwyn/KithkinHarbinger.java new file mode 100644 index 00000000000..3ff7e1a031f --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/KithkinHarbinger.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.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LoneFox + */ +public class KithkinHarbinger extends CardImpl { + + public static final FilterCard filter = new FilterCard("Kithkin card"); + + static { + filter.add(new SubtypePredicate("Kithkin")); + } + + public KithkinHarbinger(UUID ownerId) { + super(ownerId, 26, "Kithkin Harbinger", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Kithkin"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // When Kithkin Harbinger enters the battlefield, you may search your library for a Kithkin card, reveal it, then shuffle your library and put that card on top of it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(filter), true, true), true)); + } + + public KithkinHarbinger(final KithkinHarbinger card) { + super(card); + } + + @Override + public KithkinHarbinger copy() { + return new KithkinHarbinger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/KithkinMourncaller.java b/Mage.Sets/src/mage/sets/lorwyn/KithkinMourncaller.java new file mode 100644 index 00000000000..76267304715 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/KithkinMourncaller.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.lorwyn; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.PutIntoGraveFromBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterAttackingCreature; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + */ +public class KithkinMourncaller extends CardImpl { + + private static final FilterAttackingCreature filter = new FilterAttackingCreature("an attacking Kithkin or Elf"); + + static { + filter.add(Predicates.or(new SubtypePredicate("Kithkin"), new SubtypePredicate("Elf"))); + } + + public KithkinMourncaller(UUID ownerId) { + super(ownerId, 224, "Kithkin Mourncaller", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Kithkin"); + this.subtype.add("Scout"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever an attacking Kithkin or Elf is put into your graveyard from the battlefield, you may draw a card. + this.addAbility(new PutIntoGraveFromBattlefieldAllTriggeredAbility(new DrawCardSourceControllerEffect(1), + true, filter, false, true)); + } + + public KithkinMourncaller(final KithkinMourncaller card) { + super(card); + } + + @Override + public KithkinMourncaller copy() { + return new KithkinMourncaller(this); + } +} diff --git a/Mage.Sets/src/mage/sets/morningtide/KinsbaileBorderguard.java b/Mage.Sets/src/mage/sets/morningtide/KinsbaileBorderguard.java new file mode 100644 index 00000000000..5080aa2baa5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/morningtide/KinsbaileBorderguard.java @@ -0,0 +1,117 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.morningtide; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.KithkinToken; + +/** + * + * @author LoneFox + */ +public class KinsbaileBorderguard extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(new SubtypePredicate("Kithkin")); + } + + public KinsbaileBorderguard(UUID ownerId) { + super(ownerId, 14, "Kinsbaile Borderguard", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}{W}"); + this.expansionSetCode = "MOR"; + this.subtype.add("Kithkin"); + this.subtype.add("Soldier"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Kinsbaile Borderguard enters the battlefield with a +1/+1 counter on it for each other Kithkin you control. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), + new PermanentsOnBattlefieldCount(filter), true), "with a +1/+1 counter on it for each other Kithkin you control")); + // When Kinsbaile Borderguard dies, put a 1/1 white Kithkin Soldier creature token onto the battlefield for each counter on it. + this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new KithkinToken(), new AllCountersCount()))); + } + + public KinsbaileBorderguard(final KinsbaileBorderguard card) { + super(card); + } + + @Override + public KinsbaileBorderguard copy() { + return new KinsbaileBorderguard(this); + } +} + +class AllCountersCount implements DynamicValue { + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(sourceAbility.getSourceId()); + if(sourcePermanent != null) { + int total = 0; + for(Counter counter : sourcePermanent.getCounters().values()) { + total += counter.getCount(); + } + return total; + } + return 0; + } + + @Override + public DynamicValue copy() { + return new AllCountersCount(); + } + + @Override + public String getMessage() { + return "for each counter on it"; + } + + @Override + public String toString() { + return "1"; + } +}