diff --git a/Mage.Sets/src/mage/sets/dissension/Dovescape.java b/Mage.Sets/src/mage/sets/dissension/Dovescape.java index 52f70eed8ea..a727597c139 100644 --- a/Mage.Sets/src/mage/sets/dissension/Dovescape.java +++ b/Mage.Sets/src/mage/sets/dissension/Dovescape.java @@ -37,6 +37,7 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.SetTargetPointer; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -49,7 +50,7 @@ import mage.game.stack.Spell; * @author emerald000 */ public class Dovescape extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("a noncreature spell"); static { filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); @@ -61,7 +62,7 @@ public class Dovescape extends CardImpl { // Whenever a player casts a noncreature spell, counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell's converted mana cost. - this.addAbility(new SpellCastAllTriggeredAbility(new DovescapeEffect(), filter, false, true)); + this.addAbility(new SpellCastAllTriggeredAbility(new DovescapeEffect(), filter, false, SetTargetPointer.SPELL)); } public Dovescape(final Dovescape card) { @@ -75,21 +76,21 @@ public class Dovescape extends CardImpl { } class DovescapeEffect extends OneShotEffect { - + DovescapeEffect() { super(Outcome.Benefit); this.staticText = "counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell's converted mana cost"; } - + DovescapeEffect(final DovescapeEffect effect) { super(effect); } - + @Override public DovescapeEffect copy() { return new DovescapeEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(this.getTargetPointer().getFirst(game, source)); diff --git a/Mage.Sets/src/mage/sets/eventide/SootImp.java b/Mage.Sets/src/mage/sets/eventide/SootImp.java index 94f98918dc6..8ea50c3e5a9 100644 --- a/Mage.Sets/src/mage/sets/eventide/SootImp.java +++ b/Mage.Sets/src/mage/sets/eventide/SootImp.java @@ -40,11 +40,11 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.SetTargetPointer; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; -import mage.game.stack.Spell; import mage.players.Player; /** @@ -52,9 +52,9 @@ import mage.players.Player; * @author jeffwadsworth */ public class SootImp extends CardImpl { - + static final private FilterSpell filter = new FilterSpell("a nonblack spell"); - + static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); } @@ -69,10 +69,10 @@ public class SootImp extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); - + // Whenever a player casts a nonblack spell, that player loses 1 life. - this.addAbility(new SpellCastAllTriggeredAbility(new SootImpEffect(), filter, false, true)); - + this.addAbility(new SpellCastAllTriggeredAbility(new SootImpEffect(), filter, false, SetTargetPointer.PLAYER)); + } public SootImp(final SootImp card) { @@ -103,11 +103,7 @@ class SootImpEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - Player caster = null; - if (spell != null) { - caster = game.getPlayer(spell.getControllerId()); - } + Player caster = game.getPlayer(targetPointer.getFirst(game, source)); if (caster != null) { caster.loseLife(1, game); return true; diff --git a/Mage.Sets/src/mage/sets/exodus/ManaBreach.java b/Mage.Sets/src/mage/sets/exodus/ManaBreach.java new file mode 100644 index 00000000000..9dbb3b6fd24 --- /dev/null +++ b/Mage.Sets/src/mage/sets/exodus/ManaBreach.java @@ -0,0 +1,103 @@ +/* + * 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.exodus; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastAllTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.FilterSpell; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author LoneFox + + */ +public class ManaBreach extends CardImpl { + + public ManaBreach(UUID ownerId) { + super(ownerId, 38, "Mana Breach", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}"); + this.expansionSetCode = "EXO"; + + // Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand. + this.addAbility(new SpellCastAllTriggeredAbility(new ManaBreachEffect(), new FilterSpell(), false, SetTargetPointer.PLAYER)); + } + + public ManaBreach(final ManaBreach card) { + super(card); + } + + @Override + public ManaBreach copy() { + return new ManaBreach(this); + } +} + +class ManaBreachEffect extends OneShotEffect { + + public ManaBreachEffect() { + super(Outcome.Detriment); + staticText="that player returns a land he or she controls to its owner's hand."; + } + + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if(player != null) { + FilterLandPermanent filter = new FilterLandPermanent("a land you control"); + filter.add(new ControllerIdPredicate(player.getId())); + TargetLandPermanent toBounce = new TargetLandPermanent(1, 1, filter, true); + if(player.chooseTarget(Outcome.ReturnToHand, toBounce, source, game)) { + Permanent land = game.getPermanent(toBounce.getTargets().get(0)); + land.moveToZone(Zone.HAND, source.getSourceId(), game, false); + } + return true; + } + return false; + } + + public ManaBreachEffect(final ManaBreachEffect effect) { + super(effect); + } + + public ManaBreachEffect copy() { + return new ManaBreachEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/legends/InTheEyeOfChaos.java b/Mage.Sets/src/mage/sets/legends/InTheEyeOfChaos.java index 67e8dcf8563..9b9bbd952e8 100644 --- a/Mage.Sets/src/mage/sets/legends/InTheEyeOfChaos.java +++ b/Mage.Sets/src/mage/sets/legends/InTheEyeOfChaos.java @@ -36,6 +36,7 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterSpell; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -48,7 +49,7 @@ import mage.players.Player; * @author emerald000 */ public class InTheEyeOfChaos extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("an instant spell"); static { filter.add(new CardTypePredicate(CardType.INSTANT)); @@ -61,7 +62,7 @@ public class InTheEyeOfChaos extends CardImpl { // Whenever a player casts an instant spell, counter it unless that player pays {X}, where X is its converted mana cost. - this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new InTheEyeOfChaosEffect(), filter, false, true)); + this.addAbility(new SpellCastAllTriggeredAbility(Zone.BATTLEFIELD, new InTheEyeOfChaosEffect(), filter, false, SetTargetPointer.SPELL)); } public InTheEyeOfChaos(final InTheEyeOfChaos card) { @@ -75,21 +76,21 @@ public class InTheEyeOfChaos extends CardImpl { } class InTheEyeOfChaosEffect extends OneShotEffect { - + InTheEyeOfChaosEffect() { super(Outcome.Detriment); this.staticText = "counter it unless that player pays {X}, where X is its converted mana cost"; } - + InTheEyeOfChaosEffect(final InTheEyeOfChaosEffect effect) { super(effect); } - + @Override public InTheEyeOfChaosEffect copy() { return new InTheEyeOfChaosEffect(this); } - + @Override public boolean apply(Game game, Ability source) { StackObject spell = game.getStack().getStackObject(targetPointer.getFirst(game, source)); diff --git a/Mage.Sets/src/mage/sets/legends/NetherVoid.java b/Mage.Sets/src/mage/sets/legends/NetherVoid.java index 9899b75a2d5..e27e1a7bad6 100644 --- a/Mage.Sets/src/mage/sets/legends/NetherVoid.java +++ b/Mage.Sets/src/mage/sets/legends/NetherVoid.java @@ -34,6 +34,7 @@ import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; +import mage.constants.SetTargetPointer; import mage.filter.FilterSpell; /** @@ -48,7 +49,7 @@ public class NetherVoid extends CardImpl { this.supertype.add("World"); // Whenever a player casts a spell, counter it unless that player pays {3}. - this.addAbility(new SpellCastAllTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(3)), new FilterSpell("a spell"), false, true)); + this.addAbility(new SpellCastAllTriggeredAbility(new CounterUnlessPaysEffect(new GenericManaCost(3)), new FilterSpell("a spell"), false, SetTargetPointer.SPELL)); } public NetherVoid(final NetherVoid card) { diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java b/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java index 6873cd06f09..7348c1d5b82 100644 --- a/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java +++ b/Mage.Sets/src/mage/sets/mercadianmasques/HornOfPlenty.java @@ -44,9 +44,9 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.filter.FilterSpell; import mage.game.Game; -import mage.game.stack.Spell; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import mage.constants.SetTargetPointer; /** * @@ -59,7 +59,7 @@ public class HornOfPlenty extends CardImpl { this.expansionSetCode = "MMQ"; // Whenever a player casts a spell, he or she may pay {1}. If that player does, he or she draws a card at the beginning of the next end step. - this.addAbility(new SpellCastAllTriggeredAbility(new HornOfPlentyEffect(), new FilterSpell("a spell"), false, true)); + this.addAbility(new SpellCastAllTriggeredAbility(new HornOfPlentyEffect(), new FilterSpell("a spell"), false, SetTargetPointer.PLAYER)); } public HornOfPlenty(final HornOfPlenty card) { @@ -90,11 +90,7 @@ class HornOfPlentyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - Player caster = null; - if (spell != null) { - caster = game.getPlayer(spell.getControllerId()); - } + Player caster = game.getPlayer(targetPointer.getFirst(game, source)); if (caster != null) { if (caster.chooseUse(Outcome.DrawCard, "Pay {1} to draw a card at the beginning of the next end step?", source, game)) { Cost cost = new ManaCostsImpl("{1}"); diff --git a/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java b/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java index 0fba130c3e8..be4bf8d5bf1 100644 --- a/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java +++ b/Mage.Sets/src/mage/sets/odyssey/UnifyingTheory.java @@ -32,27 +32,26 @@ import mage.abilities.Ability; import mage.abilities.common.SpellCastAllTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.DrawCardTargetEffect; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.DrawCardTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; +import mage.constants.SetTargetPointer; import mage.filter.FilterSpell; import mage.game.Game; -import mage.game.stack.Spell; import mage.players.Player; -import mage.target.targetpointer.FixedTarget; /** * * @author cbt33, Level_X2 (Horn of Plenty) */ - + public class UnifyingTheory extends CardImpl { public UnifyingTheory(UUID ownerId) { @@ -61,7 +60,7 @@ public class UnifyingTheory extends CardImpl { // Whenever a player casts a spell, that player may pay {2}. If the player does, he or she draws a card. - this.addAbility(new SpellCastAllTriggeredAbility(new UnifyingTheoryEffect() , new FilterSpell("a spell"), false, true)); + this.addAbility(new SpellCastAllTriggeredAbility(new UnifyingTheoryEffect() , new FilterSpell("a spell"), false, SetTargetPointer.PLAYER)); } public UnifyingTheory(final UnifyingTheory card) { @@ -92,11 +91,7 @@ class UnifyingTheoryEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); - Player caster = null; - if (spell != null) { - caster = game.getPlayer(spell.getControllerId()); - } + Player caster = game.getPlayer(targetPointer.getFirst(game, source)); if (caster != null) { if (caster.chooseUse(Outcome.DrawCard, "Pay {2} to draw a card?", source, game)) { Cost cost = new ManaCostsImpl("{2}"); diff --git a/Mage.Sets/src/mage/sets/seventhedition/ManaBreach.java b/Mage.Sets/src/mage/sets/seventhedition/ManaBreach.java new file mode 100644 index 00000000000..d22e341467c --- /dev/null +++ b/Mage.Sets/src/mage/sets/seventhedition/ManaBreach.java @@ -0,0 +1,53 @@ +/* + * 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.seventhedition; + +import java.util.UUID; + +/** + * + * @author LoneFox + + */ +public class ManaBreach extends mage.sets.exodus.ManaBreach { + + public ManaBreach(UUID ownerId) { + super(ownerId); + this.cardNumber = 85; + this.expansionSetCode = "7ED"; + } + + public ManaBreach(final ManaBreach card) { + super(card); + } + + @Override + public ManaBreach copy() { + return new ManaBreach(this); + } +} diff --git a/Mage.Sets/src/mage/sets/timespiral/DeepSeaKraken.java b/Mage.Sets/src/mage/sets/timespiral/DeepSeaKraken.java index 28b6e618f45..5df16776da5 100644 --- a/Mage.Sets/src/mage/sets/timespiral/DeepSeaKraken.java +++ b/Mage.Sets/src/mage/sets/timespiral/DeepSeaKraken.java @@ -70,7 +70,7 @@ public class DeepSeaKraken extends CardImpl { this.addAbility(new SuspendAbility(9, new ManaCostsImpl("{2}{U}"), this)); // Whenever an opponent casts a spell, if Deep-Sea Kraken is suspended, remove a time counter from it. this.addAbility(new ConditionalTriggeredAbility( - new SpellCastAllTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), filter, false, false), SuspendedCondition.getInstance(), + new SpellCastAllTriggeredAbility(Zone.EXILED, new RemoveCounterSourceEffect(CounterType.TIME.createInstance()), filter, false, null), SuspendedCondition.getInstance(), "Whenever an opponent casts a spell, if Deep-Sea Kraken is suspended, remove a time counter from it.", false)); } diff --git a/Mage/src/mage/abilities/common/SpellCastAllTriggeredAbility.java b/Mage/src/mage/abilities/common/SpellCastAllTriggeredAbility.java index bb0e485e4da..51882dc3bbd 100644 --- a/Mage/src/mage/abilities/common/SpellCastAllTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/SpellCastAllTriggeredAbility.java @@ -29,6 +29,7 @@ package mage.abilities.common; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.filter.FilterSpell; import mage.game.Game; @@ -45,39 +46,35 @@ public class SpellCastAllTriggeredAbility extends TriggeredAbilityImpl { private static final FilterSpell spellCard = new FilterSpell("a spell"); protected FilterSpell filter; protected String rule; - - /** - * If true, the source that triggered the ability will be set as target to effect. - */ - protected boolean rememberSource = false; + protected SetTargetPointer setTargetPointer; public SpellCastAllTriggeredAbility(Effect effect, boolean optional) { - this(Zone.BATTLEFIELD, effect, spellCard, optional, false); + this(Zone.BATTLEFIELD, effect, spellCard, optional, SetTargetPointer.NONE); } public SpellCastAllTriggeredAbility(Effect effect, FilterSpell filter, boolean optional) { - this(effect, filter, optional, false); + this(effect, filter, optional, SetTargetPointer.NONE); } public SpellCastAllTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, String rule) { - this(effect, filter, optional, false); + this(effect, filter, optional, SetTargetPointer.NONE); this.rule = rule; } - public SpellCastAllTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, boolean rememberSource) { - this(Zone.BATTLEFIELD, effect, filter, optional, rememberSource); + public SpellCastAllTriggeredAbility(Effect effect, FilterSpell filter, boolean optional, SetTargetPointer setTargetPointer) { + this(Zone.BATTLEFIELD, effect, filter, optional, setTargetPointer); } - public SpellCastAllTriggeredAbility(Zone zone, Effect effect, FilterSpell filter, boolean optional, boolean rememberSource) { + public SpellCastAllTriggeredAbility(Zone zone, Effect effect, FilterSpell filter, boolean optional, SetTargetPointer setTargetPointer) { super(zone, effect, optional); this.filter = filter; - this.rememberSource = rememberSource; + this.setTargetPointer = setTargetPointer; } public SpellCastAllTriggeredAbility(final SpellCastAllTriggeredAbility ability) { super(ability); filter = ability.filter; - this.rememberSource = ability.rememberSource; + this.setTargetPointer = ability.setTargetPointer; this.rule = ability.rule; } @@ -90,8 +87,18 @@ public class SpellCastAllTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && filter.match(spell, getControllerId(), game)) { - if (rememberSource) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(spell.getId())); + if (!setTargetPointer.equals(SetTargetPointer.NONE)) { + for (Effect effect : this.getEffects()) { + switch(setTargetPointer) { + case SPELL: + effect.setTargetPointer(new FixedTarget(spell.getId())); + break; + case PLAYER: + effect.setTargetPointer(new FixedTarget(spell.getControllerId())); + break; + } + + } } return true; }