diff --git a/Mage.Sets/src/mage/cards/c/CanopyCover.java b/Mage.Sets/src/mage/cards/c/CanopyCover.java index 58ad2aed98f..a07ba372567 100644 --- a/Mage.Sets/src/mage/cards/c/CanopyCover.java +++ b/Mage.Sets/src/mage/cards/c/CanopyCover.java @@ -2,19 +2,19 @@ package mage.cards.c; 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.CantBeTargetedAttachedEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesAttachedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReachAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.filter.FilterObject; +import mage.filter.common.FilterCreaturePermanent; import mage.filter.FilterStackObject; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -25,7 +25,17 @@ import java.util.UUID; */ public final class CanopyCover extends CardImpl { - private static final FilterObject filter = new FilterStackObject("spells or abilities your opponents control"); + private static final FilterCreaturePermanent notFlyingorReachCreatures = new FilterCreaturePermanent("except by creatures with flying or reach"); + private static final FilterStackObject filter = new FilterStackObject("spells or abilities your opponents control"); + + static { + notFlyingorReachCreatures.add(Predicates.not( + Predicates.or( + new AbilityPredicate(FlyingAbility.class), + new AbilityPredicate(ReachAbility.class) + ) + )); + } public CanopyCover(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); @@ -39,10 +49,10 @@ public final class CanopyCover extends CardImpl { this.addAbility(ability); // Enchanted creature can't be blocked except by creatures with flying or reach. (!this is a static ability of the enchantment) - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CanopyCoverEffect())); + this.addAbility(new SimpleStaticAbility(new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, notFlyingorReachCreatures, AttachmentType.AURA))); // 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, TargetController.OPPONENT))); + this.addAbility(new SimpleStaticAbility(new CantBeTargetedAttachedEffect(filter, Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.OPPONENT))); } private CanopyCover(final CanopyCover card) { @@ -54,35 +64,3 @@ public final class CanopyCover extends CardImpl { return new CanopyCover(this); } } - -class CanopyCoverEffect extends RestrictionEffect { - - public CanopyCoverEffect() { - super(Duration.WhileOnBattlefield); - staticText = "Enchanted creature can't be blocked except by creatures with flying or reach"; - } - - public CanopyCoverEffect(final CanopyCoverEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - Permanent equipment = game.getPermanent(source.getSourceId()); - if (equipment != null && equipment.getAttachedTo() != null) { - Permanent equipped = game.getPermanent(equipment.getAttachedTo()); - return equipped != null && permanent.getId().equals(equipped.getId()); - } - return false; - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { - return blocker.getAbilities().contains(FlyingAbility.getInstance()) || blocker.getAbilities().contains(ReachAbility.getInstance()); - } - - @Override - public CanopyCoverEffect copy() { - return new CanopyCoverEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SilhanaLedgewalker.java b/Mage.Sets/src/mage/cards/s/SilhanaLedgewalker.java index 4735f88c013..b496bc56262 100644 --- a/Mage.Sets/src/mage/cards/s/SilhanaLedgewalker.java +++ b/Mage.Sets/src/mage/cards/s/SilhanaLedgewalker.java @@ -1,9 +1,8 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.RestrictionEffect; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.HexproofAbility; import mage.cards.CardImpl; @@ -11,9 +10,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import java.util.UUID; @@ -22,6 +21,12 @@ import java.util.UUID; */ public final class SilhanaLedgewalker extends CardImpl { + private static final FilterCreaturePermanent onlyFlyingCreatures = new FilterCreaturePermanent("except by creatures with flying"); + + static { + onlyFlyingCreatures.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + public SilhanaLedgewalker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.ELF); @@ -34,7 +39,7 @@ public final class SilhanaLedgewalker extends CardImpl { this.addAbility(HexproofAbility.getInstance()); // Silhana Ledgewalker can't be blocked except by creatures with flying. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SilhanaLedgewalkerEffect())); + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(onlyFlyingCreatures, Duration.WhileOnBattlefield))); } private SilhanaLedgewalker(final SilhanaLedgewalker card) { @@ -45,32 +50,4 @@ public final class SilhanaLedgewalker extends CardImpl { public SilhanaLedgewalker copy() { return new SilhanaLedgewalker(this); } - } - -class SilhanaLedgewalkerEffect extends RestrictionEffect { - - public SilhanaLedgewalkerEffect() { - super(Duration.WhileOnBattlefield); - staticText = "{this} can't be blocked except by creatures with flying"; - } - - public SilhanaLedgewalkerEffect(final SilhanaLedgewalkerEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - return source.getSourceId().equals(permanent.getId()); - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { - return blocker.getAbilities().contains(FlyingAbility.getInstance()); - } - - @Override - public SilhanaLedgewalkerEffect copy() { - return new SilhanaLedgewalkerEffect(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/SpireTracer.java b/Mage.Sets/src/mage/cards/s/SpireTracer.java index 36b5acc85c4..f1aafbfc45b 100644 --- a/Mage.Sets/src/mage/cards/s/SpireTracer.java +++ b/Mage.Sets/src/mage/cards/s/SpireTracer.java @@ -1,9 +1,8 @@ package mage.cards.s; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.RestrictionEffect; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ReachAbility; import mage.cards.CardImpl; @@ -11,9 +10,9 @@ import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import java.util.UUID; @@ -22,6 +21,17 @@ import java.util.UUID; */ public final class SpireTracer extends CardImpl { + private static final FilterCreaturePermanent notFlyingorReachCreatures = new FilterCreaturePermanent("except by creatures with flying or reach"); + + static { + notFlyingorReachCreatures.add(Predicates.not( + Predicates.or( + new AbilityPredicate(FlyingAbility.class), + new AbilityPredicate(ReachAbility.class) + ) + )); + } + public SpireTracer(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}"); this.subtype.add(SubType.ELF); @@ -31,7 +41,7 @@ public final class SpireTracer extends CardImpl { this.toughness = new MageInt(1); // Spire Tracer can't be blocked except by creatures with flying or reach. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect())); + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(notFlyingorReachCreatures, Duration.WhileOnBattlefield))); } @@ -44,31 +54,3 @@ public final class SpireTracer extends CardImpl { return new SpireTracer(this); } } - -class CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect extends RestrictionEffect { - - public CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect() { - super(Duration.WhileOnBattlefield); - staticText = "{this} can't be blocked except by creatures with flying or reach"; - } - - public CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect(final CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - return permanent.getId().equals(source.getSourceId()); - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { - return blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId()) - || blocker.getAbilities().containsKey(ReachAbility.getInstance().getId()); - } - - @Override - public CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect copy() { - return new CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TreetopBracers.java b/Mage.Sets/src/mage/cards/t/TreetopBracers.java index b3b58c7b0cc..c4f6dc72a55 100644 --- a/Mage.Sets/src/mage/cards/t/TreetopBracers.java +++ b/Mage.Sets/src/mage/cards/t/TreetopBracers.java @@ -2,8 +2,8 @@ package mage.cards.t; 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.combat.CantBeBlockedByCreaturesAttachedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.FlyingAbility; @@ -11,8 +11,9 @@ import mage.abilities.keyword.ReachAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -23,6 +24,12 @@ import java.util.UUID; */ public final class TreetopBracers extends CardImpl { + private static final FilterCreaturePermanent onlyFlyingCreatures = new FilterCreaturePermanent("except by creatures with flying"); + + static { + onlyFlyingCreatures.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); + } + public TreetopBracers(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); this.subtype.add(SubType.AURA); @@ -35,8 +42,8 @@ public final class TreetopBracers extends CardImpl { this.addAbility(ability); // Enchanted creature gets +1/+1 and can't be blocked except by creatures with flying. - ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield)); - ability.addEffect(new TreetopBracersRestrictEffect()); + ability = new SimpleStaticAbility(new BoostEnchantedEffect(1, 1, Duration.WhileOnBattlefield)); + ability.addEffect(new CantBeBlockedByCreaturesAttachedEffect(Duration.WhileOnBattlefield, onlyFlyingCreatures, AttachmentType.AURA).setText("and can't be blocked except by creatures with flying")); this.addAbility(ability); } @@ -49,38 +56,3 @@ public final class TreetopBracers extends CardImpl { return new TreetopBracers(this); } } - -class TreetopBracersRestrictEffect extends RestrictionEffect { - - public TreetopBracersRestrictEffect() { - super(Duration.WhileOnBattlefield); - staticText = "and can't be blocked except by creatures with flying"; - } - - public TreetopBracersRestrictEffect(final TreetopBracersRestrictEffect effect) { - super(effect); - } - - @Override - public boolean applies(Permanent permanent, Ability source, Game game) { - Permanent equipment = game.getPermanent(source.getSourceId()); - if (equipment != null - && equipment.getAttachedTo() != null) { - Permanent equipped = game.getPermanent(equipment.getAttachedTo()); - return equipped != null - && permanent != null - && permanent.getId().equals(equipped.getId()); - } - return false; - } - - @Override - public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game, boolean canUseChooseDialogs) { - return blocker.getAbilities().contains(FlyingAbility.getInstance()) || blocker.getAbilities().contains(ReachAbility.getInstance()); - } - - @Override - public TreetopBracersRestrictEffect copy() { - return new TreetopBracersRestrictEffect(this); - } -}