diff --git a/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java b/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java index c4b2cf3e4fb..bbe3a25a379 100644 --- a/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java +++ b/Mage.Sets/src/mage/sets/magic2011/GaeasRevenge.java @@ -37,7 +37,7 @@ import mage.MageInt; import mage.ObjectColor; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.common.CantCounterSourceEffect; -import mage.abilities.effects.common.CantTargetSourceEffect; +import mage.abilities.effects.common.CantBeTargetedSourceEffect; import mage.abilities.keyword.HasteAbility; import mage.cards.CardImpl; import mage.filter.FilterStackObject; @@ -66,7 +66,7 @@ public class GaeasRevenge extends CardImpl { this.addAbility(new SimpleStaticAbility(Zone.STACK, new CantCounterSourceEffect())); this.addAbility(HasteAbility.getInstance()); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantTargetSourceEffect(filter, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedSourceEffect(filter, Duration.WhileOnBattlefield))); } diff --git a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java index 795aadd1e9f..7467305f959 100644 --- a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java +++ b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java @@ -29,17 +29,24 @@ package mage.sets.zendikar; import java.util.UUID; +import mage.ObjectColor; 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.ConditionalContinousEffect; +import mage.abilities.effects.common.CantBeTargetedTargetEffect; import mage.abilities.effects.common.continious.BoostTargetEffect; import mage.abilities.effects.common.continious.GainAbilityTargetEffect; import mage.abilities.keyword.HexproofAbility; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; +import mage.constants.TargetController; +import mage.filter.FilterStackObject; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.target.common.TargetCreaturePermanent; /** @@ -47,7 +54,13 @@ import mage.target.common.TargetCreaturePermanent; */ public class VinesOfVastwood extends CardImpl { - private static final String staticText = "If Vines of Vastwood was kicked, that creature gets +4/+4 until end of turn"; + private static final FilterStackObject 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) { super(ownerId, 193, "Vines of Vastwood", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}"); @@ -58,9 +71,8 @@ public class VinesOfVastwood extends CardImpl { this.addAbility(new KickerAbility("{G}")); // Target creature can't be the target of spells or abilities your opponents control this turn. - TargetCreaturePermanent target = new TargetCreaturePermanent(); - this.getSpellAbility().addTarget(target); - this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HexproofAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new CantBeTargetedTargetEffect(filter, Duration.EndOfTurn)); // If Vines of Vastwood was kicked, that creature gets +4/+4 until end of turn. this.getSpellAbility().addEffect(new ConditionalContinousEffect(new BoostTargetEffect(4, 4, Duration.EndOfTurn), diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeTargetTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeTargetTest.java new file mode 100644 index 00000000000..dba0cbbfee0 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/rules/CantBeTargetTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package org.mage.test.cards.rules; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class CantBeTargetTest extends CardTestPlayerBase { + + /** + * Test that the target of Vines of Vastwood can't + * be the target of spells or abilities your opponents control this turn + */ + @Test + public void testVinesofVastwood() { + addCard(Zone.HAND, playerA, "Divine Favor"); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); + + addCard(Zone.HAND, playerB, "Vines of Vastwood"); + addCard(Zone.BATTLEFIELD, playerB, "Forest", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Divine Favor", "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Vines of Vastwood", "Silvercoat Lion", "Divine Favor"); + setChoice(playerB, "No"); // don't use kicker + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPowerToughness(playerA, "Silvercoat Lion", 2, 2); + assertGraveyardCount(playerA, "Divine Favor", 1); + + assertLife(playerA, 20); + assertLife(playerB, 20); + + } +} diff --git a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java similarity index 89% rename from Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java rename to Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java index 53732e2fff4..e00e75831d9 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedSourceEffect.java @@ -42,24 +42,24 @@ import mage.game.stack.StackObject; * * @author BetaSteward_at_googlemail.com */ -public class CantTargetSourceEffect extends ContinuousRuleModifiyingEffectImpl { +public class CantBeTargetedSourceEffect extends ContinuousRuleModifiyingEffectImpl { private final FilterStackObject filterSource; - public CantTargetSourceEffect(FilterStackObject filterSource, Duration duration) { + public CantBeTargetedSourceEffect(FilterStackObject filterSource, Duration duration) { super(duration, Outcome.Benefit); this.filterSource = filterSource; setText(); } - public CantTargetSourceEffect(final CantTargetSourceEffect effect) { + public CantBeTargetedSourceEffect(final CantBeTargetedSourceEffect effect) { super(effect); this.filterSource = effect.filterSource.copy(); } @Override - public CantTargetSourceEffect copy() { - return new CantTargetSourceEffect(this); + public CantBeTargetedSourceEffect copy() { + return new CantBeTargetedSourceEffect(this); } @Override diff --git a/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.java new file mode 100644 index 00000000000..ea7220ec64d --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedTargetEffect.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.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.filter.FilterStackObject; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.stack.StackObject; + +/** + * + * @author LevelX2 + */ + +public class CantBeTargetedTargetEffect extends ContinuousRuleModifiyingEffectImpl { + + private final FilterStackObject filterSource; + + public CantBeTargetedTargetEffect(FilterStackObject filterSource, Duration duration) { + super(duration, Outcome.Benefit); + this.filterSource = filterSource; + } + + public CantBeTargetedTargetEffect(final CantBeTargetedTargetEffect effect) { + super(effect); + this.filterSource = effect.filterSource.copy(); + } + + @Override + public CantBeTargetedTargetEffect copy() { + return new CantBeTargetedTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == EventType.TARGET && getTargetPointer().getTargets(game, source).contains(event.getTargetId())) { + StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); + if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) { + return true; + } + } + return false; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + if (!mode.getTargets().isEmpty()) { + sb.append("target ").append(mode.getTargets().get(0).getTargetName()); + } + sb.append(" can't be the target of "); + sb.append(filterSource.getMessage()); + if (!duration.toString().isEmpty()) { + sb.append(" "); + if (duration.equals(Duration.EndOfTurn)) { + sb.append("this turn"); + } else { + sb.append(duration.toString()); + } + } + return sb.toString(); + } + +}