From 9b3c59dfaf6d93db2827cadff19f8ae8b5a08c29 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 17 Sep 2014 14:07:36 +0200 Subject: [PATCH] * Canopy Cover - Fixed that it did not work correctly if cast on a creature controlled by an opponent. --- .../src/mage/sets/magic2011/AutumnsVeil.java | 4 +- .../mage/sets/weatherlight/DenseFoliage.java | 4 +- .../src/mage/sets/worldwake/CanopyCover.java | 19 +-- .../mage/sets/zendikar/VinesOfVastwood.java | 5 - ...fect.java => CantBeTargetedAllEffect.java} | 12 +- .../common/CantBeTargetedAttachedEffect.java | 113 ++++++++++++++++++ 6 files changed, 135 insertions(+), 22 deletions(-) rename Mage/src/mage/abilities/effects/common/{CantTargetEffect.java => CantBeTargetedAllEffect.java} (90%) create mode 100644 Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java diff --git a/Mage.Sets/src/mage/sets/magic2011/AutumnsVeil.java b/Mage.Sets/src/mage/sets/magic2011/AutumnsVeil.java index 6cf257ad57..7f61bcf9ec 100644 --- a/Mage.Sets/src/mage/sets/magic2011/AutumnsVeil.java +++ b/Mage.Sets/src/mage/sets/magic2011/AutumnsVeil.java @@ -34,7 +34,7 @@ import mage.constants.Duration; import mage.constants.Rarity; import mage.ObjectColor; import mage.abilities.effects.common.CantCounterControlledEffect; -import mage.abilities.effects.common.CantTargetEffect; +import mage.abilities.effects.common.CantBeTargetedAllEffect; import mage.cards.CardImpl; import mage.filter.FilterSpell; import mage.filter.common.FilterControlledCreaturePermanent; @@ -64,7 +64,7 @@ public class AutumnsVeil extends CardImpl { // Spells you control can't be countered by blue or black spells this turn this.getSpellAbility().addEffect(new CantCounterControlledEffect(filterTarget1, filterSource, Duration.EndOfTurn)); // and creatures you control can't be the targets of blue or black spells this turn. - this.getSpellAbility().addEffect(new CantTargetEffect(filterTarget2, filterSource, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new CantBeTargetedAllEffect(filterTarget2, filterSource, Duration.EndOfTurn)); } public AutumnsVeil(final AutumnsVeil card) { diff --git a/Mage.Sets/src/mage/sets/weatherlight/DenseFoliage.java b/Mage.Sets/src/mage/sets/weatherlight/DenseFoliage.java index 2160829c6d..69ab00d81d 100644 --- a/Mage.Sets/src/mage/sets/weatherlight/DenseFoliage.java +++ b/Mage.Sets/src/mage/sets/weatherlight/DenseFoliage.java @@ -29,7 +29,7 @@ package mage.sets.weatherlight; import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.CantTargetEffect; +import mage.abilities.effects.common.CantBeTargetedAllEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -51,7 +51,7 @@ public class DenseFoliage extends CardImpl { this.color.setGreen(true); // Creatures can't be the targets of spells. - CantTargetEffect cantTargetEffect = new CantTargetEffect(new FilterCreaturePermanent("Creatures"), new FilterSpell("spells"), Duration.WhileOnBattlefield); + CantBeTargetedAllEffect cantTargetEffect = new CantBeTargetedAllEffect(new FilterCreaturePermanent("Creatures"), new FilterSpell("spells"), Duration.WhileOnBattlefield); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, cantTargetEffect)); } diff --git a/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java b/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java index f05548e03c..84e512feb8 100644 --- a/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java +++ b/Mage.Sets/src/mage/sets/worldwake/CanopyCover.java @@ -38,12 +38,14 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.RestrictionEffect; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.effects.common.CantBeTargetedAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; -import mage.abilities.keyword.HexproofAbility; import mage.abilities.keyword.ReachAbility; import mage.cards.CardImpl; +import mage.constants.TargetController; +import mage.filter.FilterStackObject; +import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.TargetPermanent; @@ -56,6 +58,12 @@ import mage.target.common.TargetCreaturePermanent; */ public class CanopyCover extends CardImpl { + private static final FilterStackObject 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"; @@ -74,7 +82,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 GainAbilityAttachedEffect(HexproofAbility.getInstance(), AttachmentType.AURA))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA))); } public CanopyCover(final CanopyCover card) { @@ -112,10 +120,7 @@ class OrchardSpiritEffect extends RestrictionEffect { @Override public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) { - if (blocker.getAbilities().contains(FlyingAbility.getInstance()) || blocker.getAbilities().contains(ReachAbility.getInstance())) { - return true; - } - return false; + return blocker.getAbilities().contains(FlyingAbility.getInstance()) || blocker.getAbilities().contains(ReachAbility.getInstance()); } @Override diff --git a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java index 7467305f95..8f380dea34 100644 --- a/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java +++ b/Mage.Sets/src/mage/sets/zendikar/VinesOfVastwood.java @@ -29,7 +29,6 @@ package mage.sets.zendikar; import java.util.UUID; -import mage.ObjectColor; import mage.abilities.condition.LockedInCondition; import mage.constants.CardType; import mage.constants.Duration; @@ -38,14 +37,10 @@ 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; diff --git a/Mage/src/mage/abilities/effects/common/CantTargetEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedAllEffect.java similarity index 90% rename from Mage/src/mage/abilities/effects/common/CantTargetEffect.java rename to Mage/src/mage/abilities/effects/common/CantBeTargetedAllEffect.java index a0b3377e0c..d030c329dc 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedAllEffect.java @@ -44,16 +44,16 @@ import mage.game.stack.StackObject; * * @author BetaSteward_at_googlemail.com */ -public class CantTargetEffect extends ContinuousRuleModifiyingEffectImpl { +public class CantBeTargetedAllEffect extends ContinuousRuleModifiyingEffectImpl { private FilterPermanent filterTarget; private FilterStackObject filterSource; - public CantTargetEffect(FilterPermanent filterTarget, Duration duration) { + public CantBeTargetedAllEffect(FilterPermanent filterTarget, Duration duration) { this(filterTarget, null, duration); } - public CantTargetEffect(FilterPermanent filterTarget, FilterStackObject filterSource, Duration duration) { + public CantBeTargetedAllEffect(FilterPermanent filterTarget, FilterStackObject filterSource, Duration duration) { super(duration, Outcome.Benefit); this.filterTarget = filterTarget; this.filterSource = filterSource; @@ -61,7 +61,7 @@ public class CantTargetEffect extends ContinuousRuleModifiyingEffectImpl { } - public CantTargetEffect(final CantTargetEffect effect) { + public CantBeTargetedAllEffect(final CantBeTargetedAllEffect effect) { super(effect); if (effect.filterTarget != null) { this.filterTarget = effect.filterTarget.copy(); @@ -72,8 +72,8 @@ public class CantTargetEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public CantTargetEffect copy() { - return new CantTargetEffect(this); + public CantBeTargetedAllEffect copy() { + return new CantBeTargetedAllEffect(this); } @Override diff --git a/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java b/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java new file mode 100644 index 0000000000..0b1e988940 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/CantBeTargetedAttachedEffect.java @@ -0,0 +1,113 @@ +/* + * 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.AttachmentType; +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.permanent.Permanent; +import mage.game.stack.StackObject; + +/** + * + * @author LevelX2 + */ + +public class CantBeTargetedAttachedEffect extends ContinuousRuleModifiyingEffectImpl { + + private final FilterStackObject filterSource; + private final AttachmentType attachmentType; + + public CantBeTargetedAttachedEffect(FilterStackObject filterSource, Duration duration, AttachmentType attachmentType) { + super(duration, Outcome.Benefit); + this.filterSource = filterSource; + this.attachmentType = attachmentType; + } + + public CantBeTargetedAttachedEffect(final CantBeTargetedAttachedEffect effect) { + super(effect); + this.filterSource = effect.filterSource.copy(); + this.attachmentType = effect.attachmentType; + } + + @Override + public CantBeTargetedAttachedEffect copy() { + return new CantBeTargetedAttachedEffect(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) { + 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)) { + return true; + } + } + } + return false; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + if (attachmentType.equals(AttachmentType.AURA)) { + sb.append("Enchanted creature"); + } else { + sb.append("Equipped creature"); + } + 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(); + } + +}