diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java index 29c128af844..8cdf926c72c 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java @@ -29,17 +29,16 @@ package mage.sets.championsofkamigawa; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; @@ -76,7 +75,10 @@ public class SosukeSonOfSeshiro extends CardImpl { // Other Snake creatures you control get +1/+0. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield, filter, true))); // Whenever a Warrior you control deals combat damage to a creature, destroy that creature at end of combat. - this.addAbility(new SosukeSonOfSeshiroTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new SosukeSonOfSeshiroTriggeredAbility(effect)); } public SosukeSonOfSeshiro(final SosukeSonOfSeshiro card) { @@ -91,8 +93,8 @@ public class SosukeSonOfSeshiro extends CardImpl { class SosukeSonOfSeshiroTriggeredAbility extends TriggeredAbilityImpl { - SosukeSonOfSeshiroTriggeredAbility() { - super(Zone.BATTLEFIELD, new SosukeSonOfSeshiroEffect()); + SosukeSonOfSeshiroTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect); } SosukeSonOfSeshiroTriggeredAbility(final SosukeSonOfSeshiroTriggeredAbility ability) { @@ -128,35 +130,3 @@ class SosukeSonOfSeshiroTriggeredAbility extends TriggeredAbilityImpl { return "Whenever a Warrior you control deals combat damage to a creature, destroy that creature at end of combat."; } } - -class SosukeSonOfSeshiroEffect extends OneShotEffect { - - SosukeSonOfSeshiroEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - SosukeSonOfSeshiroEffect(final SosukeSonOfSeshiroEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public SosukeSonOfSeshiroEffect copy() { - return new SosukeSonOfSeshiroEffect(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/dissension/SimicBasilisk.java b/Mage.Sets/src/mage/sets/dissension/SimicBasilisk.java index 2d6da8494b8..09d54a7ec21 100644 --- a/Mage.Sets/src/mage/sets/dissension/SimicBasilisk.java +++ b/Mage.Sets/src/mage/sets/dissension/SimicBasilisk.java @@ -32,7 +32,10 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.GraftAbility; @@ -69,7 +72,10 @@ public class SimicBasilisk extends CardImpl { this.addAbility(new GraftAbility(this, 3)); // {1}{G}: Until end of turn, target creature with a +1/+1 counter on it gains "Whenever this creature deals combat damage to a creature, destroy that creature at end of combat." - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(new DealsDamageToACreatureTriggeredAbility(new DestroyTargetEffect(), true, false, true), Duration.EndOfTurn), new ManaCostsImpl("{1}{G}")); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(new DealsDamageToACreatureTriggeredAbility(effect, true, false, true), Duration.EndOfTurn), new ManaCostsImpl("{1}{G}")); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/sets/fifthdawn/TangleAsp.java b/Mage.Sets/src/mage/sets/fifthdawn/TangleAsp.java index 88d2760e804..1a5e0bb53e0 100644 --- a/Mage.Sets/src/mage/sets/fifthdawn/TangleAsp.java +++ b/Mage.Sets/src/mage/sets/fifthdawn/TangleAsp.java @@ -54,8 +54,8 @@ public class TangleAsp extends CardImpl { this.toughness = new MageInt(2); // Whenever Tangle Asp blocks or becomes blocked by a creature, destroy that creature at end of combat. - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - Effect effect = new CreateDelayedTriggeredAbilityEffect(delayedAbility, true); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); effect.setText("destroy that creature at end of combat"); this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, false)); } diff --git a/Mage.Sets/src/mage/sets/legends/Abomination.java b/Mage.Sets/src/mage/sets/legends/Abomination.java index 5bf815d95f1..179e0541ff5 100644 --- a/Mage.Sets/src/mage/sets/legends/Abomination.java +++ b/Mage.Sets/src/mage/sets/legends/Abomination.java @@ -29,22 +29,18 @@ package mage.sets.legends; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; /** * @@ -52,6 +48,12 @@ import mage.target.targetpointer.FixedTarget; */ public class Abomination extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("green or white creature"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.GREEN), new ColorPredicate(ObjectColor.WHITE))); + } + public Abomination(UUID ownerId) { super(ownerId, 1, "Abomination", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); this.expansionSetCode = "LEG"; @@ -61,7 +63,10 @@ public class Abomination extends CardImpl { this.toughness = new MageInt(6); // Whenever Abomination blocks or becomes blocked by a green or white creature, destroy that creature at end of combat. - this.addAbility(new AbominationTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); } public Abomination(final Abomination card) { @@ -73,99 +78,3 @@ public class Abomination extends CardImpl { return new Abomination(this); } } - -class AbominationTriggeredAbility extends TriggeredAbilityImpl { - - AbominationTriggeredAbility() { - super(Zone.BATTLEFIELD, new AbominationEffect()); - } - - AbominationTriggeredAbility(final AbominationTriggeredAbility ability) { - super(ability); - } - - @Override - public AbominationTriggeredAbility copy() { - return new AbominationTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.BLOCKER_DECLARED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent blocker = game.getPermanent(event.getSourceId()); - Permanent blocked = game.getPermanent(event.getTargetId()); - Permanent abomination = game.getPermanent(sourceId); - if (blocker != null && blocker != abomination - && blocker.getColor(game).isWhite() - && blocked == abomination) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); - return true; - } - } - if (blocker != null && blocker == abomination - && game.getPermanent(event.getTargetId()).getColor(game).isWhite()) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); - return true; - } - } - if (blocker != null && blocker != abomination - && blocker.getColor(game).isGreen() - && blocked == abomination) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); - return true; - } - } - if (blocker != null && blocker == abomination - && game.getPermanent(event.getTargetId()).getColor(game).isGreen()) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} blocks or becomes blocked by a green or white creature, destroy that creature at end of combat."; - } -} - -class AbominationEffect extends OneShotEffect { - - AbominationEffect() { - super(Outcome.Detriment); - staticText = "Destroy that creature at the end of combat"; - } - - AbominationEffect(final AbominationEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability event) { - Permanent permanent = game.getPermanent(targetPointer.getFirst(game, event)); - if (permanent != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(permanent.getId()); - delayedAbility.setControllerId(event.getControllerId()); - delayedAbility.setSourceObject(event.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public AbominationEffect copy() { - return new AbominationEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Cockatrice.java b/Mage.Sets/src/mage/sets/limitedalpha/Cockatrice.java index eb9712905e9..e6896635fad 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/Cockatrice.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/Cockatrice.java @@ -29,22 +29,18 @@ package mage.sets.limitedalpha; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -52,6 +48,12 @@ import mage.target.targetpointer.FixedTarget; */ public class Cockatrice extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Wall creature"); + + static { + filter.add(Predicates.not(new SubtypePredicate("Wall"))); + } + public Cockatrice(UUID ownerId) { super(ownerId, 98, "Cockatrice", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); this.expansionSetCode = "LEA"; @@ -60,10 +62,13 @@ public class Cockatrice extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(4); - // Flying - this.addAbility(FlyingAbility.getInstance()); + // Flying + this.addAbility(FlyingAbility.getInstance()); // Whenever Cockatrice blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat. - this.addAbility(new CockatriceTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); } public Cockatrice(final Cockatrice card) { @@ -75,80 +80,3 @@ public class Cockatrice extends CardImpl { return new Cockatrice(this); } } - -class CockatriceTriggeredAbility extends TriggeredAbilityImpl { - - CockatriceTriggeredAbility() { - super(Zone.BATTLEFIELD, new CockatriceEffect()); - } - - CockatriceTriggeredAbility(final CockatriceTriggeredAbility ability) { - super(ability); - } - - @Override - public CockatriceTriggeredAbility copy() { - return new CockatriceTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.BLOCKER_DECLARED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent blocker = game.getPermanent(event.getSourceId()); - Permanent blocked = game.getPermanent(event.getTargetId()); - Permanent cockatrice = game.getPermanent(sourceId); - if (blocker != null && blocker != cockatrice - && !blocker.getSubtype().contains("Wall") - && blocked == cockatrice) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocker.getId())); - return true; - } - if (blocker != null && blocker == cockatrice - && !blocked.getSubtype().contains("Wall")) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocked.getId())); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat."; - } -} - -class CockatriceEffect extends OneShotEffect { - - CockatriceEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - CockatriceEffect(final CockatriceEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public CockatriceEffect copy() { - return new CockatriceEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/limitedalpha/ThicketBasilisk.java b/Mage.Sets/src/mage/sets/limitedalpha/ThicketBasilisk.java index 1c8dfda7ce2..329272766b5 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/ThicketBasilisk.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/ThicketBasilisk.java @@ -29,21 +29,17 @@ package mage.sets.limitedalpha; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -51,6 +47,12 @@ import mage.target.targetpointer.FixedTarget; */ public class ThicketBasilisk extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Wall creature"); + + static { + filter.add(Predicates.not(new SubtypePredicate("Wall"))); + } + public ThicketBasilisk(UUID ownerId) { super(ownerId, 127, "Thicket Basilisk", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); this.expansionSetCode = "LEA"; @@ -60,7 +62,10 @@ public class ThicketBasilisk extends CardImpl { this.toughness = new MageInt(4); // Whenever Thicket Basilisk blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat. - this.addAbility(new ThicketBasiliskTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); } public ThicketBasilisk(final ThicketBasilisk card) { @@ -72,80 +77,3 @@ public class ThicketBasilisk extends CardImpl { return new ThicketBasilisk(this); } } - -class ThicketBasiliskTriggeredAbility extends TriggeredAbilityImpl { - - ThicketBasiliskTriggeredAbility() { - super(Zone.BATTLEFIELD, new ThicketBasiliskEffect()); - } - - ThicketBasiliskTriggeredAbility(final ThicketBasiliskTriggeredAbility ability) { - super(ability); - } - - @Override - public ThicketBasiliskTriggeredAbility copy() { - return new ThicketBasiliskTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.BLOCKER_DECLARED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent blocker = game.getPermanent(event.getSourceId()); - Permanent blocked = game.getPermanent(event.getTargetId()); - Permanent thicketBasilisk = game.getPermanent(sourceId); - if (blocker != null && blocker != thicketBasilisk - && !blocker.getSubtype().contains("Wall") - && blocked == thicketBasilisk) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocker.getId())); - return true; - } - if (blocker != null && blocker == thicketBasilisk - && !blocked.getSubtype().contains("Wall")) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocked.getId())); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat."; - } -} - -class ThicketBasiliskEffect extends OneShotEffect { - - ThicketBasiliskEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - ThicketBasiliskEffect(final ThicketBasiliskEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public ThicketBasiliskEffect copy() { - return new ThicketBasiliskEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/mirage/RockBasilisk.java b/Mage.Sets/src/mage/sets/mirage/RockBasilisk.java index 66e96becae5..cbe897d304f 100644 --- a/Mage.Sets/src/mage/sets/mirage/RockBasilisk.java +++ b/Mage.Sets/src/mage/sets/mirage/RockBasilisk.java @@ -29,21 +29,17 @@ package mage.sets.mirage; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; /** * @@ -51,6 +47,12 @@ import mage.target.targetpointer.FixedTarget; */ public class RockBasilisk extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Wall creature"); + + static { + filter.add(Predicates.not(new SubtypePredicate("Wall"))); + } + public RockBasilisk(UUID ownerId) { super(ownerId, 339, "Rock Basilisk", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{R}{G}"); this.expansionSetCode = "MIR"; @@ -60,7 +62,10 @@ public class RockBasilisk extends CardImpl { this.toughness = new MageInt(5); // Whenever Rock Basilisk blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat. - this.addAbility(new RockBasiliskTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); } public RockBasilisk(final RockBasilisk card) { @@ -72,80 +77,3 @@ public class RockBasilisk extends CardImpl { return new RockBasilisk(this); } } - -class RockBasiliskTriggeredAbility extends TriggeredAbilityImpl { - - RockBasiliskTriggeredAbility() { - super(Zone.BATTLEFIELD, new RockBasiliskEffect()); - } - - RockBasiliskTriggeredAbility(final RockBasiliskTriggeredAbility ability) { - super(ability); - } - - @Override - public RockBasiliskTriggeredAbility copy() { - return new RockBasiliskTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.BLOCKER_DECLARED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - Permanent blocker = game.getPermanent(event.getSourceId()); - Permanent blocked = game.getPermanent(event.getTargetId()); - Permanent rockBasilisk = game.getPermanent(sourceId); - if (blocker != null && blocker != rockBasilisk - && !blocker.getSubtype().contains("Wall") - && blocked == rockBasilisk) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocker.getId())); - return true; - } - if (blocker != null && blocker == rockBasilisk - && !blocked.getSubtype().contains("Wall")) { - this.getEffects().get(0).setTargetPointer(new FixedTarget(blocked.getId())); - return true; - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat."; - } -} - -class RockBasiliskEffect extends OneShotEffect { - - RockBasiliskEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - RockBasiliskEffect(final RockBasiliskEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public RockBasiliskEffect copy() { - return new RockBasiliskEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/ninthedition/Deathgazer.java b/Mage.Sets/src/mage/sets/ninthedition/Deathgazer.java index 68f56668e4d..f8bd55460ae 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/Deathgazer.java +++ b/Mage.Sets/src/mage/sets/ninthedition/Deathgazer.java @@ -29,18 +29,18 @@ package mage.sets.ninthedition; import java.util.UUID; import mage.MageInt; -import mage.abilities.TriggeredAbilityImpl; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; /** * @@ -48,6 +48,12 @@ import mage.target.targetpointer.FixedTarget; */ public class Deathgazer extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + public Deathgazer(UUID ownerId) { super(ownerId, 124, "Deathgazer", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}"); this.expansionSetCode = "9ED"; @@ -57,7 +63,11 @@ public class Deathgazer extends CardImpl { this.toughness = new MageInt(2); // Whenever Deathgazer blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. - this.addAbility(new DeathgazerTriggeredAbility(new DestroyTargetEffect(), false)); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); + } public Deathgazer(final Deathgazer card) { @@ -69,54 +79,3 @@ public class Deathgazer extends CardImpl { return new Deathgazer(this); } } - -class DeathgazerTriggeredAbility extends TriggeredAbilityImpl { - - - - public DeathgazerTriggeredAbility(Effect effect, boolean optional) { - super(Zone.BATTLEFIELD, effect, optional); - } - - public DeathgazerTriggeredAbility(final DeathgazerTriggeredAbility ability) { - super(ability); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == EventType.BLOCKER_DECLARED; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getSourceId().equals(this.getSourceId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && !permanent.getColor(game).isBlack()) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); - } - return true; - } - } - if (event.getTargetId().equals(this.getSourceId())) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null && !permanent.getColor(game).isBlack()) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); - } - return true; - } - } - return false; - } - - @Override - public String getRule() { - return "Whenever {this} blocks or becomes blocked by a nonblack creature, " + super.getRule(); - } - - @Override - public DeathgazerTriggeredAbility copy() { - return new DeathgazerTriggeredAbility(this); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/thedark/Venom.java b/Mage.Sets/src/mage/sets/thedark/Venom.java index 42eb58e7165..5c736ca71e6 100644 --- a/Mage.Sets/src/mage/sets/thedark/Venom.java +++ b/Mage.Sets/src/mage/sets/thedark/Venom.java @@ -31,8 +31,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DestroyTargetEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -66,7 +67,10 @@ public class Venom extends CardImpl { this.addAbility(ability); // Whenever enchanted creature blocks or becomes blocked by a non-Wall creature, destroy the other creature at end of combat. - this.addAbility(new VenomTriggeredAbility()); + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new VenomTriggeredAbility(effect)); } public Venom(final Venom card) { @@ -81,8 +85,8 @@ public class Venom extends CardImpl { class VenomTriggeredAbility extends TriggeredAbilityImpl { - VenomTriggeredAbility() { - super(Zone.BATTLEFIELD, new VenomEffect()); + VenomTriggeredAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect); } VenomTriggeredAbility(final VenomTriggeredAbility ability) { @@ -128,35 +132,3 @@ class VenomTriggeredAbility extends TriggeredAbilityImpl { return "Whenever enchanted creature blocks or becomes blocked by a non-Wall creature, destroy that creature at end of combat."; } } - -class VenomEffect extends OneShotEffect { - - VenomEffect() { - super(Outcome.DestroyPermanent); - staticText = "destroy that creature at end of combat"; - } - - VenomEffect(final VenomEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (targetCreature != null) { - AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); - delayedAbility.setSourceId(source.getSourceId()); - delayedAbility.setControllerId(source.getControllerId()); - delayedAbility.setSourceObject(source.getSourceObject(game), game); - delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); - game.addDelayedTriggeredAbility(delayedAbility); - return true; - } - return false; - } - - @Override - public VenomEffect copy() { - return new VenomEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/timespiral/GorgonRecluse.java b/Mage.Sets/src/mage/sets/timespiral/GorgonRecluse.java new file mode 100644 index 00000000000..fec34f76e4a --- /dev/null +++ b/Mage.Sets/src/mage/sets/timespiral/GorgonRecluse.java @@ -0,0 +1,84 @@ +/* + * 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.sets.timespiral; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.MadnessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author nigelzor + */ +public class GorgonRecluse extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public GorgonRecluse(UUID ownerId) { + super(ownerId, 111, "Gorgon Recluse", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "TSP"; + this.subtype.add("Gorgon"); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever Gorgon Recluse blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); + // Madness {B}{B} + this.addAbility(new MadnessAbility(this, new ManaCostsImpl("{B}{B}"))); + } + + public GorgonRecluse(final GorgonRecluse card) { + super(card); + } + + @Override + public GorgonRecluse copy() { + return new GorgonRecluse(this); + } +} diff --git a/Mage/src/mage/abilities/common/BlocksOrBecomesBlockedByCreatureTriggeredAbility.java b/Mage/src/mage/abilities/common/BlocksOrBecomesBlockedByCreatureTriggeredAbility.java index 88c172b7a1b..b4231f41b10 100644 --- a/Mage/src/mage/abilities/common/BlocksOrBecomesBlockedByCreatureTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BlocksOrBecomesBlockedByCreatureTriggeredAbility.java @@ -30,8 +30,11 @@ package mage.abilities.common; import mage.constants.Zone; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; /** @@ -40,19 +43,29 @@ import mage.target.targetpointer.FixedTarget; */ public class BlocksOrBecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityImpl { + // note that this is using the Filter#match(E e, Game game), + // not FilterInPlay#(E o, UUID sourceId, UUID playerId, Game game) + // this triggers on both blocked and blocking, so source and player don't have a consistent definition + protected FilterPermanent filter; protected String rule; public BlocksOrBecomesBlockedByCreatureTriggeredAbility(Effect effect, boolean optional) { - this(effect, optional, null); + this(effect, new FilterCreaturePermanent(), optional, null); } - public BlocksOrBecomesBlockedByCreatureTriggeredAbility(Effect effect, boolean optional, String rule) { + public BlocksOrBecomesBlockedByCreatureTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional) { + this(effect, filter, optional, null); + } + + public BlocksOrBecomesBlockedByCreatureTriggeredAbility(Effect effect, FilterPermanent filter, boolean optional, String rule) { super(Zone.BATTLEFIELD, effect, optional); + this.filter = filter; this.rule = rule; } public BlocksOrBecomesBlockedByCreatureTriggeredAbility(final BlocksOrBecomesBlockedByCreatureTriggeredAbility ability) { super(ability); + this.filter = ability.filter; this.rule = ability.rule; } @@ -64,16 +77,22 @@ public class BlocksOrBecomesBlockedByCreatureTriggeredAbility extends TriggeredA @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getSourceId().equals(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getTargetId())); + Permanent blocked = game.getPermanent(event.getTargetId()); + if (blocked != null && filter.match(blocked, game)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; } - return true; } if (event.getTargetId().equals(this.getSourceId())) { - for (Effect effect : this.getEffects()) { - effect.setTargetPointer(new FixedTarget(event.getSourceId())); + Permanent blocker = game.getPermanent(event.getSourceId()); + if (blocker != null && filter.match(blocker, game)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getSourceId())); + } + return true; } - return true; } return false; } @@ -83,7 +102,7 @@ public class BlocksOrBecomesBlockedByCreatureTriggeredAbility extends TriggeredA if (rule != null) { return rule; } - return "Whenever {this} blocks or becomes blocked by a creature, " + super.getRule(); + return "Whenever {this} blocks or becomes blocked by a " + filter.getMessage() + ", " + super.getRule(); } @Override