diff --git a/Mage.Sets/src/mage/sets/dissension/ShieldingPlax.java b/Mage.Sets/src/mage/sets/dissension/ShieldingPlax.java index 3d42a62d49e..f2367a6c851 100644 --- a/Mage.Sets/src/mage/sets/dissension/ShieldingPlax.java +++ b/Mage.Sets/src/mage/sets/dissension/ShieldingPlax.java @@ -43,8 +43,8 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; +import mage.filter.FilterObject; import mage.filter.FilterStackObject; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -54,12 +54,8 @@ import mage.target.common.TargetCreaturePermanent; */ public class ShieldingPlax extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("spells or abilities your opponents control"); + private static final FilterObject filter = new FilterStackObject("spells or abilities your opponents control"); - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } - public ShieldingPlax(UUID ownerId) { super(ownerId, 147, "Shielding Plax", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G/U}"); this.expansionSetCode = "DIS"; @@ -71,12 +67,13 @@ public class ShieldingPlax extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // When Shielding Plax enters the battlefield, draw a card. this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); - + // Enchanted creature can't be the target of spells or abilities your opponents control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.OPPONENT))); } public ShieldingPlax(final ShieldingPlax card) { diff --git a/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java b/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java index d09fae31897..1c174e38e8e 100644 --- a/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java +++ b/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.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,19 +20,14 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.magic2011; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SimpleStaticAbility; @@ -40,6 +35,11 @@ import mage.abilities.effects.common.CantBeCounteredSourceEffect; import mage.abilities.effects.common.CantBeTargetedSourceEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterObject; import mage.filter.FilterStackObject; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; @@ -50,7 +50,7 @@ import mage.filter.predicate.mageobject.ColorPredicate; */ public class GaeasRevenge extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("nongreen spells or abilities from nongreen sources"); + private static final FilterObject filter = new FilterStackObject("nongreen spells or abilities from nongreen sources"); static { filter.add(Predicates.not(new ColorPredicate(ObjectColor.GREEN))); diff --git a/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java b/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java index ca6ca52f355..71c8ff7ec97 100644 --- a/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java +++ b/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java @@ -28,12 +28,6 @@ package mage.sets.worldwake; import java.util.UUID; -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.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.RestrictionEffect; @@ -43,33 +37,32 @@ import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReachAbility; import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterObject; import mage.filter.FilterStackObject; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; - - /** * @author noxx */ public class CanopyCover extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("spells or abilities your opponents control"); + private static final FilterObject filter = new FilterStackObject("spells or abilities your opponents control"); - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } - public CanopyCover(UUID ownerId) { super(ownerId, 98, "Canopy Cover", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.expansionSetCode = "WWK"; this.subtype.add("Aura"); - // Enchant creature TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); @@ -81,7 +74,7 @@ public class CanopyCover extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OrchardSpiritEffect())); // Enchanted creature can't be the target of spells or abilities your opponents control. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.OPPONENT))); } public CanopyCover(final CanopyCover card) { diff --git a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java index d67de8aa3f2..cb72eb9e989 100644 --- a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java +++ b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java @@ -25,23 +25,22 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.zendikar; import java.util.UUID; import mage.abilities.condition.LockedInCondition; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; import mage.abilities.condition.common.KickedCondition; import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.effects.common.CantBeTargetedTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; import mage.constants.TargetController; +import mage.filter.FilterObject; import mage.filter.FilterStackObject; -import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; /** @@ -49,12 +48,8 @@ import mage.target.common.TargetCreaturePermanent; */ public class VinesOfVastwood extends CardImpl { - private static final FilterStackObject filter = new FilterStackObject("spells or abilities your opponents control"); + private static final FilterObject filter = new FilterStackObject("spells or abilities your opponents control"); - static { - filter.add(new ControllerPredicate(TargetController.OPPONENT)); - } - private static final String staticText = "If {this} was kicked, that creature gets +4/+4 until end of turn"; public VinesOfVastwood(UUID ownerId) { @@ -66,7 +61,7 @@ public class VinesOfVastwood extends CardImpl { // Target creature can't be the target of spells or abilities your opponents control this turn. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new CantBeTargetedTargetEffect(filter, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new CantBeTargetedTargetEffect(filter, Duration.EndOfTurn, TargetController.OPPONENT)); // If Vines of Vastwood was kicked, that creature gets +4/+4 until end of turn. this.getSpellAbility().addEffect(new ConditionalContinuousEffect(new BoostTargetEffect(4, 4, Duration.EndOfTurn), @@ -82,4 +77,3 @@ public class VinesOfVastwood extends CardImpl { return new VinesOfVastwood(this); } } - diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/CanopyCoverTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/CanopyCoverTest.java new file mode 100644 index 00000000000..d3c0125f01a --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/CanopyCoverTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.replacement.canttarget; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class CanopyCoverTest extends CardTestPlayerBase { + + /** + * Test spell + */ + @Test + public void testCantBeTargetedWithSpells() { + addCard(Zone.HAND, playerB, "Lightning Bolt"); + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // 2/2 Creature - Lion + // Enchanted creature can't be the target of spells or abilities your opponents control. + addCard(Zone.HAND, playerA, "Canopy Cover"); // Enchantment - Aura + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Canopy Cover", "Silvercoat Lion"); + + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Canopy Cover", 1); + assertPermanentCount(playerA, "Silvercoat Lion", 1); + + assertHandCount(playerB, "Lightning Bolt", 1); + } + + @Test + public void testCantBeTargetedWithAbilities() { + // {U},Sacrifice AEther Spellbomb: Return target creature to its owner's hand. + addCard(Zone.BATTLEFIELD, playerB, "AEther Spellbomb"); + addCard(Zone.BATTLEFIELD, playerB, "Island", 1); + + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); // 2/2 Creature - Lion + // Enchanted creature can't be the target of spells or abilities your opponents control. + addCard(Zone.HAND, playerA, "Canopy Cover"); // Enchantment - Aura + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Canopy Cover", "Silvercoat Lion"); + + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "{U},Sacrifice", "Silvercoat Lion"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertPermanentCount(playerA, "Canopy Cover", 1); + assertPermanentCount(playerA, "Silvercoat Lion", 1); + + assertGraveyardCount(playerB, "AEther Spellbomb", 0); + assertPermanentCount(playerB, "AEther Spellbomb", 1); + } +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/GaeasRevengeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/GaeasRevengeTest.java new file mode 100644 index 00000000000..34fa2d09766 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/replacement/canttarget/GaeasRevengeTest.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 org.mage.test.cards.replacement.canttarget; + +import mage.abilities.keyword.TrampleAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class GaeasRevengeTest extends CardTestPlayerBase { + + /** + * Test spell + */ + @Test + public void testGreenCanTargetWithSpells() { + addCard(Zone.HAND, playerA, "Titanic Growth"); + // Gaea's Revenge can't be countered. + // Haste + // Gaea's Revenge can't be the target of nongreen spells or abilities from nongreen sources. + addCard(Zone.BATTLEFIELD, playerA, "Gaea's Revenge"); // 8/5 Creature - Elemental + + addCard(Zone.BATTLEFIELD, playerA, "Forest", 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Titanic Growth", "Gaea's Revenge"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + assertPowerToughness(playerA, "Gaea's Revenge", 12, 9); + } + + @Test + public void testGreenCanTargetWithAnAbilitiy() { + // Gaea's Revenge can't be countered. + // Haste + // Gaea's Revenge can't be the target of nongreen spells or abilities from nongreen sources. + addCard(Zone.BATTLEFIELD, playerB, "Gaea's Revenge"); // 8/5 Creature - Elemental + // Whenever a creature you control becomes blocked, it gets +1/+1 until end of turn. + // {1}{G}: Target creature you control gains trample until end of turn. + addCard(Zone.BATTLEFIELD, playerB, "Somberwald Alpha"); // 3/2 Creature - Wolf + + addCard(Zone.BATTLEFIELD, playerB, "Forest", 2); + + activateAbility(2, PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{G}: Target creature", "Gaea's Revenge"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + assertAbility(playerB, "Gaea's Revenge", TrampleAbility.getInstance(), true); + assertPowerToughness(playerB, "Gaea's Revenge", 8, 5); + } +} diff --git a/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java index bf055b18060..132375bef28 100644 --- a/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java @@ -27,39 +27,43 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.constants.AttachmentType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.FilterStackObject; +import mage.constants.TargetController; +import mage.filter.FilterObject; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; -import mage.game.stack.StackObject; +import mage.game.stack.StackAbility; /** * * @author LevelX2 */ - public class CantBeTargetedAttachedEffect extends ContinuousRuleModifyingEffectImpl { - private final FilterStackObject filterSource; + private final FilterObject filterSource; private final AttachmentType attachmentType; - - public CantBeTargetedAttachedEffect(FilterStackObject filterSource, Duration duration, AttachmentType attachmentType) { + private final TargetController targetController; + + public CantBeTargetedAttachedEffect(FilterObject filterSource, Duration duration, AttachmentType attachmentType, TargetController targetController) { super(duration, Outcome.Benefit); this.filterSource = filterSource; this.attachmentType = attachmentType; + this.targetController = targetController; } public CantBeTargetedAttachedEffect(final CantBeTargetedAttachedEffect effect) { super(effect); this.filterSource = effect.filterSource.copy(); this.attachmentType = effect.attachmentType; + this.targetController = effect.targetController; } @Override @@ -81,8 +85,18 @@ public class CantBeTargetedAttachedEffect extends ContinuousRuleModifyingEffectI public boolean applies(GameEvent event, Ability source, Game game) { Permanent attachment = game.getPermanent(source.getSourceId()); if (attachment != null && event.getTargetId().equals(attachment.getAttachedTo())) { - StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); - if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) { + if (targetController.equals(TargetController.OPPONENT) + && !game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + return false; + } + MageObject mageObject = game.getObject(event.getSourceId()); + MageObject sourceObject; + if (mageObject instanceof StackAbility) { + sourceObject = ((StackAbility) mageObject).getSourceObject(game); + } else { + sourceObject = mageObject; + } + if (mageObject != null && filterSource.match(sourceObject, game)) { return true; } } @@ -103,13 +117,13 @@ public class CantBeTargetedAttachedEffect extends ContinuousRuleModifyingEffectI sb.append(" can't be the target of "); sb.append(filterSource.getMessage()); if (!duration.toString().isEmpty()) { - sb.append(" "); + sb.append(" "); if (duration.equals(Duration.EndOfTurn)) { sb.append("this turn"); } else { sb.append(duration.toString()); } - } + } return sb.toString(); } diff --git a/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java index d49b331c814..2a09645f968 100644 --- a/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.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,22 +20,23 @@ * 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; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.FilterStackObject; +import mage.filter.FilterObject; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.stack.StackAbility; import mage.game.stack.StackObject; /** @@ -44,9 +45,9 @@ import mage.game.stack.StackObject; */ public class CantBeTargetedSourceEffect extends ContinuousRuleModifyingEffectImpl { - private final FilterStackObject filterSource; + private final FilterObject filterSource; - public CantBeTargetedSourceEffect(FilterStackObject filterSource, Duration duration) { + public CantBeTargetedSourceEffect(FilterObject filterSource, Duration duration) { super(duration, Outcome.Benefit); this.filterSource = filterSource; setText(); @@ -66,7 +67,7 @@ public class CantBeTargetedSourceEffect extends ContinuousRuleModifyingEffectImp public boolean apply(Game game, Ability source) { return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.TARGET; @@ -75,8 +76,14 @@ public class CantBeTargetedSourceEffect extends ContinuousRuleModifyingEffectImp @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getTargetId().equals(source.getSourceId())) { - StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); - if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) { + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); + MageObject sourceObject; + if (stackObject instanceof StackAbility) { + sourceObject = ((StackAbility) stackObject).getSourceObject(game); + } else { + sourceObject = stackObject; + } + if (sourceObject != null && filterSource.match(sourceObject, game)) { return true; } } diff --git a/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java index 644b78b6459..387a5e03bfc 100644 --- a/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java @@ -27,34 +27,43 @@ */ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.FilterStackObject; +import mage.constants.TargetController; +import mage.filter.FilterObject; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.stack.StackAbility; import mage.game.stack.StackObject; /** * * @author LevelX2 */ - public class CantBeTargetedTargetEffect extends ContinuousRuleModifyingEffectImpl { - private final FilterStackObject filterSource; + private final FilterObject filterSource; + private final TargetController targetController; - public CantBeTargetedTargetEffect(FilterStackObject filterSource, Duration duration) { + public CantBeTargetedTargetEffect(FilterObject filterSource, Duration duration) { + this(filterSource, duration, TargetController.ANY); + } + + public CantBeTargetedTargetEffect(FilterObject filterSource, Duration duration, TargetController targetController) { super(duration, Outcome.Benefit, false, false); + this.targetController = targetController; this.filterSource = filterSource; } public CantBeTargetedTargetEffect(final CantBeTargetedTargetEffect effect) { super(effect); this.filterSource = effect.filterSource.copy(); + this.targetController = effect.targetController; } @Override @@ -75,8 +84,18 @@ public class CantBeTargetedTargetEffect extends ContinuousRuleModifyingEffectImp @Override public boolean applies(GameEvent event, Ability source, Game game) { if (getTargetPointer().getTargets(game, source).contains(event.getTargetId())) { - StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); - if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) { + if (targetController.equals(TargetController.OPPONENT) + && !game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + return false; + } + StackObject stackObject = game.getStack().getStackObject(event.getSourceId()); + MageObject sourceObject; + if (stackObject instanceof StackAbility) { + sourceObject = ((StackAbility) stackObject).getSourceObject(game); + } else { + sourceObject = stackObject; + } + if (sourceObject != null && filterSource.match(sourceObject, game)) { return true; } } @@ -95,13 +114,13 @@ public class CantBeTargetedTargetEffect extends ContinuousRuleModifyingEffectImp sb.append(" can't be the target of "); sb.append(filterSource.getMessage()); if (!duration.toString().isEmpty()) { - sb.append(" "); + sb.append(" "); if (duration.equals(Duration.EndOfTurn)) { sb.append("this turn"); } else { sb.append(duration.toString()); } - } + } return sb.toString(); } diff --git a/Mage/src/mage/filter/FilterImpl.java b/Mage/src/mage/filter/FilterImpl.java index ecb3f9ee923..7def209d6ef 100644 --- a/Mage/src/mage/filter/FilterImpl.java +++ b/Mage/src/mage/filter/FilterImpl.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.filter; import java.util.ArrayList; @@ -52,7 +51,7 @@ public abstract class FilterImpl implements Filter { this.message = name; } - public FilterImpl(FilterImpl filter) { + public FilterImpl(FilterImpl filter) { this.message = filter.message; this.predicates = new ArrayList<>(filter.predicates); } diff --git a/Mage/src/mage/filter/FilterObject.java b/Mage/src/mage/filter/FilterObject.java index 29402389df3..3fc96e9c6b9 100644 --- a/Mage/src/mage/filter/FilterObject.java +++ b/Mage/src/mage/filter/FilterObject.java @@ -1,31 +1,30 @@ /* -* 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. -*/ - + * 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.filter; import mage.MageObject; @@ -46,7 +45,7 @@ public class FilterObject extends FilterImpl { super(name); } - public FilterObject(FilterObject filter) { + public FilterObject(FilterObject filter) { super(filter); } } diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index e4c858c6d45..2b0cd6990ca 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -390,6 +390,11 @@ public abstract class GameImpl implements Game, Serializable { object = state.getBattlefield().getPermanent(objectId); return object; } + // can be an ability of a sacrificed Token trying to get it's source object + object = getLastKnownInformation(objectId, Zone.BATTLEFIELD); + if (object != null) { + return object; + } for (CommandObject commandObject : state.getCommand()) { if (commandObject instanceof Commander && commandObject.getId().equals(objectId)) { return commandObject; @@ -402,8 +407,6 @@ public abstract class GameImpl implements Game, Serializable { return commandObject; } } - // can be an ability of a sacrificed Token trying to get it's source object - object = getLastKnownInformation(objectId, Zone.BATTLEFIELD); } return object; } diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java index 0ab2eeb7bae..aa8d58de407 100644 --- a/Mage/src/mage/game/stack/StackAbility.java +++ b/Mage/src/mage/game/stack/StackAbility.java @@ -1,41 +1,45 @@ /* -* 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. -*/ - + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ package mage.game.stack; -import mage.constants.AbilityType; -import mage.constants.CardType; -import mage.constants.EffectType; -import mage.constants.Zone; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.ObjectColor; -import mage.abilities.*; +import mage.abilities.Abilities; +import mage.abilities.AbilitiesImpl; +import mage.abilities.Ability; +import mage.abilities.MageSingleton; +import mage.abilities.Mode; +import mage.abilities.Modes; +import mage.abilities.StateTriggeredAbility; import mage.abilities.costs.AlternativeCost; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; @@ -45,19 +49,19 @@ import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; +import mage.cards.Card; import mage.choices.Choice; import mage.choices.Choices; -import mage.game.Game; -import mage.target.Target; -import mage.target.Targets; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import mage.cards.Card; +import mage.constants.AbilityType; import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.EffectType; +import mage.constants.Zone; +import mage.game.Game; import mage.game.events.GameEvent; import mage.players.Player; +import mage.target.Target; +import mage.target.Targets; import mage.util.GameLog; import mage.watchers.Watcher; @@ -96,7 +100,7 @@ public class StackAbility extends StackObjImpl implements Ability { public boolean isActivated() { return ability.isActivated(); } - + @Override public boolean resolve(Game game) { if (ability.getTargets().stillLegal(ability, game)) { @@ -110,13 +114,14 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void reset(Game game) { } + public void reset(Game game) { + } @Override public void counter(UUID sourceId, Game game) { //20100716 - 603.8 if (ability instanceof StateTriggeredAbility) { - ((StateTriggeredAbility)ability).counter(game); + ((StateTriggeredAbility) ability).counter(game); } } @@ -127,14 +132,14 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public String getIdName() { - return getName() + " ["+getId().toString().substring(0,3) +"]"; + return getName() + " [" + getId().toString().substring(0, 3) + "]"; } - + @Override public String getLogName() { return GameLog.getColoredObjectIdName(this); } - + @Override public String getImageName() { return name; @@ -221,9 +226,9 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public int getConvertedManaCost() { - // Activated abilities have an "activation cost" but they don't have a characteristic related to that while on the stack. + // Activated abilities have an "activation cost" but they don't have a characteristic related to that while on the stack. // There are certain effects that interact with the cost to activate an ability (e.g., Training Grounds, Power Artifact) - // but nothing that looks for that quality of an ability once it's on the stack. + // but nothing that looks for that quality of an ability once it's on the stack. return 0; } @@ -258,13 +263,16 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void setSourceId(UUID sourceID) {} + public void setSourceId(UUID sourceID) { + } @Override - public void addCost(Cost cost) {} + public void addCost(Cost cost) { + } @Override - public void addEffect(Effect effect) {} + public void addEffect(Effect effect) { + } @Override public boolean activate(Game game, boolean noMana) { @@ -277,7 +285,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void addTarget(Target target) {} + public void addTarget(Target target) { + } @Override public UUID getFirstTarget() { @@ -290,7 +299,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void addChoice(Choice choice) {} + public void addChoice(Choice choice) { + } @Override public List getAlternativeCosts() { @@ -298,7 +308,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void addAlternativeCost(AlternativeCost cost) { } + public void addAlternativeCost(AlternativeCost cost) { + } @Override public ManaCosts getManaCosts() { @@ -306,12 +317,13 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public ManaCosts getManaCostsToPay ( ) { + public ManaCosts getManaCostsToPay() { return ability.getManaCostsToPay(); } @Override - public void addManaCost(ManaCost cost) { } + public void addManaCost(ManaCost cost) { + } @Override public AbilityType getAbilityType() { @@ -329,7 +341,7 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void setName(String name) { + public void setName(String name) { this.name = name; } @@ -344,7 +356,7 @@ public class StackAbility extends StackObjImpl implements Ability { card.adjustChoices(ability, game); } } - + @Override public void adjustCosts(Ability ability, Game game) { Card card = game.getCard(ability.getSourceId()); @@ -367,7 +379,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void addOptionalCost(Cost cost) {} + public void addOptionalCost(Cost cost) { + } @Override public boolean checkIfClause(Game game) { @@ -382,7 +395,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void newOriginalId() {} + public void newOriginalId() { + } @Override public Ability getStackAbility() { @@ -395,7 +409,8 @@ public class StackAbility extends StackObjImpl implements Ability { } @Override - public void addMode(Mode mode) {} + public void addMode(Mode mode) { + } @Override public Modes getModes() { @@ -455,7 +470,7 @@ public class StackAbility extends StackObjImpl implements Ability { public void setAdditionalCostsRuleVisible(boolean ruleAdditionalCostsVisible) { this.ability.setAdditionalCostsRuleVisible(ruleAdditionalCostsVisible); } - + @Override public UUID getOriginalId() { return this.ability.getOriginalId(); @@ -478,7 +493,7 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public void setCostModificationActive(boolean active) { - throw new UnsupportedOperationException("Not supported. Only neede for flashbacked spells"); + throw new UnsupportedOperationException("Not supported. Only neede for flashbacked spells"); } @Override @@ -500,7 +515,7 @@ public class StackAbility extends StackObjImpl implements Ability { public void addWatcher(Watcher watcher) { throw new UnsupportedOperationException("Not supported."); } - + @Override public List getSubAbilities() { return this.ability.getSubAbilities(); @@ -513,7 +528,7 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public MageObject getSourceObject(Game game) { - throw new UnsupportedOperationException("Not supported."); + return game.getBaseObject(getSourceId()); } @Override @@ -529,7 +544,7 @@ public class StackAbility extends StackObjImpl implements Ability { @Override public void setSourceObject(MageObject sourceObject, Game game) { throw new UnsupportedOperationException("Not supported."); - } + } @Override public int getZoneChangeCounter(Game game) {