Replace many custom effects with ExileUntilSourceLeavesEffect

This commit is contained in:
Alex W. Jackson 2022-09-06 06:50:01 -04:00
parent 6f8d0dcee5
commit e310ede837
25 changed files with 101 additions and 604 deletions

View file

@ -72,11 +72,9 @@ class AlignedHedronNetworkExileEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller == null) { return false;} if (controller == null) { return false;}
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null) { return false; } if (permanent == null) { return false; }
// If Whale leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
Set<Card> toExile = new LinkedHashSet<>(game.getBattlefield().getActivePermanents(filter, controller.getId(), source, game)); Set<Card> toExile = new LinkedHashSet<>(game.getBattlefield().getActivePermanents(filter, controller.getId(), source, game));
if (toExile.isEmpty()) { return false; } if (toExile.isEmpty()) { return false; }

View file

@ -1,4 +1,3 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID; import java.util.UUID;
@ -6,23 +5,17 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters; import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
* @author jeffwadsworth using LevelX2 tech * @author awjackson
*/ */
public final class BanisherPriest extends CardImpl { public final class BanisherPriest extends CardImpl {
@ -34,8 +27,8 @@ public final class BanisherPriest extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// When Banisher Priest enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield. // When Banisher Priest enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new BanisherPriestExileEffect()); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
} }
@ -49,31 +42,3 @@ public final class BanisherPriest extends CardImpl {
return new BanisherPriest(this); return new BanisherPriest(this);
} }
} }
class BanisherPriestExileEffect extends OneShotEffect {
public BanisherPriestExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature an opponent controls until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
}
public BanisherPriestExileEffect(final BanisherPriestExileEffect effect) {
super(effect);
}
@Override
public BanisherPriestExileEffect copy() {
return new BanisherPriestExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
// If Banisher Priest leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -78,7 +78,7 @@ class BanishmentEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
Permanent targeted = game.getPermanent(source.getFirstTarget()); Permanent targeted = game.getPermanent(source.getFirstTarget());
if (permanent == null || controller == null || targeted == null) { if (permanent == null || controller == null || targeted == null) {
@ -103,5 +103,4 @@ class BanishmentEffect extends OneShotEffect {
public BanishmentEffect copy() { public BanishmentEffect copy() {
return new BanishmentEffect(this); return new BanishmentEffect(this);
} }
} }

View file

@ -1,66 +1,29 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters; import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledLandPermanent; import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.util.CardUtil;
/** /**
* If the land Chained to the Rocks is enchanting stops being a Mountain or * @author awjackson
* another player gains control of it, Chained to the Rocks will be put into its
* owner's graveyard when state-based actions are performed.
*
* Chained to the Rocks's ability causes a zone change with a duration, a style
* of ability introduced in Magic 2014 that's somewhat reminiscent of older
* cards like Oblivion Ring. However, unlike Oblivion Ring, cards like Chained
* to the Rocks have a single ability that creates two one-shot effects: one
* that exiles the creature when the ability resolves, and another that returns
* the exiled card to the battlefield immediately after Chained to the Rocks
* leaves the battlefield.
*
* If Chained to the Rocks leaves the battlefield before its triggered ability
* resolves, the target creature won't be exiled.
*
* Auras attached to the exiled creature will be put into their owners'
* graveyards (unless they have bestow). Equipment attached to the exiled
* creature will become unattached and remain on the battlefield. Any counters
* on the exiled creature will cease to exist.
*
* If a creature token is exiled, it ceases to exist. It won't be returned to
* the battlefield.
*
* The exiled card returns to the battlefield immediately after Chained to the
* Rocks leaves the battlefield. Nothing happens between the two events,
* including state-based actions.
*
* In a multiplayer game, if Chained to the Rocks's owner leaves the game, the
* exiled card will return to the battlefield. Because the one-shot effect that
* returns the card isn't an ability that goes on the stack, it won't cease to
* exist along with the leaving player's spells and abilities on the stack.
*
* @author LevelX2
*/ */
public final class ChainedToTheRocks extends CardImpl { public final class ChainedToTheRocks extends CardImpl {
private static final FilterControlledLandPermanent filter = new FilterControlledLandPermanent("Mountain you control"); private static final FilterPermanent filter = new FilterControlledLandPermanent("Mountain you control");
static { static {
filter.add(SubType.MOUNTAIN.getPredicate()); filter.add(SubType.MOUNTAIN.getPredicate());
@ -78,11 +41,10 @@ public final class ChainedToTheRocks extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// When Chained to the Rocks enters the battlefield, exile target creature an opponent controls until Chained to the Rocks leaves the battlefield. (That creature returns under its owner's control.) // When Chained to the Rocks enters the battlefield, exile target creature an opponent controls until Chained to the Rocks leaves the battlefield. (That creature returns under its owner's control.)
ability = new EntersBattlefieldTriggeredAbility(new ChainedToTheRocksEffect()); ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
} }
private ChainedToTheRocks(final ChainedToTheRocks card) { private ChainedToTheRocks(final ChainedToTheRocks card) {
@ -94,31 +56,3 @@ public final class ChainedToTheRocks extends CardImpl {
return new ChainedToTheRocks(this); return new ChainedToTheRocks(this);
} }
} }
class ChainedToTheRocksEffect extends OneShotEffect {
public ChainedToTheRocksEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature an opponent controls until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
}
public ChainedToTheRocksEffect(final ChainedToTheRocksEffect effect) {
super(effect);
}
@Override
public ChainedToTheRocksEffect copy() {
return new ChainedToTheRocksEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Chained to the Rocks leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,36 +1,34 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.keyword.IslandwalkAbility; import mage.abilities.keyword.IslandwalkAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Outcome; import mage.filter.FilterPermanent;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
import mage.game.Game; import mage.target.TargetPermanent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
* @author LevelX2 * @author awjackson
*/ */
public final class ColossalWhale extends CardImpl { public final class ColossalWhale extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("creature defending player controls");
static {
filter.add(DefendingPlayerControlsPredicate.instance);
}
public ColossalWhale(UUID ownerId, CardSetInfo setInfo) { public ColossalWhale(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}"); super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{U}{U}");
this.subtype.add(SubType.WHALE); this.subtype.add(SubType.WHALE);
@ -40,8 +38,12 @@ public final class ColossalWhale extends CardImpl {
// Islandwalk // Islandwalk
this.addAbility(new IslandwalkAbility()); this.addAbility(new IslandwalkAbility());
// Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield. // Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield.
this.addAbility(new ColossalWhaleAbility()); Ability ability = new AttacksTriggeredAbility(new ExileUntilSourceLeavesEffect(), true);
ability.addTarget(new TargetPermanent(filter));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
} }
@ -54,70 +56,3 @@ public final class ColossalWhale extends CardImpl {
return new ColossalWhale(this); return new ColossalWhale(this);
} }
} }
class ColossalWhaleAbility extends TriggeredAbilityImpl {
public ColossalWhaleAbility() {
super(Zone.BATTLEFIELD, null);
this.addEffect(new ColossalWhaleExileEffect());
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
setTriggerPhrase("Whenever {this} attacks, ");
}
public ColossalWhaleAbility(final ColossalWhaleAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ATTACKER_DECLARED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId().equals(this.getSourceId())) {
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls");
UUID defenderId = game.getCombat().getDefenderId(sourceId);
filter.add(new ControllerIdPredicate(defenderId));
this.getTargets().clear();
TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
this.addTarget(target);
return true;
}
return false;
}
@Override
public ColossalWhaleAbility copy() {
return new ColossalWhaleAbility(this);
}
}
class ColossalWhaleExileEffect extends OneShotEffect {
public ColossalWhaleExileEffect() {
super(Outcome.Benefit);
this.staticText = "you may exile target creature defending player controls until {this} leaves the battlefield";
}
public ColossalWhaleExileEffect(final ColossalWhaleExileEffect effect) {
super(effect);
}
@Override
public ColossalWhaleExileEffect copy() {
return new ColossalWhaleExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Whale leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -6,22 +6,18 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
* @author LevelX2 * @author awjackson
*/ */
public final class ConstrictingSliver extends CardImpl { public final class ConstrictingSliver extends CardImpl {
@ -34,15 +30,14 @@ public final class ConstrictingSliver extends CardImpl {
// Sliver creatures you control have "When this creature enters the battlefield, you may exile target creature an opponent controls // Sliver creatures you control have "When this creature enters the battlefield, you may exile target creature an opponent controls
// until this creature leaves the battlefield." // until this creature leaves the battlefield."
Ability ability = new EntersBattlefieldTriggeredAbility(new ConstrictingSliverExileEffect(), true); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(), true);
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(ability, new GainAbilityControlledEffect(ability,
Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS) Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS)
.setText("Sliver creatures you control have \"When this creature enters the battlefield, " .setText("Sliver creatures you control have \"When this creature enters the battlefield, "
+ "you may exile target creature an opponent controls until this creature leaves the battlefield.\""))); + "you may exile target creature an opponent controls until this creature leaves the battlefield.\"")));
} }
private ConstrictingSliver(final ConstrictingSliver card) { private ConstrictingSliver(final ConstrictingSliver card) {
@ -54,31 +49,3 @@ public final class ConstrictingSliver extends CardImpl {
return new ConstrictingSliver(this); return new ConstrictingSliver(this);
} }
} }
class ConstrictingSliverExileEffect extends OneShotEffect {
public ConstrictingSliverExileEffect() {
super(Outcome.Benefit);
this.staticText = "you may exile target creature an opponent controls until this creature leaves the battlefield";
}
public ConstrictingSliverExileEffect(final ConstrictingSliverExileEffect effect) {
super(effect);
}
@Override
public ConstrictingSliverExileEffect copy() {
return new ConstrictingSliverExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If the creature leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -64,7 +64,7 @@ class ConsulateCracksownExileEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
//If the permanent leaves the battlefield before the ability resolves, artifacts won't be exiled. //If the permanent leaves the battlefield before the ability resolves, artifacts won't be exiled.
if (permanent == null || controller == null) return false; if (permanent == null || controller == null) return false;
@ -86,5 +86,4 @@ class ConsulateCracksownExileEffect extends OneShotEffect {
public ConsulateCracksownExileEffect copy() { public ConsulateCracksownExileEffect copy() {
return new ConsulateCracksownExileEffect(this); return new ConsulateCracksownExileEffect(this);
} }
} }

View file

@ -78,7 +78,7 @@ class DeputyOfDetentionExileEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
Permanent targeted = game.getPermanent(source.getFirstTarget()); Permanent targeted = game.getPermanent(source.getFirstTarget());
if (permanent == null || controller == null || targeted == null) { if (permanent == null || controller == null || targeted == null) {

View file

@ -19,7 +19,7 @@ import mage.constants.Zone;
import mage.filter.common.FilterAttackingOrBlockingCreature; import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.filter.predicate.permanent.ControllerControlsIslandPredicate; import mage.filter.predicate.permanent.ControllerControlsIslandPredicate;
import mage.game.Game; import mage.game.Game;
import mage.target.common.TargetAttackingOrBlockingCreature; import mage.target.TargetPermanent;
/** /**
* *
@ -49,7 +49,7 @@ public final class DwarvenSeaClan extends CardImpl {
new TapSourceCost(), new TapSourceCost(),
BeforeEndCombatCondition.getInstance() BeforeEndCombatCondition.getInstance()
); );
ability.addTarget(new TargetAttackingOrBlockingCreature(1, 1, filter, false)); ability.addTarget(new TargetPermanent(filter));
addAbility(ability); addAbility(ability);
} }

View file

@ -1,4 +1,3 @@
package mage.cards.f; package mage.cards.f;
import java.util.UUID; import java.util.UUID;
@ -6,19 +5,13 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Outcome; import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
@ -34,8 +27,8 @@ public final class FairgroundsWarden extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// When Fairgrounds Warden enters the battlefield, exile target creature an opponent controls until Fairgrounds Warden leaves the battlefield. // When Fairgrounds Warden enters the battlefield, exile target creature an opponent controls until Fairgrounds Warden leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new FairsgroundsWardenExileEffect()); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
} }
@ -49,31 +42,3 @@ public final class FairgroundsWarden extends CardImpl {
return new FairgroundsWarden(this); return new FairgroundsWarden(this);
} }
} }
class FairsgroundsWardenExileEffect extends OneShotEffect {
public FairsgroundsWardenExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature an opponent controls until {this} leaves the battlefield.";
}
public FairsgroundsWardenExileEffect(final FairsgroundsWardenExileEffect effect) {
super(effect);
}
@Override
public FairsgroundsWardenExileEffect copy() {
return new FairsgroundsWardenExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
// If Fairsgrounds Warden leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.f; package mage.cards.f;
import java.util.UUID; import java.util.UUID;
@ -9,23 +8,19 @@ import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
* @author LevelX2 * @author awjackson
*/ */
public final class FaithUnbroken extends CardImpl { public final class FaithUnbroken extends CardImpl {
@ -41,13 +36,13 @@ public final class FaithUnbroken extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// When Faith Unbroken enters the battlefield, exile target creature an opponent controls until Faith Unbroken leaves the battlefield. // When Faith Unbroken enters the battlefield, exile target creature an opponent controls until Faith Unbroken leaves the battlefield.
ability = new EntersBattlefieldTriggeredAbility(new FaithUnbrokenEffect()); ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
// Enchanted creature gets +2/+2. // Enchanted creature gets +2/+2.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(2, 2, Duration.WhileOnBattlefield)));
} }
private FaithUnbroken(final FaithUnbroken card) { private FaithUnbroken(final FaithUnbroken card) {
@ -59,31 +54,3 @@ public final class FaithUnbroken extends CardImpl {
return new FaithUnbroken(this); return new FaithUnbroken(this);
} }
} }
class FaithUnbrokenEffect extends OneShotEffect {
public FaithUnbrokenEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature an opponent controls until {this} leaves the battlefield";
}
public FaithUnbrokenEffect(final FaithUnbrokenEffect effect) {
super(effect);
}
@Override
public FaithUnbrokenEffect copy() {
return new FaithUnbrokenEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Chained to the Rocks leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,7 +1,6 @@
package mage.cards.g; package mage.cards.g;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
@ -20,6 +19,7 @@ import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -90,7 +90,7 @@ class GloriousProtectorEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game); Permanent sourceObject = source.getSourcePermanentIfItStillExists(game);
if (player == null || sourceObject == null) { if (player == null || sourceObject == null) {
return false; return false;
} }

View file

@ -1,4 +1,3 @@
package mage.cards.h; package mage.cards.h;
import java.util.UUID; import java.util.UUID;
@ -7,16 +6,13 @@ import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -24,7 +20,6 @@ import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/** /**
* *
@ -44,7 +39,7 @@ public final class HixusPrisonWarden extends CardImpl {
this.addAbility(FlashAbility.getInstance()); this.addAbility(FlashAbility.getInstance());
// Whenever a creature deals combat damage to you, if Hixus, Prison Warden entered the battlefield this turn, exile that creature until Hixus leaves the battlefield. // Whenever a creature deals combat damage to you, if Hixus, Prison Warden entered the battlefield this turn, exile that creature until Hixus leaves the battlefield.
this.addAbility(new HixusPrisonWardenTriggeredAbility(new HixusPrisonWardenExileEffect())); this.addAbility(new HixusPrisonWardenTriggeredAbility());
} }
private HixusPrisonWarden(final HixusPrisonWarden card) { private HixusPrisonWarden(final HixusPrisonWarden card) {
@ -59,9 +54,10 @@ public final class HixusPrisonWarden extends CardImpl {
class HixusPrisonWardenTriggeredAbility extends TriggeredAbilityImpl { class HixusPrisonWardenTriggeredAbility extends TriggeredAbilityImpl {
public HixusPrisonWardenTriggeredAbility(Effect effect) { public HixusPrisonWardenTriggeredAbility() {
super(Zone.BATTLEFIELD, effect); super(Zone.BATTLEFIELD, new ExileUntilSourceLeavesEffect());
this.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
setTriggerPhrase("Whenever a creature deals combat damage to you, if {this} entered the battlefield this turn, ");
} }
public HixusPrisonWardenTriggeredAbility(final HixusPrisonWardenTriggeredAbility ability) { public HixusPrisonWardenTriggeredAbility(final HixusPrisonWardenTriggeredAbility ability) {
@ -97,40 +93,4 @@ class HixusPrisonWardenTriggeredAbility extends TriggeredAbilityImpl {
} }
return false; return false;
} }
@Override
public String getRule() {
return "Whenever a creature deals combat damage to you, if {this} entered the battlefield this turn, exile that creature until {this} leaves the battlefield.";
}
}
class HixusPrisonWardenExileEffect extends OneShotEffect {
public HixusPrisonWardenExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile that creature until {this} leaves the battlefield";
}
public HixusPrisonWardenExileEffect(final HixusPrisonWardenExileEffect effect) {
super(effect);
}
@Override
public HixusPrisonWardenExileEffect copy() {
return new HixusPrisonWardenExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
// If Prison Warden leaves the battlefield before its triggered ability resolves,
// the target creature won't be exiled.
if (permanent != null) {
Effect effect = new ExileTargetEffect(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName());
effect.setTargetPointer(getTargetPointer());
return effect.apply(game, source);
}
return false;
}
} }

View file

@ -81,7 +81,7 @@ class HostageTakerExileEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent card = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent card = game.getPermanent(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || card == null) { if (permanent == null || card == null) {
return false; return false;
} }

View file

@ -5,24 +5,19 @@ import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.CardUtil;
/** /**
* *
* @author fireshoes * @author awjackson
*/ */
public final class IsolationZone extends CardImpl { public final class IsolationZone extends CardImpl {
@ -38,7 +33,7 @@ public final class IsolationZone extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}");
// When Isolation Zone enters the battlefield, exile target creature or enchantment an opponent controls until Isolation Zone leaves the battlefield. // When Isolation Zone enters the battlefield, exile target creature or enchantment an opponent controls until Isolation Zone leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new IsolationZoneExileEffect()); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetPermanent(filter)); ability.addTarget(new TargetPermanent(filter));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
@ -53,31 +48,3 @@ public final class IsolationZone extends CardImpl {
return new IsolationZone(this); return new IsolationZone(this);
} }
} }
class IsolationZoneExileEffect extends OneShotEffect {
public IsolationZoneExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature or enchantment an opponent controls until {this} leaves the battlefield";
}
public IsolationZoneExileEffect(final IsolationZoneExileEffect effect) {
super(effect);
}
@Override
public IsolationZoneExileEffect copy() {
return new IsolationZoneExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Stasis Snare leaves the battlefield before its triggered ability resolves,
// the target won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -66,7 +66,7 @@ public final class LagrellaTheMagpie extends CardImpl {
class LagrellaTheMagpieEffect extends OneShotEffect { class LagrellaTheMagpieEffect extends OneShotEffect {
LagrellaTheMagpieEffect() { LagrellaTheMagpieEffect() {
super(Outcome.Benefit); super(Outcome.Exile);
staticText = "exile any number of other target creatures controlled by different players " + staticText = "exile any number of other target creatures controlled by different players " +
"until {this} leaves the battlefield. When an exiled card enters the battlefield " + "until {this} leaves the battlefield. When an exiled card enters the battlefield " +
"under your control this way, put two +1/+1 counters on it"; "under your control this way, put two +1/+1 counters on it";
@ -84,11 +84,7 @@ class LagrellaTheMagpieEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null) { if (player == null || source.getSourcePermanentIfItStillExists(game) == null) {
return false;
}
// Like other Banishing Light effects, no permanents get exiled if Lagrella is not in the battlefield when this ability resolves.
if (game.getPermanent(source.getSourceId()) == null) {
return false; return false;
} }

View file

@ -68,7 +68,7 @@ public final class MysteriousLimousine extends CardImpl {
class MysteriousLimousineEffect extends OneShotEffect { class MysteriousLimousineEffect extends OneShotEffect {
MysteriousLimousineEffect() { MysteriousLimousineEffect() {
super(Outcome.Benefit); super(Outcome.Exile);
staticText = "exile up to one other target creature until {this} leaves the battlefield. " + staticText = "exile up to one other target creature until {this} leaves the battlefield. " +
"If a creature is put into exile this way, return each other card exiled " + "If a creature is put into exile this way, return each other card exiled " +
"with {this} to the battlefield under its owner's control"; "with {this} to the battlefield under its owner's control";
@ -87,7 +87,7 @@ class MysteriousLimousineEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null) { if (player == null || permanent == null || source.getSourcePermanentIfItStillExists(game) == null) {
return false; return false;
} }
UUID exileId = CardUtil.getExileZoneId(game, source); UUID exileId = CardUtil.getExileZoneId(game, source);

View file

@ -5,14 +5,12 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.common.FilterNonlandPermanent; import mage.filter.common.FilterNonlandPermanent;
@ -20,12 +18,11 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetadjustment.TargetAdjuster;
import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
/** /**
* @author LevelX2 * @author awjackson
*/ */
public final class QuarantineField extends CardImpl { public final class QuarantineField extends CardImpl {
@ -36,7 +33,9 @@ public final class QuarantineField extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.ISOLATION.createInstance()))); this.addAbility(new EntersBattlefieldAbility(new EntersBattlefieldWithXCountersEffect(CounterType.ISOLATION.createInstance())));
// When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponent controls until Quarantine Field leaves the battlefield. // When Quarantine Field enters the battlefield, for each isolation counter on it, exile up to one target nonland permanent an opponent controls until Quarantine Field leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new QuarantineFieldEffect(), false); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()
.setText("for each isolation counter on it, exile up to one target nonland permanent an opponent controls until {this} leaves the battlefield")
);
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
ability.setTargetAdjuster(QuarantineFieldAdjuster.instance); ability.setTargetAdjuster(QuarantineFieldAdjuster.instance);
this.addAbility(ability); this.addAbility(ability);
@ -59,38 +58,10 @@ enum QuarantineFieldAdjuster implements TargetAdjuster {
public void adjustTargets(Ability ability, Game game) { public void adjustTargets(Ability ability, Game game) {
Permanent sourceObject = game.getPermanent(ability.getSourceId()); Permanent sourceObject = game.getPermanent(ability.getSourceId());
if (sourceObject != null) { if (sourceObject != null) {
int isolationCounters = sourceObject.getCounters(game).getCount(CounterType.ISOLATION); int counters = sourceObject.getCounters(game).getCount(CounterType.ISOLATION);
FilterNonlandPermanent filter = new FilterNonlandPermanent("up to " + isolationCounters + " nonland permanents controlled by an opponent"); FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent" + (counters > 1 ? "s" : "") + " an opponent controls");
filter.add(TargetController.OPPONENT.getControllerPredicate()); filter.add(TargetController.OPPONENT.getControllerPredicate());
ability.addTarget(new TargetPermanent(0, isolationCounters, filter, false)); ability.addTarget(new TargetPermanent(0, counters, filter));
} }
} }
} }
class QuarantineFieldEffect extends OneShotEffect {
public QuarantineFieldEffect() {
super(Outcome.Exile);
this.staticText = "for each isolation counter on it, exile up to one target nonland permanent an opponent controls until {this} leaves the battlefield";
}
public QuarantineFieldEffect(final QuarantineFieldEffect effect) {
super(effect);
}
@Override
public QuarantineFieldEffect copy() {
return new QuarantineFieldEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If the source permanent leaves the battlefield before its triggered ability resolves,
// the targets won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -4,30 +4,24 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.target.common.TargetAttackingOrBlockingCreature;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
/** /**
* *
* @author ciaccona007 * @author awjackson
*/ */
public final class SigridGodFavored extends CardImpl { public final class SigridGodFavored extends CardImpl {
@ -55,8 +49,8 @@ public final class SigridGodFavored extends CardImpl {
this.addAbility(new ProtectionAbility(filterGod)); this.addAbility(new ProtectionAbility(filterGod));
// When Sigrid, God-Favored enters the battlefield, exile up to one target attacking or blocking creature until Sigrid leaves the battlefield. // When Sigrid, God-Favored enters the battlefield, exile up to one target attacking or blocking creature until Sigrid leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new SigridGodFavoredExileEffect()); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetPermanent(0,1,new FilterAttackingOrBlockingCreature(), false)); ability.addTarget(new TargetAttackingOrBlockingCreature(0, 1));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
} }
@ -70,30 +64,3 @@ public final class SigridGodFavored extends CardImpl {
return new SigridGodFavored(this); return new SigridGodFavored(this);
} }
} }
class SigridGodFavoredExileEffect extends OneShotEffect {
SigridGodFavoredExileEffect() {
super(Outcome.Exile);
this.staticText = "exile up to one target attacking or blocking creature until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
}
SigridGodFavoredExileEffect(final SigridGodFavoredExileEffect effect) {
super(effect);
}
@Override
public SigridGodFavoredExileEffect copy() {
return new SigridGodFavoredExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
// If Sigrid, God-Favored leaves the battlefield before its triggered ability resolves, the target won't be exiled.
if (sourcePermanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,29 +1,23 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ComparisonType; import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ManaValuePredicate; import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.CardUtil;
/** /**
* *
* @author jeffwadsworth * @author awjackson
*/ */
public final class Silkwrap extends CardImpl { public final class Silkwrap extends CardImpl {
@ -37,8 +31,8 @@ public final class Silkwrap extends CardImpl {
public Silkwrap(UUID ownerId, CardSetInfo setInfo) { public Silkwrap(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}");
// When Silkwrap enters the battlefield, exile target creature with converted mana cost 3 or less an opponent controls until Silkwrap leaves the battlefield. // When Silkwrap enters the battlefield, exile target creature with mana value 3 or less an opponent controls until Silkwrap leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new SilkwrapEffect()); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetPermanent(filter)); ability.addTarget(new TargetPermanent(filter));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
@ -54,29 +48,3 @@ public final class Silkwrap extends CardImpl {
return new Silkwrap(this); return new Silkwrap(this);
} }
} }
class SilkwrapEffect extends OneShotEffect {
public SilkwrapEffect() {
super(Outcome.Neutral);
this.staticText = "exile target creature with mana value 3 or less an opponent controls until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
}
public SilkwrapEffect(final SilkwrapEffect effect) {
super(effect);
}
@Override
public SilkwrapEffect copy() {
return new SilkwrapEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,28 +1,22 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.ComparisonType; import mage.constants.ComparisonType;
import mage.constants.Outcome;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ToughnessPredicate; import mage.filter.predicate.mageobject.ToughnessPredicate;
import mage.game.Game; import mage.target.TargetPermanent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/** /**
* *
* @author emerald000 * @author awjackson
*/ */
public final class SuspensionField extends CardImpl { public final class SuspensionField extends CardImpl {
@ -36,11 +30,10 @@ public final class SuspensionField extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}");
// When Suspension Field enters the battlefield, you may exile target creature with toughness 3 or greater until Suspension Field leaves the battlefield. // When Suspension Field enters the battlefield, you may exile target creature with toughness 3 or greater until Suspension Field leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new SuspensionFieldExileEffect(), true); Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(), true);
ability.addTarget(new TargetCreaturePermanent(filter)); ability.addTarget(new TargetPermanent(filter));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability); this.addAbility(ability);
} }
private SuspensionField(final SuspensionField card) { private SuspensionField(final SuspensionField card) {
@ -52,30 +45,3 @@ public final class SuspensionField extends CardImpl {
return new SuspensionField(this); return new SuspensionField(this);
} }
} }
class SuspensionFieldExileEffect extends OneShotEffect {
SuspensionFieldExileEffect() {
super(Outcome.Exile);
this.staticText = "you may exile target creature with toughness 3 or greater until {this} leaves the battlefield. <i>(That creature returns under its owner's control.)</i>";
}
SuspensionFieldExileEffect(final SuspensionFieldExileEffect effect) {
super(effect);
}
@Override
public SuspensionFieldExileEffect copy() {
return new SuspensionFieldExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
// If Suspension Field leaves the battlefield before its triggered ability resolves, the target won't be exiled.
if (sourcePermanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -1,4 +1,3 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID; import java.util.UUID;
@ -12,9 +11,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterAttackingOrBlockingCreature; import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.target.common.TargetAttackingOrBlockingCreature; import mage.target.TargetPermanent;
/** /**
* *
@ -38,8 +36,8 @@ public final class TakenosCavalry extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
this.addAbility(new BushidoAbility(1)); this.addAbility(new BushidoAbility(1));
// {tap}: Takeno's Cavalry deals 1 damage to target attacking or blocking Spirit. // {tap}: Takeno's Cavalry deals 1 damage to target attacking or blocking Spirit.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new TapSourceCost()); Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(1), new TapSourceCost());
ability.addTarget(new TargetAttackingOrBlockingCreature(1, 1, filter, false)); ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -89,7 +89,7 @@ class YannikScavengingSentinelEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = source.getSourcePermanentIfItStillExists(game);
if (player == null || sourcePermanent == null if (player == null || sourcePermanent == null
|| game.getBattlefield().count(filter, source.getControllerId(), source, game) < 1) { || game.getBattlefield().count(filter, source.getControllerId(), source, game) < 1) {
return false; return false;

View file

@ -129,29 +129,6 @@ public class ExileTargetEffect extends OneShotEffect {
if (staticText != null && !staticText.isEmpty()) { if (staticText != null && !staticText.isEmpty()) {
return staticText; return staticText;
} }
StringBuilder sb = new StringBuilder(); return "exile " + getTargetPointer().describeTargets(mode.getTargets(), "that permanent");
if (mode.getTargets().isEmpty()) {
sb.append("exile that permanent"); // this will be used if the target is set by target pointer and staticText not set.
} else {
Target target;
if (targetPointer instanceof SecondTargetPointer && mode.getTargets().size() > 1) {
target = mode.getTargets().get(1);
} else {
target = mode.getTargets().get(0);
}
if (target.getNumberOfTargets() == 1) {
String targetName = target.getTargetName();
sb.append("exile ");
if (!targetName.startsWith("another")) {
sb.append("target ");
}
sb.append(targetName);
} else if (target.getNumberOfTargets() == 0 && target.getMaxNumberOfTargets() > 0) {
sb.append("exile up to ").append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(" target ").append(target.getTargetName());
} else {
sb.append("exile ").append(CardUtil.numberToText(target.getNumberOfTargets())).append(" target ").append(target.getTargetName());
}
}
return sb.toString();
} }
} }

View file

@ -1,25 +1,24 @@
package mage.target.common; package mage.target.common;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterAttackingOrBlockingCreature;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
/** /**
* *
* @author nantuko * @author awjackson
*/ */
public class TargetAttackingOrBlockingCreature extends TargetPermanent { public class TargetAttackingOrBlockingCreature extends TargetPermanent {
public TargetAttackingOrBlockingCreature() { public TargetAttackingOrBlockingCreature() {
this(1, 1, StaticFilters.FILTER_ATTACKING_OR_BLOCKING_CREATURE, false); this(1);
} }
public TargetAttackingOrBlockingCreature(int numTargets) { public TargetAttackingOrBlockingCreature(int numTargets) {
this(numTargets, numTargets, StaticFilters.FILTER_ATTACKING_OR_BLOCKING_CREATURE, false); this(numTargets, numTargets);
} }
public TargetAttackingOrBlockingCreature(int minNumTargets, int maxNumTargets, FilterAttackingOrBlockingCreature filter, boolean notTarget) { public TargetAttackingOrBlockingCreature(int minNumTargets, int maxNumTargets) {
super(minNumTargets, maxNumTargets, filter, notTarget); super(minNumTargets, maxNumTargets, maxNumTargets > 1 ? StaticFilters.FILTER_ATTACKING_OR_BLOCKING_CREATURES : StaticFilters.FILTER_ATTACKING_OR_BLOCKING_CREATURE);
} }
public TargetAttackingOrBlockingCreature(final TargetAttackingOrBlockingCreature target) { public TargetAttackingOrBlockingCreature(final TargetAttackingOrBlockingCreature target) {
@ -30,5 +29,4 @@ public class TargetAttackingOrBlockingCreature extends TargetPermanent {
public TargetAttackingOrBlockingCreature copy() { public TargetAttackingOrBlockingCreature copy() {
return new TargetAttackingOrBlockingCreature(this); return new TargetAttackingOrBlockingCreature(this);
} }
} }