From 2c222c4d7bab592615a3a23885ed15e6f93189cd Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 14 Dec 2015 11:24:17 +0200 Subject: [PATCH 1/8] Implement cards: Dross Harvester, Goblin Dirigible, Goblin War Wagon, and Woebearer --- .../mage/sets/mirrodin/DrossHarvester.java | 81 +++++++++++++++++++ .../mage/sets/mirrodin/GoblinDirigible.java | 75 +++++++++++++++++ .../mage/sets/mirrodin/GoblinWarWagon.java | 72 +++++++++++++++++ .../src/mage/sets/mirrodin/Woebearer.java | 71 ++++++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mirrodin/DrossHarvester.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/GoblinDirigible.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/GoblinWarWagon.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/Woebearer.java diff --git a/Mage.Sets/src/mage/sets/mirrodin/DrossHarvester.java b/Mage.Sets/src/mage/sets/mirrodin/DrossHarvester.java new file mode 100644 index 0000000000..677f3bbb3a --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/DrossHarvester.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + */ +public class DrossHarvester extends CardImpl { + + private static final FilterCard filter = new FilterCard("white"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public DrossHarvester(UUID ownerId) { + super(ownerId, 63, "Dross Harvester", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Horror"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Protection from white + this.addAbility(new ProtectionAbility(filter)); + // At the beginning of your end step, you lose 4 life. + this.addAbility(new BeginningOfEndStepTriggeredAbility(new LoseLifeSourceControllerEffect(4), + TargetController.YOU, false)); + // Whenever a creature dies, you gain 2 life. + this.addAbility(new DiesCreatureTriggeredAbility(new GainLifeEffect(2), false)); + } + + public DrossHarvester(final DrossHarvester card) { + super(card); + } + + @java.lang.Override + public DrossHarvester copy() { + return new DrossHarvester(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/GoblinDirigible.java b/Mage.Sets/src/mage/sets/mirrodin/GoblinDirigible.java new file mode 100644 index 0000000000..e69ec072b4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/GoblinDirigible.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.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class GoblinDirigible extends CardImpl { + + public GoblinDirigible(UUID ownerId) { + super(ownerId, 177, "Goblin Dirigible", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Construct"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Goblin Dirigible doesn't untap during your untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); + // At the beginning of your upkeep, you may pay {4}. If you do, untap Goblin Dirigible. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DoIfCostPaid( + new UntapSourceEffect(), new ManaCostsImpl("{4}")), TargetController.YOU, false)); + } + + public GoblinDirigible(final GoblinDirigible card) { + super(card); + } + + @java.lang.Override + public GoblinDirigible copy() { + return new GoblinDirigible(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/GoblinWarWagon.java b/Mage.Sets/src/mage/sets/mirrodin/GoblinWarWagon.java new file mode 100644 index 0000000000..e36bc2639f --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/GoblinWarWagon.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect; +import mage.abilities.effects.common.UntapSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class GoblinWarWagon extends CardImpl { + + public GoblinWarWagon(UUID ownerId) { + super(ownerId, 179, "Goblin War Wagon", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Juggernaut"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Goblin War Wagon doesn't untap during your untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepSourceEffect())); + // At the beginning of your upkeep, you may pay {2}. If you do, untap Goblin War Wagon. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DoIfCostPaid( + new UntapSourceEffect(), new ManaCostsImpl("{2}")), TargetController.YOU, false)); + } + + public GoblinWarWagon(final GoblinWarWagon card) { + super(card); + } + + @java.lang.Override + public GoblinWarWagon copy() { + return new GoblinWarWagon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/Woebearer.java b/Mage.Sets/src/mage/sets/mirrodin/Woebearer.java new file mode 100644 index 0000000000..550671e1ce --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/Woebearer.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.FearAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LoneFox + */ +public class Woebearer extends CardImpl { + + public Woebearer(UUID ownerId) { + super(ownerId, 83, "Woebearer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{B}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Zombie"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Fear + this.addAbility(FearAbility.getInstance()); + // Whenever Woebearer deals combat damage to a player, you may return target creature card from your graveyard to your hand. + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandTargetEffect(), true); + ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard"))); + this.addAbility(ability); + } + + public Woebearer(final Woebearer card) { + super(card); + } + + @java.lang.Override + public Woebearer copy() { + return new Woebearer(this); + } +} From 6106bbe7dace9e190802a094b000ef7de76c6fee Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 14 Dec 2015 12:07:24 +0200 Subject: [PATCH 2/8] Implement cards: Domineer, Granite Shard, Heartwood Shard, and Irradiate --- .../src/mage/sets/mirrodin/Domineer.java | 81 +++++++++++++++++++ .../src/mage/sets/mirrodin/GraniteShard.java | 71 ++++++++++++++++ .../mage/sets/mirrodin/HeartwoodShard.java | 75 +++++++++++++++++ .../src/mage/sets/mirrodin/Irradiate.java | 64 +++++++++++++++ 4 files changed, 291 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mirrodin/Domineer.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/GraniteShard.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/HeartwoodShard.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/Irradiate.java diff --git a/Mage.Sets/src/mage/sets/mirrodin/Domineer.java b/Mage.Sets/src/mage/sets/mirrodin/Domineer.java new file mode 100644 index 0000000000..ea9388e1ca --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/Domineer.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.ControlEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class Domineer extends CardImpl { + + final static FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creature"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public Domineer(UUID ownerId) { + super(ownerId, 33, "Domineer", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}{U}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Aura"); + + // Enchant artifact creature + TargetPermanent auraTarget = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // You control enchanted artifact creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + } + + public Domineer(final Domineer card) { + super(card); + } + + @java.lang.Override + public Domineer copy() { + return new Domineer(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/GraniteShard.java b/Mage.Sets/src/mage/sets/mirrodin/GraniteShard.java new file mode 100644 index 0000000000..cce7e33270 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/GraniteShard.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LoneFox + */ +public class GraniteShard extends CardImpl { + + public GraniteShard(UUID ownerId) { + super(ownerId, 182, "Granite Shard", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "MRD"; + + // {3}, {tap} or {R}, {tap}: Granite Shard deals 1 damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{3}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new ManaCostsImpl("{R}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public GraniteShard(final GraniteShard card) { + super(card); + } + + @java.lang.Override + public GraniteShard copy() { + return new GraniteShard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/HeartwoodShard.java b/Mage.Sets/src/mage/sets/mirrodin/HeartwoodShard.java new file mode 100644 index 0000000000..f14be2df0f --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/HeartwoodShard.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.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class HeartwoodShard extends CardImpl { + + public HeartwoodShard(UUID ownerId) { + super(ownerId, 184, "Heartwood Shard", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "MRD"; + + // {3}, {tap} or {G}, {tap}: Target creature gains trample until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{3}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect( + TrampleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{G}")); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public HeartwoodShard(final HeartwoodShard card) { + super(card); + } + + @java.lang.Override + public HeartwoodShard copy() { + return new HeartwoodShard(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/Irradiate.java b/Mage.Sets/src/mage/sets/mirrodin/Irradiate.java new file mode 100644 index 0000000000..b95ae9031c --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/Irradiate.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.mirrodin; + +import java.util.UUID; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +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.filter.common.FilterControlledArtifactPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class Irradiate extends CardImpl { + + public Irradiate(UUID ownerId) { + super(ownerId, 67, "Irradiate", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{B}"); + this.expansionSetCode = "MRD"; + + // Target creature gets -1/-1 until end of turn for each artifact you control. + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(new FilterControlledArtifactPermanent(), -1); + this.getSpellAbility().addEffect(new BoostTargetEffect(count, count, Duration.EndOfTurn, true)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public Irradiate(final Irradiate card) { + super(card); + } + + @java.lang.Override + public Irradiate copy() { + return new Irradiate(this); + } +} From acb2c472074afb50f7f8551126a3b91b0a049a87 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 14 Dec 2015 12:51:23 +0200 Subject: [PATCH 3/8] Clean up various Control Magic effects --- .../mage/sets/avacynrestored/SpiritAway.java | 16 +++++--- .../sets/dragonsoftarkir/IllusoryGains.java | 10 ++--- Mage.Sets/src/mage/sets/iceage/Conquer.java | 6 +-- .../mage/sets/limitedalpha/ControlMagic.java | 2 +- .../src/mage/sets/magic2010/MindControl.java | 22 +++++----- .../sets/masterseditionii/BindingGrasp.java | 2 +- .../src/mage/sets/mirrodin/Domineer.java | 2 +- .../mirrodinbesieged/CorruptedConscience.java | 2 +- .../sets/modernmasters/TakePossession.java | 5 +-- .../src/mage/sets/newphyrexia/Enslave.java | 2 +- Mage.Sets/src/mage/sets/onslaught/Annex.java | 2 +- .../sets/scarsofmirrodin/VolitionReins.java | 17 ++++---- .../sets/seventhedition/StealArtifact.java | 13 +++--- .../mage/sets/shadowmoor/BitingTether.java | 40 ++----------------- .../mage/sets/tempest/StealEnchantment.java | 6 +-- .../mage/sets/tenthedition/Persuasion.java | 4 +- .../src/mage/sets/urzasdestiny/Treachery.java | 6 +-- .../src/mage/sets/urzassaga/Confiscate.java | 4 +- .../src/mage/sets/worldwake/VaporSnare.java | 13 +++--- .../continuous/ControlEnchantedEffect.java | 6 ++- 20 files changed, 78 insertions(+), 102 deletions(-) diff --git a/Mage.Sets/src/mage/sets/avacynrestored/SpiritAway.java b/Mage.Sets/src/mage/sets/avacynrestored/SpiritAway.java index 983e2a25f2..5b60e2c02c 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/SpiritAway.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/SpiritAway.java @@ -27,7 +27,7 @@ */ package mage.sets.avacynrestored; -import mage.constants.*; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; @@ -37,11 +37,15 @@ 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; -import java.util.UUID; - /** * * @author noxx @@ -58,11 +62,11 @@ public class SpiritAway extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - - // You control enchanted creature. + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + + // You control enchanted creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); // Enchanted creature gets +2/+2 and has flying. diff --git a/Mage.Sets/src/mage/sets/dragonsoftarkir/IllusoryGains.java b/Mage.Sets/src/mage/sets/dragonsoftarkir/IllusoryGains.java index e2c756460a..5cbae1c125 100644 --- a/Mage.Sets/src/mage/sets/dragonsoftarkir/IllusoryGains.java +++ b/Mage.Sets/src/mage/sets/dragonsoftarkir/IllusoryGains.java @@ -56,9 +56,9 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class IllusoryGains extends CardImpl { - + private static final FilterPermanent filter = new FilterCreaturePermanent("a creature"); - + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); } @@ -71,13 +71,13 @@ public class IllusoryGains extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // You control enchanted creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); - + // Whenever a creature enters the battlefield under an opponent's control, attach Illusory Gains to that creature. this.addAbility(new EntersBattlefieldAllTriggeredAbility( Zone.BATTLEFIELD, new IllusoryGainsEffect(), filter, false, SetTargetPointer.PERMANENT, "Whenever a creature enters the battlefield under an opponent's control, you attach Illusory Gains to that creature.")); diff --git a/Mage.Sets/src/mage/sets/iceage/Conquer.java b/Mage.Sets/src/mage/sets/iceage/Conquer.java index 614ae63e28..901f6332df 100644 --- a/Mage.Sets/src/mage/sets/iceage/Conquer.java +++ b/Mage.Sets/src/mage/sets/iceage/Conquer.java @@ -56,12 +56,12 @@ public class Conquer extends CardImpl { // Enchant land TargetPermanent auraTarget = new TargetLandPermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // You control enchanted land. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("land"))); } public Conquer(final Conquer card) { diff --git a/Mage.Sets/src/mage/sets/limitedalpha/ControlMagic.java b/Mage.Sets/src/mage/sets/limitedalpha/ControlMagic.java index 6a27d829d8..77b9fbe191 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/ControlMagic.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/ControlMagic.java @@ -57,7 +57,7 @@ public class ControlMagic extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // You control enchanted creature. diff --git a/Mage.Sets/src/mage/sets/magic2010/MindControl.java b/Mage.Sets/src/mage/sets/magic2010/MindControl.java index b3e030da38..e068e09e5e 100644 --- a/Mage.Sets/src/mage/sets/magic2010/MindControl.java +++ b/Mage.Sets/src/mage/sets/magic2010/MindControl.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,7 +20,7 @@ * 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. @@ -29,16 +29,16 @@ package mage.sets.magic2010; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -54,11 +54,13 @@ public class MindControl extends CardImpl { this.subtype.add("Aura"); + // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // You control enchanted creature. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); } diff --git a/Mage.Sets/src/mage/sets/masterseditionii/BindingGrasp.java b/Mage.Sets/src/mage/sets/masterseditionii/BindingGrasp.java index 860203cdf7..9e2899223b 100644 --- a/Mage.Sets/src/mage/sets/masterseditionii/BindingGrasp.java +++ b/Mage.Sets/src/mage/sets/masterseditionii/BindingGrasp.java @@ -61,7 +61,7 @@ public class BindingGrasp extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // At the beginning of your upkeep, sacrifice Binding Grasp unless you pay {1}{U}. diff --git a/Mage.Sets/src/mage/sets/mirrodin/Domineer.java b/Mage.Sets/src/mage/sets/mirrodin/Domineer.java index ea9388e1ca..a277945e33 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/Domineer.java +++ b/Mage.Sets/src/mage/sets/mirrodin/Domineer.java @@ -67,7 +67,7 @@ public class Domineer extends CardImpl { Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // You control enchanted artifact creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("artifact creature"))); } public Domineer(final Domineer card) { diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java index c26e3cff44..f62215f71b 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/CorruptedConscience.java @@ -58,7 +58,7 @@ public class CorruptedConscience extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/modernmasters/TakePossession.java b/Mage.Sets/src/mage/sets/modernmasters/TakePossession.java index 692ba6a793..b3f3741406 100644 --- a/Mage.Sets/src/mage/sets/modernmasters/TakePossession.java +++ b/Mage.Sets/src/mage/sets/modernmasters/TakePossession.java @@ -63,10 +63,7 @@ public class TakePossession extends CardImpl { Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // You control enchanted permanent. - Effect effect = new ControlEnchantedEffect(); - effect.setText("You control enchanted permanent"); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("permanent"))); } public TakePossession(final TakePossession card) { diff --git a/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java b/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java index b9bd782627..33c231b5bb 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/Enslave.java @@ -61,7 +61,7 @@ public class Enslave extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/onslaught/Annex.java b/Mage.Sets/src/mage/sets/onslaught/Annex.java index d25c9ee9b6..bc7e376582 100644 --- a/Mage.Sets/src/mage/sets/onslaught/Annex.java +++ b/Mage.Sets/src/mage/sets/onslaught/Annex.java @@ -61,7 +61,7 @@ public class Annex extends CardImpl { this.addAbility(ability); // You control enchanted land. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("land"))); } public Annex(final Annex card) { diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/VolitionReins.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/VolitionReins.java index acec0deffa..b6007a9c07 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/VolitionReins.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/VolitionReins.java @@ -28,9 +28,7 @@ package mage.sets.scarsofmirrodin; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.Zone; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -39,13 +37,14 @@ import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; -import java.util.UUID; - /** * @author nantuko */ @@ -56,14 +55,16 @@ public class VolitionReins extends CardImpl { this.expansionSetCode = "SOM"; this.subtype.add("Aura"); - + // Enchant permanent TargetPermanent auraTarget = new TargetPermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + // When Volition Reins enters the battlefield, if enchanted permanent is tapped, untap it. this.addAbility(new EntersBattlefieldTriggeredAbility(new UntapVolitionReinsEffect())); + // You control enchanted permanent. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("permanent"))); } public VolitionReins(final VolitionReins card) { diff --git a/Mage.Sets/src/mage/sets/seventhedition/StealArtifact.java b/Mage.Sets/src/mage/sets/seventhedition/StealArtifact.java index 383d8fda12..3e35758430 100644 --- a/Mage.Sets/src/mage/sets/seventhedition/StealArtifact.java +++ b/Mage.Sets/src/mage/sets/seventhedition/StealArtifact.java @@ -28,16 +28,16 @@ package mage.sets.seventhedition; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetArtifactPermanent; @@ -52,15 +52,14 @@ public class StealArtifact extends CardImpl { this.expansionSetCode = "7ED"; this.subtype.add("Aura"); - // Enchant artifact TargetPermanent auraTarget = new TargetArtifactPermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // You control enchanted artifact. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("artifact"))); } public StealArtifact(final StealArtifact card) { diff --git a/Mage.Sets/src/mage/sets/shadowmoor/BitingTether.java b/Mage.Sets/src/mage/sets/shadowmoor/BitingTether.java index 6501317fac..7f8a133a58 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/BitingTether.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/BitingTether.java @@ -31,9 +31,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; +import mage.abilities.effects.common.counter.AddCountersAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -42,8 +42,6 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -59,11 +57,10 @@ public class BitingTether extends CardImpl { this.expansionSetCode = "SHM"; this.subtype.add("Aura"); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); @@ -71,7 +68,7 @@ public class BitingTether extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); // At the beginning of your upkeep, put a -1/-1 counter on enchanted creature. - this.addAbility(new BeginningOfUpkeepTriggeredAbility(new BitingTetherEffect(), TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersAttachedEffect(CounterType.M1M1.createInstance(), "enchanted creature"), TargetController.YOU, false)); } @@ -84,34 +81,3 @@ public class BitingTether extends CardImpl { return new BitingTether(this); } } - -class BitingTetherEffect extends OneShotEffect { - - public BitingTetherEffect() { - super(Outcome.Neutral); - this.staticText = "put a -1/-1 counter on enchanted creature"; - } - - public BitingTetherEffect(final BitingTetherEffect effect) { - super(effect); - } - - @Override - public BitingTetherEffect copy() { - return new BitingTetherEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent bitingTether = game.getPermanent(source.getSourceId()); - if (bitingTether == null) { - return false; - } - Permanent enchantedCreature = game.getPermanent(bitingTether.getAttachedTo()); - if (enchantedCreature != null) { - enchantedCreature.addCounters(CounterType.M1M1.createInstance(), game); - return true; - } - return false; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/tempest/StealEnchantment.java b/Mage.Sets/src/mage/sets/tempest/StealEnchantment.java index 252bfc7189..deedc3d20f 100644 --- a/Mage.Sets/src/mage/sets/tempest/StealEnchantment.java +++ b/Mage.Sets/src/mage/sets/tempest/StealEnchantment.java @@ -56,12 +56,12 @@ public class StealEnchantment extends CardImpl { // Enchant enchantment TargetPermanent auraTarget = new TargetEnchantmentPermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // You control enchanted enchantment. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("enchantment"))); } public StealEnchantment(final StealEnchantment card) { diff --git a/Mage.Sets/src/mage/sets/tenthedition/Persuasion.java b/Mage.Sets/src/mage/sets/tenthedition/Persuasion.java index ca8b798600..fc492d4568 100644 --- a/Mage.Sets/src/mage/sets/tenthedition/Persuasion.java +++ b/Mage.Sets/src/mage/sets/tenthedition/Persuasion.java @@ -56,10 +56,10 @@ public class Persuasion extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // You control enchanted creature. Ability controlAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect()); this.addAbility(controlAbility); diff --git a/Mage.Sets/src/mage/sets/urzasdestiny/Treachery.java b/Mage.Sets/src/mage/sets/urzasdestiny/Treachery.java index 0b2b58a5a3..e3222f67c4 100644 --- a/Mage.Sets/src/mage/sets/urzasdestiny/Treachery.java +++ b/Mage.Sets/src/mage/sets/urzasdestiny/Treachery.java @@ -29,8 +29,6 @@ package mage.sets.urzasdestiny; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -39,7 +37,9 @@ import mage.abilities.effects.common.UntapLandsEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.Zone; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -59,7 +59,7 @@ public class Treachery extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // When Treachery enters the battlefield, untap up to five lands. diff --git a/Mage.Sets/src/mage/sets/urzassaga/Confiscate.java b/Mage.Sets/src/mage/sets/urzassaga/Confiscate.java index 071e9d1386..e86cbc23e1 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Confiscate.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Confiscate.java @@ -56,12 +56,12 @@ public class Confiscate extends CardImpl { // Enchant permanent TargetPermanent auraTarget = new TargetPermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); // You control enchanted permanent. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ControlEnchantedEffect("permanent"))); } public Confiscate(final Confiscate card) { diff --git a/Mage.Sets/src/mage/sets/worldwake/VaporSnare.java b/Mage.Sets/src/mage/sets/worldwake/VaporSnare.java index e56332bdb5..743143d411 100644 --- a/Mage.Sets/src/mage/sets/worldwake/VaporSnare.java +++ b/Mage.Sets/src/mage/sets/worldwake/VaporSnare.java @@ -28,8 +28,6 @@ package mage.sets.worldwake; import java.util.UUID; - -import mage.constants.*; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; @@ -39,6 +37,11 @@ import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.continuous.ControlEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -61,7 +64,7 @@ public class VaporSnare extends CardImpl { // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainControl)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); @@ -83,7 +86,7 @@ public class VaporSnare extends CardImpl { } class VaporSnareEffect extends OneShotEffect { - + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); private static final String effectText = "sacrifice {this} unless you return a land you control to its owner's hand"; @@ -123,4 +126,4 @@ class VaporSnareEffect extends OneShotEffect { public VaporSnareEffect copy() { return new VaporSnareEffect(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java index d4492fecd4..55755f9c1d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/ControlEnchantedEffect.java @@ -15,8 +15,12 @@ import mage.game.permanent.Permanent; public class ControlEnchantedEffect extends ContinuousEffectImpl { public ControlEnchantedEffect() { + this("creature"); + } + + public ControlEnchantedEffect(String targetDescription) { super(Duration.WhileOnBattlefield, Outcome.GainControl); - staticText = "You control enchanted creature"; + staticText = "You control enchanted " + targetDescription; } public ControlEnchantedEffect(final ControlEnchantedEffect effect) { From ac84f8d75ad0aba6161ed5cf32ccd5d7e3df6534 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Mon, 14 Dec 2015 21:06:27 +0200 Subject: [PATCH 4/8] Implement cards: Copperhoof Vorrac, Inertia Bubble, Moriok Scavenger, and Myr Mindservant --- .../mage/sets/mirrodin/CopperhoofVorrac.java | 81 +++++++++++++++++++ .../src/mage/sets/mirrodin/InertiaBubble.java | 72 +++++++++++++++++ .../mage/sets/mirrodin/MoriokScavenger.java | 77 ++++++++++++++++++ .../mage/sets/mirrodin/MyrMindservant.java | 69 ++++++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mirrodin/CopperhoofVorrac.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/InertiaBubble.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/MoriokScavenger.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/MyrMindservant.java diff --git a/Mage.Sets/src/mage/sets/mirrodin/CopperhoofVorrac.java b/Mage.Sets/src/mage/sets/mirrodin/CopperhoofVorrac.java new file mode 100644 index 0000000000..cb33d72ead --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/CopperhoofVorrac.java @@ -0,0 +1,81 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +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.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.TappedPredicate; + +/** + + * + * @author LoneFox + */ +public class CopperhoofVorrac extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("untapped permanent your opponents control"); + + static { + filter.add(Predicates.not(new TappedPredicate())); + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public CopperhoofVorrac(UUID ownerId) { + super(ownerId, 116, "Copperhoof Vorrac", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Boar"); + this.subtype.add("Beast"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Copperhoof Vorrac gets +1/+1 for each untapped permanent your opponents control. + PermanentsOnBattlefieldCount count = new PermanentsOnBattlefieldCount(filter); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(count, count, Duration.WhileOnBattlefield))); + } + + public CopperhoofVorrac(final CopperhoofVorrac card) { + super(card); + } + + @java.lang.Override + public CopperhoofVorrac copy() { + return new CopperhoofVorrac(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/InertiaBubble.java b/Mage.Sets/src/mage/sets/mirrodin/InertiaBubble.java new file mode 100644 index 0000000000..23533edf48 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/InertiaBubble.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +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 InertiaBubble extends CardImpl { + + public InertiaBubble(UUID ownerId) { + super(ownerId, 37, "Inertia Bubble", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Aura"); + + // Enchant artifact + TargetPermanent auraTarget = new TargetArtifactPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + // Enchanted artifact doesn't untap during its controller's untap step. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontUntapInControllersUntapStepEnchantedEffect("artifact"))); + } + + public InertiaBubble(final InertiaBubble card) { + super(card); + } + + @java.lang.Override + public InertiaBubble copy() { + return new InertiaBubble(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/MoriokScavenger.java b/Mage.Sets/src/mage/sets/mirrodin/MoriokScavenger.java new file mode 100644 index 0000000000..7b1d05af5f --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/MoriokScavenger.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.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LoneFox + */ +public class MoriokScavenger extends CardImpl { + + final static FilterCreatureCard filter = new FilterCreatureCard("artifact creature card from your graveyard"); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + public MoriokScavenger(UUID ownerId) { + super(ownerId, 68, "Moriok Scavenger", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Human"); + this.subtype.add("Rogue"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // When Moriok Scavenger enters the battlefield, you may return target artifact creature card from your graveyard to your hand. + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); + ability.addTarget(new TargetCardInYourGraveyard(filter)); + this.addAbility(ability); + } + + public MoriokScavenger(final MoriokScavenger card) { + super(card); + } + + @java.lang.Override + public MoriokScavenger copy() { + return new MoriokScavenger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/MyrMindservant.java b/Mage.Sets/src/mage/sets/mirrodin/MyrMindservant.java new file mode 100644 index 0000000000..6847081ec5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/MyrMindservant.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.ShuffleLibrarySourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + */ +public class MyrMindservant extends CardImpl { + + public MyrMindservant(UUID ownerId) { + super(ownerId, 213, "Myr Mindservant", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Myr"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {2}, {tap}: Shuffle your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleLibrarySourceEffect(), new ManaCostsImpl("{2}")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + public MyrMindservant(final MyrMindservant card) { + super(card); + } + + @java.lang.Override + public MyrMindservant copy() { + return new MyrMindservant(this); + } +} From 6b3f61ce4caa78a828627cdac9b8c2adfe34e579 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 15 Dec 2015 10:43:50 +0200 Subject: [PATCH 5/8] Implement cards: Electrostatic Bolt, Forge Armor, Power Conduit, and Relic Bane --- .../mage/sets/mirrodin/ElectrostaticBolt.java | 101 ++++++++++++++++++ .../src/mage/sets/mirrodin/ForgeArmor.java | 68 ++++++++++++ .../src/mage/sets/mirrodin/PowerConduit.java | 75 +++++++++++++ .../src/mage/sets/mirrodin/RelicBane.java | 77 +++++++++++++ 4 files changed, 321 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mirrodin/ElectrostaticBolt.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/ForgeArmor.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/PowerConduit.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/RelicBane.java diff --git a/Mage.Sets/src/mage/sets/mirrodin/ElectrostaticBolt.java b/Mage.Sets/src/mage/sets/mirrodin/ElectrostaticBolt.java new file mode 100644 index 0000000000..81c301a4f8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/ElectrostaticBolt.java @@ -0,0 +1,101 @@ +/* + * 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.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class ElectrostaticBolt extends CardImpl { + + public ElectrostaticBolt(UUID ownerId) { + super(ownerId, 89, "Electrostatic Bolt", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "MRD"; + + // Electrostatic Bolt deals 2 damage to target creature. If it's an artifact creature, Electrostatic Bolt deals 4 damage to it instead. + Effect effect = new DamageTargetEffect(new ElectrostaticBoltDamageValue()); + effect.setText("{this} deals 2 damage to target creature. If it's an artifact creature, {this} deals 4 damage to it instead."); + this.getSpellAbility().addEffect(effect); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public ElectrostaticBolt(final ElectrostaticBolt card) { + super(card); + } + + @java.lang.Override + public ElectrostaticBolt copy() { + return new ElectrostaticBolt(this); + } +} + +class ElectrostaticBoltDamageValue implements DynamicValue { + + final static FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new CardTypePredicate(CardType.ARTIFACT)); + } + + @java.lang.Override + public int calculate(Game game, Ability source, Effect effect) { + Permanent targetPermanent = game.getPermanent(source.getFirstTarget()); + if(targetPermanent != null) { + if(filter.match(targetPermanent, game)) { + return 4; + } + return 2; + } + return 0; + } + + @java.lang.Override + public ElectrostaticBoltDamageValue copy() { + return new ElectrostaticBoltDamageValue(); + } + + @java.lang.Override + public String getMessage() { + return ""; + } +} + diff --git a/Mage.Sets/src/mage/sets/mirrodin/ForgeArmor.java b/Mage.Sets/src/mage/sets/mirrodin/ForgeArmor.java new file mode 100644 index 0000000000..1e732153d7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/ForgeArmor.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.dynamicvalue.common.SacrificeCostConvertedMana; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledArtifactPermanent; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class ForgeArmor extends CardImpl { + + public ForgeArmor(UUID ownerId) { + super(ownerId, 92, "Forge Armor", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{4}{R}"); + this.expansionSetCode = "MRD"; + + // As an additional cost to cast Forge Armor, sacrifice an artifact. + this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent()))); + // Put X +1/+1 counters on target creature, where X is the sacrificed artifact's converted mana cost. + this.getSpellAbility().addEffect(new AddCountersTargetEffect(new AddCountersTargetEffect( + CounterType.P1P1.createInstance(), new SacrificeCostConvertedMana("artifact")))); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + } + + public ForgeArmor(final ForgeArmor card) { + super(card); + } + + @java.lang.Override + public ForgeArmor copy() { + return new ForgeArmor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/PowerConduit.java b/Mage.Sets/src/mage/sets/mirrodin/PowerConduit.java new file mode 100644 index 0000000000..c3c4c169da --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/PowerConduit.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.mirrodin; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCounterCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.target.common.TargetArtifactPermanent; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + */ +public class PowerConduit extends CardImpl { + + public PowerConduit(UUID ownerId) { + super(ownerId, 229, "Power Conduit", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "MRD"; + + // {tap}, Remove a counter from a permanent you control: Choose one - Put a charge counter on target artifact; or put a +1/+1 counter on target creature. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.CHARGE.createInstance()), new TapSourceCost()); + ability.addCost(new RemoveCounterCost(new TargetControlledPermanent())); + ability.addTarget(new TargetArtifactPermanent()); + Mode mode = new Mode(); + mode.getEffects().add(new AddCountersTargetEffect(CounterType.P1P1.createInstance())); + mode.getTargets().add(new TargetCreaturePermanent()); + ability.addMode(mode); + this.addAbility(ability); + } + + public PowerConduit(final PowerConduit card) { + super(card); + } + + @java.lang.Override + public PowerConduit copy() { + return new PowerConduit(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/RelicBane.java b/Mage.Sets/src/mage/sets/mirrodin/RelicBane.java new file mode 100644 index 0000000000..991a01830b --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/RelicBane.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.mirrodin; + +import java.util.UUID; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.target.TargetPermanent; +import mage.target.common.TargetArtifactPermanent; + +/** + * + * @author LoneFox + */ +public class RelicBane extends CardImpl { + + public RelicBane(UUID ownerId) { + super(ownerId, 76, "Relic Bane", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Aura"); + + // Enchant artifact + TargetPermanent auraTarget = new TargetArtifactPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); + this.addAbility(new EnchantAbility(auraTarget.getTargetName())); + // Enchanted artifact has "At the beginning of your upkeep, you lose 2 life." + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect( + new BeginningOfUpkeepTriggeredAbility(new LoseLifeSourceControllerEffect(2), + TargetController.YOU, false), AttachmentType.AURA))); + } + + public RelicBane(final RelicBane card) { + super(card); + } + + @java.lang.Override + public RelicBane copy() { + return new RelicBane(this); + } +} From 86104fa12423b2d5f20a7521b05791a9e2d78eb4 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 15 Dec 2015 14:11:08 +0200 Subject: [PATCH 6/8] Add DistributeCountersEffect and use it for existing cards. Fix Armament Corps, which allowed to put counters on other players' creatures. Implement cards: Bounty of the Hunt, Shambling Swarm, and Wurmskin Forger --- .../mage/sets/alliances/BountyOfTheHunt.java | 54 ++++++ .../src/mage/sets/alliances/Contagion.java | 56 +------ .../avacynrestored/BlessingsOfNature.java | 43 +---- .../JuganTheRisingStar.java | 44 +---- .../journeyintonyx/AjaniMentorOfHeroes.java | 43 +---- .../mage/sets/khansoftarkir/AbzanCharm.java | 40 +---- .../sets/khansoftarkir/ArmamentCorps.java | 50 ++---- .../masterseditionii/BountyOfTheHunt.java | 77 +++++++++ .../mage/sets/mirrodin/WurmskinForger.java | 69 ++++++++ .../src/mage/sets/stronghold/ElvenRite.java | 40 +---- .../src/mage/sets/torment/ShamblingSwarm.java | 68 ++++++++ .../counter/DistributeCountersEffect.java | 154 ++++++++++++++++++ .../main/java/mage/counters/CounterType.java | 3 + 13 files changed, 458 insertions(+), 283 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/alliances/BountyOfTheHunt.java create mode 100644 Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java create mode 100644 Mage.Sets/src/mage/sets/mirrodin/WurmskinForger.java create mode 100644 Mage.Sets/src/mage/sets/torment/ShamblingSwarm.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/counter/DistributeCountersEffect.java diff --git a/Mage.Sets/src/mage/sets/alliances/BountyOfTheHunt.java b/Mage.Sets/src/mage/sets/alliances/BountyOfTheHunt.java new file mode 100644 index 0000000000..b9d73b4a47 --- /dev/null +++ b/Mage.Sets/src/mage/sets/alliances/BountyOfTheHunt.java @@ -0,0 +1,54 @@ +/* + * 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.alliances; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class BountyOfTheHunt extends mage.sets.masterseditionii.BountyOfTheHunt { + + public BountyOfTheHunt(UUID ownerId) { + super(ownerId); + this.cardNumber = 63; + this.expansionSetCode = "ALL"; + this.rarity = Rarity.UNCOMMON; + } + + public BountyOfTheHunt(final BountyOfTheHunt card) { + super(card); + } + + @Override + public BountyOfTheHunt copy() { + return new BountyOfTheHunt(this); + } +} diff --git a/Mage.Sets/src/mage/sets/alliances/Contagion.java b/Mage.Sets/src/mage/sets/alliances/Contagion.java index a4f7ee3d23..c88002e855 100644 --- a/Mage.Sets/src/mage/sets/alliances/Contagion.java +++ b/Mage.Sets/src/mage/sets/alliances/Contagion.java @@ -30,23 +30,18 @@ package mage.sets.alliances; import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.Mode; import mage.abilities.costs.AlternativeCostSourceAbility; import mage.abilities.costs.common.ExileFromHandCost; import mage.abilities.costs.common.PayLifeCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.counters.BoostCounter; +import mage.counters.CounterType; import mage.filter.common.FilterOwnedCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardIdPredicate; import mage.filter.predicate.mageobject.ColorPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreaturePermanentAmount; @@ -55,7 +50,7 @@ import mage.target.common.TargetCreaturePermanentAmount; * @author Plopman */ public class Contagion extends CardImpl { - + public Contagion(UUID ownerId) { super(ownerId, 4, "Contagion", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{3}{B}{B}"); this.expansionSetCode = "ALL"; @@ -63,15 +58,15 @@ public class Contagion extends CardImpl { FilterOwnedCard filter = new FilterOwnedCard("black card from your hand"); filter.add(new ColorPredicate(ObjectColor.BLACK)); filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself - + // You may pay 1 life and exile a black card from your hand rather than pay Contagion's mana cost. AlternativeCostSourceAbility ability = new AlternativeCostSourceAbility(new PayLifeCost(1)); ability.addCost(new ExileFromHandCost(new TargetCardInHand(filter))); - this.addAbility(ability); - + this.addAbility(ability); + // Distribute two -2/-1 counters among one or two target creatures. this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(2)); - this.getSpellAbility().addEffect(new DistributeCountersEffect()); + this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.M2M1, 2, false, "one or two target creatures")); } public Contagion(final Contagion card) { @@ -83,40 +78,3 @@ public class Contagion extends CardImpl { return new Contagion(this); } } - -class DistributeCountersEffect extends OneShotEffect { - - - public DistributeCountersEffect() { - super(Outcome.UnboostCreature); - } - - public DistributeCountersEffect(final DistributeCountersEffect effect) { - super(effect); - } - - @Override - public DistributeCountersEffect copy() { - return new DistributeCountersEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target: multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - int amount = multiTarget.getTargetAmount(target); - permanent.addCounters(new BoostCounter(-2, -1, amount), game); - } - } - } - return true; - } - - @Override - public String getText(Mode mode) { - return "Distribute two -2/-1 counters among one or two target creatures"; - } -} diff --git a/Mage.Sets/src/mage/sets/avacynrestored/BlessingsOfNature.java b/Mage.Sets/src/mage/sets/avacynrestored/BlessingsOfNature.java index b2fdf9ac90..fb08f62d85 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/BlessingsOfNature.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/BlessingsOfNature.java @@ -28,18 +28,14 @@ package mage.sets.avacynrestored; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.abilities.keyword.MiracleAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; /** @@ -54,7 +50,7 @@ public class BlessingsOfNature extends CardImpl { // Distribute four +1/+1 counters among any number of target creatures. - this.getSpellAbility().addEffect(new BlessingsOfNatureEffect()); + this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.P1P1, 4, false, "any number of target creatures")); this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(4)); this.addAbility(new MiracleAbility(this, new ManaCostsImpl("{G}"))); @@ -69,34 +65,3 @@ public class BlessingsOfNature extends CardImpl { return new BlessingsOfNature(this); } } - -class BlessingsOfNatureEffect extends OneShotEffect { - - public BlessingsOfNatureEffect() { - super(Outcome.BoostCreature); - this.staticText = "Distribute four +1/+1 counters among any number of target creatures"; - } - - public BlessingsOfNatureEffect(final BlessingsOfNatureEffect effect) { - super(effect); - } - - @Override - public BlessingsOfNatureEffect copy() { - return new BlessingsOfNatureEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target : multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - } - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/JuganTheRisingStar.java b/Mage.Sets/src/mage/sets/championsofkamigawa/JuganTheRisingStar.java index 39ab666cef..5b5c93caeb 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/JuganTheRisingStar.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/JuganTheRisingStar.java @@ -29,19 +29,15 @@ package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; /** @@ -62,7 +58,7 @@ public class JuganTheRisingStar extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // When Jugan, the Rising Star dies, you may distribute five +1/+1 counters among any number of target creatures. - Ability ability = new DiesTriggeredAbility(new JuganTheRisingStarMultiEffect(), true); + Ability ability = new DiesTriggeredAbility(new DistributeCountersEffect(CounterType.P1P1, 5, false, "any number of target creatures"), true); ability.addTarget(new TargetCreaturePermanentAmount(5)); this.addAbility(ability); } @@ -77,35 +73,3 @@ public class JuganTheRisingStar extends CardImpl { } } - -class JuganTheRisingStarMultiEffect extends OneShotEffect { - - public JuganTheRisingStarMultiEffect() { - super(Outcome.BoostCreature); - this.staticText = "distribute five +1/+1 counters among any number of target creatures"; - } - - public JuganTheRisingStarMultiEffect(final JuganTheRisingStarMultiEffect effect) { - super(effect); - } - - @Override - public JuganTheRisingStarMultiEffect copy() { - return new JuganTheRisingStarMultiEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target: multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - } - } - } - return true; - } - -} diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java index 2fce108dbb..8cb23a8b8a 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/AjaniMentorOfHeroes.java @@ -31,12 +31,11 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; @@ -47,10 +46,6 @@ import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.ControllerPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; /** @@ -78,7 +73,7 @@ public class AjaniMentorOfHeroes extends CardImpl { this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(4)); // +1: Distribute three +1/+1 counters among one, two, or three target creatures you control - Ability ability = new LoyaltyAbility(new AjaniMentorOfHeroesAddCountersEffect(), 1); + Ability ability = new LoyaltyAbility(new DistributeCountersEffect(CounterType.P1P1, 3, false, "one, two, or three target creatures you control"), 1); ability.addTarget(new TargetCreaturePermanentAmount(3, filter)); this.addAbility(ability); @@ -98,37 +93,3 @@ public class AjaniMentorOfHeroes extends CardImpl { return new AjaniMentorOfHeroes(this); } } - -class AjaniMentorOfHeroesAddCountersEffect extends OneShotEffect { - - public AjaniMentorOfHeroesAddCountersEffect() { - super(Outcome.BoostCreature); - this.staticText = "Distribute three +1/+1 counters among one, two, or three target creatures you control"; - } - - public AjaniMentorOfHeroesAddCountersEffect(final AjaniMentorOfHeroesAddCountersEffect effect) { - super(effect); - } - - @Override - public AjaniMentorOfHeroesAddCountersEffect copy() { - return new AjaniMentorOfHeroesAddCountersEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target : multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - game.informPlayers(new StringBuilder(controller.getLogName()).append(" puts ").append(multiTarget.getTargetAmount(target)).append(" ").append(CounterType.P1P1.getName().toLowerCase()).append(" counter on ").append(permanent.getName()).toString()); - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/AbzanCharm.java b/Mage.Sets/src/mage/sets/khansoftarkir/AbzanCharm.java index 8294c22e25..23f53bab6b 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/AbzanCharm.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/AbzanCharm.java @@ -28,23 +28,18 @@ package mage.sets.khansoftarkir; import java.util.UUID; -import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.counters.CounterType; import mage.filter.Filter; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.PowerPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanentAmount; @@ -78,7 +73,7 @@ public class AbzanCharm extends CardImpl { // *Distribute two +1/+1 counters among one or two target creatures. mode = new Mode(); - mode.getEffects().add(new AbzanCharmDistributeEffect()); + mode.getEffects().add(new DistributeCountersEffect(CounterType.P1P1, 2, false, "one or two target creatures")); mode.getTargets().add(new TargetCreaturePermanentAmount(2)); this.getSpellAbility().addMode(mode); @@ -93,34 +88,3 @@ public class AbzanCharm extends CardImpl { return new AbzanCharm(this); } } - -class AbzanCharmDistributeEffect extends OneShotEffect { - - public AbzanCharmDistributeEffect() { - super(Outcome.BoostCreature); - this.staticText = "Distribute two +1/+1 counters among one or two target creatures"; - } - - public AbzanCharmDistributeEffect(final AbzanCharmDistributeEffect effect) { - super(effect); - } - - @Override - public AbzanCharmDistributeEffect copy() { - return new AbzanCharmDistributeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target : multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - } - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/ArmamentCorps.java b/Mage.Sets/src/mage/sets/khansoftarkir/ArmamentCorps.java index 66e27e47e9..9aae2bfa5f 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/ArmamentCorps.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/ArmamentCorps.java @@ -31,15 +31,14 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.TargetController; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanentAmount; /** @@ -48,6 +47,12 @@ import mage.target.common.TargetCreaturePermanentAmount; */ public class ArmamentCorps extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(new ControllerPredicate(TargetController.YOU)); + } + public ArmamentCorps(UUID ownerId) { super(ownerId, 165, "Armament Corps", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}{B}{G}"); this.expansionSetCode = "KTK"; @@ -58,8 +63,8 @@ public class ArmamentCorps extends CardImpl { this.toughness = new MageInt(4); // When Armament Corps enters the battlefield, distribute two +1/+1 counters among one or two target creatures you control. - Ability ability = new EntersBattlefieldTriggeredAbility(new ArmamentCorpsDistributeEffect(), false); - ability.addTarget(new TargetCreaturePermanentAmount(2)); + Ability ability = new EntersBattlefieldTriggeredAbility(new DistributeCountersEffect(CounterType.P1P1, 2, false, "one or two target creatures you control"), false); + ability.addTarget(new TargetCreaturePermanentAmount(2, filter)); this.addAbility(ability); } @@ -72,34 +77,3 @@ public class ArmamentCorps extends CardImpl { return new ArmamentCorps(this); } } - -class ArmamentCorpsDistributeEffect extends OneShotEffect { - - public ArmamentCorpsDistributeEffect() { - super(Outcome.BoostCreature); - this.staticText = "Distribute two +1/+1 counters among one or two target creatures"; - } - - public ArmamentCorpsDistributeEffect(final ArmamentCorpsDistributeEffect effect) { - super(effect); - } - - @Override - public ArmamentCorpsDistributeEffect copy() { - return new ArmamentCorpsDistributeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target : multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - } - } - } - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java b/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java new file mode 100644 index 0000000000..d95658f315 --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.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.masterseditionii; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.costs.AlternativeCostSourceAbility; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.effects.common.counter.DistributeCountersEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author LoneFox + */ +public class BountyOfTheHunt extends CardImpl { + + private static final FilterCard filter = new FilterCard("a green card from your hand"); + + static { + filter.add(new ColorPredicate(ObjectColor.GREEN)); + } + + + public BountyOfTheHunt(UUID ownerId) { + super(ownerId, 154, "Bounty of the Hunt", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{G}{G}"); + this.expansionSetCode = "ME2"; + + // You may exile a green card from your hand rather than pay Bounty of the Hunt's mana cost. + this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter)))); + + // Distribute three +1/+1 counters among one, two, or three target creatures. For each +1/+1 counter you put on a creature this way, remove a +1/+1 counter from that creature at the beginning of the next cleanup step. + this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.P1P1, 3, true, "one, two, or three target creatures")); + this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3)); + } + + public BountyOfTheHunt(final BountyOfTheHunt card) { + super(card); + } + + @Override + public BountyOfTheHunt copy() { + return new BountyOfTheHunt(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirrodin/WurmskinForger.java b/Mage.Sets/src/mage/sets/mirrodin/WurmskinForger.java new file mode 100644 index 0000000000..6e685c0ffc --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirrodin/WurmskinForger.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirrodin; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.DistributeCountersEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author LoneFox + */ +public class WurmskinForger extends CardImpl { + + public WurmskinForger(UUID ownerId) { + super(ownerId, 140, "Wurmskin Forger", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{5}{G}{G}"); + this.expansionSetCode = "MRD"; + this.subtype.add("Elf"); + this.subtype.add("Warrior"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Wurmskin Forger enters the battlefield, distribute three +1/+1 counters among one, two, or three target creatures. + Ability ability = new EntersBattlefieldTriggeredAbility(new DistributeCountersEffect(CounterType.P1P1, 3, false, "one, two, or three target creatures"), false); + ability.addTarget(new TargetCreaturePermanentAmount(3)); + this.addAbility(ability); + } + + public WurmskinForger(final WurmskinForger card) { + super(card); + } + + @java.lang.Override + public WurmskinForger copy() { + return new WurmskinForger(this); + } +} diff --git a/Mage.Sets/src/mage/sets/stronghold/ElvenRite.java b/Mage.Sets/src/mage/sets/stronghold/ElvenRite.java index 02f5e41008..70eb510639 100644 --- a/Mage.Sets/src/mage/sets/stronghold/ElvenRite.java +++ b/Mage.Sets/src/mage/sets/stronghold/ElvenRite.java @@ -28,16 +28,11 @@ package mage.sets.stronghold; import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.DistributeCountersEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.target.Target; import mage.target.common.TargetCreaturePermanentAmount; /** @@ -51,7 +46,7 @@ public class ElvenRite extends CardImpl { this.expansionSetCode = "STH"; // Distribute two +1/+1 counters among one or two target creatures. - this.getSpellAbility().addEffect(new ElvenRiteDistributeEffect()); + this.getSpellAbility().addEffect(new DistributeCountersEffect(CounterType.P1P1, 2, false, "one or two target creatures")); this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(2)); } @@ -64,34 +59,3 @@ public class ElvenRite extends CardImpl { return new ElvenRite(this); } } - -class ElvenRiteDistributeEffect extends OneShotEffect { - - public ElvenRiteDistributeEffect() { - super(Outcome.BoostCreature); - this.staticText = "Distribute two +1/+1 counters among one or two target creatures"; - } - - public ElvenRiteDistributeEffect(final ElvenRiteDistributeEffect effect) { - super(effect); - } - - @Override - public ElvenRiteDistributeEffect copy() { - return new ElvenRiteDistributeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - if (source.getTargets().size() > 0) { - Target multiTarget = source.getTargets().get(0); - for (UUID target : multiTarget.getTargets()) { - Permanent permanent = game.getPermanent(target); - if (permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(multiTarget.getTargetAmount(target)), game); - } - } - } - return true; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/torment/ShamblingSwarm.java b/Mage.Sets/src/mage/sets/torment/ShamblingSwarm.java new file mode 100644 index 0000000000..3cd23c9452 --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/ShamblingSwarm.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.counter.DistributeCountersEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author LoneFox + */ +public class ShamblingSwarm extends CardImpl { + + public ShamblingSwarm(UUID ownerId) { + super(ownerId, 82, "Shambling Swarm", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}{B}{B}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Horror"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // When Shambling Swarm dies, distribute three -1/-1 counters among one, two, or three target creatures. For each -1/-1 counter you put on a creature this way, remove a -1/-1 counter from that creature at the beginning of the next end step. + Ability ability = new DiesTriggeredAbility(new DistributeCountersEffect(CounterType.M1M1, 3, true, "one, two, or three target creatures"), false); + ability.addTarget(new TargetCreaturePermanentAmount(3)); + this.addAbility(ability); + } + + public ShamblingSwarm(final ShamblingSwarm card) { + super(card); + } + + @Override + public ShamblingSwarm copy() { + return new ShamblingSwarm(this); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/DistributeCountersEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/DistributeCountersEffect.java new file mode 100644 index 0000000000..d1fdf6be71 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/counter/DistributeCountersEffect.java @@ -0,0 +1,154 @@ +/* + * 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.effects.common.counter; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.Mode; +import mage.abilities.common.delayed.AtTheBeginOfNextCleanupDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.util.CardUtil; + +/** + * + * @author LoneFox + */ +public class DistributeCountersEffect extends OneShotEffect { + + private final CounterType counterType; + private final int amount; + private final boolean removeAtEndOfTurn; + private final String targetDescription; + + public DistributeCountersEffect(CounterType counterType, int amount, boolean removeAtEndOfTurn, String targetDescription) { + super(Outcome.BoostCreature); + this.counterType = counterType; + this.amount = amount; + this.removeAtEndOfTurn = removeAtEndOfTurn; + this.targetDescription = targetDescription; + } + + public DistributeCountersEffect(final DistributeCountersEffect effect) { + super(effect); + this.counterType = effect.counterType; + this.amount = effect.amount; + this.removeAtEndOfTurn = effect.removeAtEndOfTurn; + this.targetDescription = effect.targetDescription; + } + + @Override + public DistributeCountersEffect copy() { + return new DistributeCountersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if(source.getTargets().size() > 0) { + Target multiTarget = source.getTargets().get(0); + for(UUID target : multiTarget.getTargets()) { + Permanent permanent = game.getPermanent(target); + if(permanent != null) { + permanent.addCounters(counterType.createInstance(multiTarget.getTargetAmount(target)), game); + } + } + + if(removeAtEndOfTurn) { + DelayedTriggeredAbility ability = new AtTheBeginOfNextCleanupDelayedTriggeredAbility( + new RemoveCountersAtEndOfTurn(counterType)); + ability.setSourceId(source.getSourceId()); + ability.setControllerId(source.getControllerId()); + ability.setSourceObject(source.getSourceObject(game), game); + ability.getTargets().addAll(source.getTargets()); + game.addDelayedTriggeredAbility(ability); + } + + return true; + } + return false; + } + + @Override + public String getText(Mode mode) { + if (!staticText.isEmpty()) { + return staticText; + } + + String name = counterType.getName(); + String text = "distribute " + CardUtil.numberToText(amount) + " " + name + " counters among " + targetDescription + "."; + if(removeAtEndOfTurn) { + text += " For each " + name + " counter you put on a creature this way, remove a " + + name + " counter from that creature at the beginning of the next cleanup step."; + } + return text; + } +} + +class RemoveCountersAtEndOfTurn extends OneShotEffect { + + private final CounterType counterType; + + public RemoveCountersAtEndOfTurn(CounterType counterType) { + super(Outcome.Detriment); + this.counterType = counterType; + String name = counterType.getName(); + staticText = "For each " + name + " counter you put on a creature this way, remove a " + + name + " counter from that creature at the beginning of the next cleanup step."; + } + + public RemoveCountersAtEndOfTurn(final RemoveCountersAtEndOfTurn effect) { + super(effect); + this.counterType = effect.counterType; + } + + @Override + public RemoveCountersAtEndOfTurn copy() { + return new RemoveCountersAtEndOfTurn(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if(source.getTargets().size() > 0) { + Target multiTarget = source.getTargets().get(0); + for(UUID target : multiTarget.getTargets()) { + Permanent permanent = game.getPermanent(target); + if(permanent != null) { + permanent.removeCounters(counterType.getName(), multiTarget.getTargetAmount(target), game); + } + } + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/counters/CounterType.java b/Mage/src/main/java/mage/counters/CounterType.java index f0091d4a2b..afccad2b15 100644 --- a/Mage/src/main/java/mage/counters/CounterType.java +++ b/Mage/src/main/java/mage/counters/CounterType.java @@ -74,6 +74,7 @@ public enum CounterType { LOYALTY("loyalty"), MANNEQUIN("mannequin"), M1M1(new BoostCounter(-1, -1).name), + M2M1(new BoostCounter(-2, -1).name), M2M2(new BoostCounter(-2, -2).name), MINING("mining"), MUSTER("muster"), @@ -153,6 +154,8 @@ public enum CounterType { return new BoostCounter(2, 2, amount); case M1M1: return new BoostCounter(-1, -1, amount); + case M2M1: + return new BoostCounter(-2, -1, amount); case M2M2: return new BoostCounter(-2, -2, amount); default: From 092951a24ac5c1045e0de4ed5131cfa306938430 Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 15 Dec 2015 14:28:29 +0200 Subject: [PATCH 7/8] Fix Bounty of the Hunt's alternative cost to work the same way as other cards of that cycle. --- .../sets/masterseditionii/BountyOfTheHunt.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java b/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java index d95658f315..4701b9be74 100644 --- a/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java +++ b/Mage.Sets/src/mage/sets/masterseditionii/BountyOfTheHunt.java @@ -36,7 +36,9 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.counters.CounterType; -import mage.filter.FilterCard; +import mage.filter.common.FilterOwnedCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardIdPredicate; import mage.filter.predicate.mageobject.ColorPredicate; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCreaturePermanentAmount; @@ -47,18 +49,14 @@ import mage.target.common.TargetCreaturePermanentAmount; */ public class BountyOfTheHunt extends CardImpl { - private static final FilterCard filter = new FilterCard("a green card from your hand"); - - static { - filter.add(new ColorPredicate(ObjectColor.GREEN)); - } - - public BountyOfTheHunt(UUID ownerId) { super(ownerId, 154, "Bounty of the Hunt", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{3}{G}{G}"); this.expansionSetCode = "ME2"; // You may exile a green card from your hand rather than pay Bounty of the Hunt's mana cost. + FilterOwnedCard filter = new FilterOwnedCard("green card from your hand"); + filter.add(new ColorPredicate(ObjectColor.GREEN)); + filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter)))); // Distribute three +1/+1 counters among one, two, or three target creatures. For each +1/+1 counter you put on a creature this way, remove a +1/+1 counter from that creature at the beginning of the next cleanup step. From 07f7f38843dfb6f1f27e1672ae9055fea10f606e Mon Sep 17 00:00:00 2001 From: LoneFox Date: Tue, 15 Dec 2015 14:29:14 +0200 Subject: [PATCH 8/8] Fix a bogus warning when removing all counters of one type from a permanent --- Mage/src/main/java/mage/counters/Counter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/counters/Counter.java b/Mage/src/main/java/mage/counters/Counter.java index 7a9c16e5b5..e2f9949633 100644 --- a/Mage/src/main/java/mage/counters/Counter.java +++ b/Mage/src/main/java/mage/counters/Counter.java @@ -112,7 +112,7 @@ public class Counter implements Serializable { * to be less than 0. If an attempt is made to make the count be less than zero, the call will be logged. */ public void remove(int amount) { - if (count > amount) { + if (count >= amount) { count -= amount; } else { logger.warn("An attempt was made to set the counter '" + name +