mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
Simplify some instances of 'treetop ability'
This commit is contained in:
parent
e4206169b2
commit
0b93dcdfaa
4 changed files with 58 additions and 149 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue