refactor: common classes for LeaveBattlefieldExile (#11248)

This commit is contained in:
xenohedron 2023-10-02 18:42:25 -04:00 committed by GitHub
parent 9d1ad256a5
commit ba135abc78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 200 additions and 628 deletions

View file

@ -1,4 +1,3 @@
package mage.cards.d;
import java.util.UUID;
@ -8,8 +7,8 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
@ -22,8 +21,6 @@ import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@ -49,7 +46,7 @@ public final class DreamsOfTheDead extends CardImpl {
// {1}{U}: Return target white or black creature card from your graveyard to the battlefield. That creature gains "Cumulative upkeep {2}." If the creature would leave the battlefield, exile it instead of putting it anywhere else.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DreamsOfTheDeadEffect(), new ManaCostsImpl<>("{1}{U}"));
ability.addTarget(new TargetCardInYourGraveyard(filter));
ability.addEffect(new DreamsOfTheDeadReplacementEffect());
ability.addEffect(new LeaveBattlefieldExileTargetReplacementEffect("the creature"));
this.addAbility(ability);
}
@ -65,7 +62,7 @@ public final class DreamsOfTheDead extends CardImpl {
class DreamsOfTheDeadEffect extends OneShotEffect {
public DreamsOfTheDeadEffect() {
DreamsOfTheDeadEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Return target white or black creature card from your graveyard to the battlefield. That creature gains \"Cumulative upkeep {2}.\"";
}
@ -97,46 +94,3 @@ class DreamsOfTheDeadEffect extends OneShotEffect {
return false;
}
}
class DreamsOfTheDeadReplacementEffect extends ReplacementEffectImpl {
DreamsOfTheDeadReplacementEffect() {
super(Duration.OneUse, Outcome.Tap);
staticText = "If the creature would leave the battlefield, exile it instead of putting it anywhere else";
}
private DreamsOfTheDeadReplacementEffect(final DreamsOfTheDeadReplacementEffect effect) {
super(effect);
}
@Override
public DreamsOfTheDeadReplacementEffect copy() {
return new DreamsOfTheDeadReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -5,9 +5,9 @@ import mage.abilities.Ability;
import mage.abilities.common.MagecraftAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.ZoneChangeTriggeredAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileSourceReplacementEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -34,7 +34,7 @@ public final class ElementalExpressionist extends CardImpl {
// Magecraft Whenever you cast or copy an instant or sorcery spell, choose target creature you control. Until end of turn, it gains "If this creature would leave the battlefield, exile it instead of putting it anywhere else" and "When you exile this creature, create a 4/4 blue and red Elemental creature token."
Ability ability = new MagecraftAbility(new GainAbilityTargetEffect(
new SimpleStaticAbility(new ElementalExpressionistReplacementEffect()),
new SimpleStaticAbility(new LeaveBattlefieldExileSourceReplacementEffect("this creature")),
Duration.EndOfTurn, "choose target creature you control. Until end of turn, " +
"it gains \"If this creature would leave the battlefield, exile it instead of putting it anywhere else\""
));
@ -56,46 +56,6 @@ public final class ElementalExpressionist extends CardImpl {
}
}
class ElementalExpressionistReplacementEffect extends ReplacementEffectImpl {
ElementalExpressionistReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Tap);
staticText = "If this creature would leave the battlefield, exile it instead of putting it anywhere else";
}
private ElementalExpressionistReplacementEffect(final ElementalExpressionistReplacementEffect effect) {
super(effect);
}
@Override
public ElementalExpressionistReplacementEffect copy() {
return new ElementalExpressionistReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getTargetId().equals(source.getSourceId())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}
class ElementalExpressionistTriggeredAbility extends ZoneChangeTriggeredAbility {
ElementalExpressionistTriggeredAbility() {

View file

@ -1,22 +1,15 @@
package mage.cards.f;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldWithCounterTargetEffect;
import mage.abilities.effects.common.TakeTheInitiativeEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.EscapeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.target.common.TargetCardInGraveyard;
import java.util.UUID;
@ -33,7 +26,7 @@ public final class FromTheCatacombs extends CardImpl {
// Return target creature card from a graveyard to the battlefield with a corpse counter on it. If that creature would leave the battlefield, exile it instead of putting it anywhere else.
this.getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldWithCounterTargetEffect(CounterType.CORPSE.createInstance()));
this.getSpellAbility().addEffect(new FromTheCatacombsEffect());
this.getSpellAbility().addEffect(new LeaveBattlefieldExileTargetReplacementEffect("that creature"));
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter));
// You take the initiative.
@ -52,46 +45,3 @@ public final class FromTheCatacombs extends CardImpl {
return new FromTheCatacombs(this);
}
}
class FromTheCatacombsEffect extends ReplacementEffectImpl {
FromTheCatacombsEffect() {
super(Duration.Custom, Outcome.Exile);
staticText = "If that creature would leave the battlefield, exile it instead of putting it anywhere else";
}
private FromTheCatacombsEffect(final FromTheCatacombsEffect effect) {
super(effect);
}
@Override
public FromTheCatacombsEffect copy() {
return new FromTheCatacombsEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -4,20 +4,16 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.CompositeCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileSourceReplacementEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
@ -45,7 +41,7 @@ public class GethThaneOfContracts extends CardImpl {
);
ability.addCost(new TapSourceCost());
ability.addEffect(new GainAbilityTargetEffect(
new SimpleStaticAbility(new GethThaneOfContractsReplacementEffect()),
new SimpleStaticAbility(new LeaveBattlefieldExileSourceReplacementEffect("this creature")),
Duration.Custom
).setText("It gains \"If this creature would leave the battlefield, exile it instead of putting it anywhere else.\""));
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
@ -61,39 +57,3 @@ public class GethThaneOfContracts extends CardImpl {
return new GethThaneOfContracts(this);
}
}
class GethThaneOfContractsReplacementEffect extends ReplacementEffectImpl {
public GethThaneOfContractsReplacementEffect() {
super(Duration.Custom, Outcome.Exile);
this.staticText = "If {this} would leave the battlefield, exile it instead of putting it anywhere else.";
}
private GethThaneOfContractsReplacementEffect(final GethThaneOfContractsReplacementEffect effect) {
super(effect);
}
@Override
public GethThaneOfContractsReplacementEffect copy() {
return new GethThaneOfContractsReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
UUID targetId = zEvent.getTargetId();
return targetId != null && targetId.equals(source.getSourceId())
&& zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() != Zone.EXILED;
}
}

View file

@ -5,9 +5,9 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
@ -18,8 +18,6 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInOpponentsGraveyard;
@ -41,7 +39,7 @@ public final class GruesomeEncore extends CardImpl {
this.getSpellAbility().addEffect(new GruesomeEncoreEffect());
// Exile it at the beginning of the next end step. If that creature would leave the battlefield, exile it instead of putting it anywhere else.
this.getSpellAbility().addEffect(new GruesomeEncoreReplacementEffect());
this.getSpellAbility().addEffect(new LeaveBattlefieldExileTargetReplacementEffect("that creature"));
this.getSpellAbility().addTarget(new TargetCardInOpponentsGraveyard(filter));
}
@ -96,43 +94,3 @@ class GruesomeEncoreEffect extends OneShotEffect {
return false;
}
}
class GruesomeEncoreReplacementEffect extends ReplacementEffectImpl {
GruesomeEncoreReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Tap);
staticText = "If that creature would leave the battlefield, exile it instead of putting it anywhere else";
}
private GruesomeEncoreReplacementEffect(final GruesomeEncoreReplacementEffect effect) {
super(effect);
}
@Override
public GruesomeEncoreReplacementEffect copy() {
return new GruesomeEncoreReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -8,7 +8,7 @@ import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
@ -20,8 +20,6 @@ import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@ -95,7 +93,7 @@ class IsarethTheAwakenerCreateReflexiveTriggerEffect extends OneShotEffect {
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new IsarethTheAwakenerEffect(), false, rule
);
ability.addEffect(new IsarethTheAwakenerReplacementEffect());
ability.addEffect(new LeaveBattlefieldExileTargetReplacementEffect("that creature"));
ability.addTarget(new TargetCardInYourGraveyard(makeFilter(costX)));
game.fireReflexiveTriggeredAbility(ability, source);
return true;
@ -141,45 +139,3 @@ class IsarethTheAwakenerEffect extends OneShotEffect {
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
}
class IsarethTheAwakenerReplacementEffect extends ReplacementEffectImpl {
IsarethTheAwakenerReplacementEffect() {
super(Duration.Custom, Outcome.Exile);
}
private IsarethTheAwakenerReplacementEffect(final IsarethTheAwakenerReplacementEffect effect) {
super(effect);
}
@Override
public IsarethTheAwakenerReplacementEffect copy() {
return new IsarethTheAwakenerReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -1,6 +1,5 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
@ -9,32 +8,24 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.ReplacementEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.cards.*;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author LevelX2
@ -66,7 +57,7 @@ public final class KheruLichLord extends CardImpl {
class KheruLichLordEffect extends OneShotEffect {
public KheruLichLordEffect() {
KheruLichLordEffect() {
super(Outcome.Benefit);
this.staticText = "return a creature card at random from your graveyard to the battlefield. It gains flying, trample, and haste. Exile that card at the beginning of the next end step. If that card would leave the battlefield, exile it instead of putting it anywhere else";
}
@ -108,7 +99,7 @@ class KheruLichLordEffect extends OneShotEffect {
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
game.addDelayedTriggeredAbility(delayedAbility, source);
KheruLichLordReplacementEffect replacementEffect = new KheruLichLordReplacementEffect();
ReplacementEffect replacementEffect = new LeaveBattlefieldExileTargetReplacementEffect("that card");
replacementEffect.setTargetPointer(fixedTarget);
game.addEffect(replacementEffect, source);
}
@ -119,47 +110,3 @@ class KheruLichLordEffect extends OneShotEffect {
return false;
}
}
class KheruLichLordReplacementEffect extends ReplacementEffectImpl {
KheruLichLordReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Exile);
staticText = "If that card would leave the battlefield, exile it instead of putting it anywhere else";
}
private KheruLichLordReplacementEffect(final KheruLichLordReplacementEffect effect) {
super(effect);
}
@Override
public KheruLichLordReplacementEffect copy() {
return new KheruLichLordReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& event.getTargetId().equals(getTargetPointer().getFirst(game, source))
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -1,25 +1,23 @@
package mage.cards.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.costadjusters.DomainAdjuster;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.ReturnSourceFromGraveyardToBattlefieldEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileSourceReplacementEffect;
import mage.abilities.hint.common.DomainHint;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import java.util.UUID;
/**
*
@ -47,7 +45,7 @@ public final class LlanowarGreenwidow extends CardImpl {
new ManaCostsImpl<>("{7}{G}")
);
ability.addEffect(new GainAbilitySourceEffect(
new SimpleStaticAbility(new LlanowarGreenwidowReplacementEffect()),
new SimpleStaticAbility(new LeaveBattlefieldExileSourceReplacementEffect("this permanent")),
Duration.Custom
).setText("It gains \"If this permanent would leave the battlefield, exile it instead of putting it anywhere else.\""));
ability.addEffect(new InfoEffect("This ability costs {1} less to activate " +
@ -67,39 +65,3 @@ public final class LlanowarGreenwidow extends CardImpl {
return new LlanowarGreenwidow(this);
}
}
class LlanowarGreenwidowReplacementEffect extends ReplacementEffectImpl {
public LlanowarGreenwidowReplacementEffect() {
super(Duration.Custom, Outcome.Exile);
this.staticText = "If {this} would leave the battlefield, exile it instead of putting it anywhere else.";
}
private LlanowarGreenwidowReplacementEffect(final LlanowarGreenwidowReplacementEffect effect) {
super(effect);
}
@Override
public LlanowarGreenwidowReplacementEffect copy() {
return new LlanowarGreenwidowReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
UUID targetId = zEvent.getTargetId();
return targetId != null && targetId.equals(source.getSourceId())
&& zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() != Zone.EXILED;
}
}

View file

@ -1,7 +1,5 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
@ -9,153 +7,105 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.FilterSpell;
import mage.filter.common.FilterHistoricSpell;
import mage.filter.common.FilterPermanentCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.game.events.ZoneChangeEvent;
import java.util.UUID;
public final class MoiraAndTeshar extends CardImpl {
private static final FilterSpell filter = new FilterHistoricSpell();
private static final FilterPermanentCard targetFilter = new FilterPermanentCard(
"nonland permanent card from your graveyard");
private static final FilterSpell filter = new FilterHistoricSpell();
private static final FilterPermanentCard targetFilter = new FilterPermanentCard(
"nonland permanent card from your graveyard");
public MoiraAndTeshar(UUID ownerId, CardSetInfo setInfo) {
public MoiraAndTeshar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[] { CardType.CREATURE }, "{3}{W}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.BIRD);
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.BIRD);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever you cast a historic spell, return target nonland permanent card from
// your graveyard to the battlefield. It gains haste. Exile it at the beginning
// of the next end step.
Ability ability = new SpellCastControllerTriggeredAbility(new MoiraAndTesharEffect(), filter, false);
ability.addTarget(new TargetCardInYourGraveyard(targetFilter));
// Whenever you cast a historic spell, return target nonland permanent card from
// your graveyard to the battlefield. It gains haste. Exile it at the beginning
// of the next end step.
Ability ability = new SpellCastControllerTriggeredAbility(new MoiraAndTesharEffect(), filter, false);
ability.addTarget(new TargetCardInYourGraveyard(targetFilter));
// If it would leave the battlefield, exile it instead of putting it anywhere
// else. (Artifacts, legendaries, and Sagas are historic.)
ability.addEffect(new MoiraAndTesharReplacementEffect());
this.addAbility(ability);
}
// If it would leave the battlefield, exile it instead of putting it anywhere
// else. (Artifacts, legendaries, and Sagas are historic.)
ability.addEffect(new LeaveBattlefieldExileTargetReplacementEffect("it"));
this.addAbility(ability);
}
private MoiraAndTeshar(final MoiraAndTeshar card) {
super(card);
}
private MoiraAndTeshar(final MoiraAndTeshar card) {
super(card);
}
@Override
public MoiraAndTeshar copy() {
return new MoiraAndTeshar(this);
}
@Override
public MoiraAndTeshar copy() {
return new MoiraAndTeshar(this);
}
}
class MoiraAndTesharEffect extends OneShotEffect {
MoiraAndTesharEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Return target nonland permanent card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step";
}
MoiraAndTesharEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Return target nonland permanent card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step";
}
private MoiraAndTesharEffect(final MoiraAndTesharEffect effect) {
super(effect);
}
private MoiraAndTesharEffect(final MoiraAndTesharEffect effect) {
super(effect);
}
@Override
public MoiraAndTesharEffect copy() {
return new MoiraAndTesharEffect(this);
}
@Override
public MoiraAndTesharEffect copy() {
return new MoiraAndTesharEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null) {
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
// It gains haste
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
// Exile at begin of next end step
ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD);
exileEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
game.addDelayedTriggeredAbility(delayedAbility, source);
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null) {
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
Permanent permanent = game.getPermanent(card.getId());
if (permanent != null) {
// It gains haste
ContinuousEffect effect = new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
// Exile at begin of next end step
ExileTargetEffect exileEffect = new ExileTargetEffect(null, null, Zone.BATTLEFIELD);
exileEffect.setTargetPointer(new FixedTarget(permanent, game));
DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect);
game.addDelayedTriggeredAbility(delayedAbility, source);
}
}
return true;
}
}
return true;
return false;
}
return false;
}
}
class MoiraAndTesharReplacementEffect extends ReplacementEffectImpl {
MoiraAndTesharReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Tap);
staticText = "If it would leave the battlefield, exile it instead of putting it anywhere else";
}
private MoiraAndTesharReplacementEffect(final MoiraAndTesharReplacementEffect effect) {
super(effect);
}
@Override
public MoiraAndTesharReplacementEffect copy() {
return new MoiraAndTesharReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -7,9 +7,9 @@ import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.MillCardsTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileSourceReplacementEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
@ -18,8 +18,6 @@ import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
@ -110,48 +108,8 @@ class RealmbreakerTheInvasionTreeEffect extends OneShotEffect {
return false;
}
game.addEffect(new GainAbilityTargetEffect(
new SimpleStaticAbility(new RealmbreakerTheInvasionTreeReplacementEffect()), Duration.Custom
new SimpleStaticAbility(new LeaveBattlefieldExileSourceReplacementEffect("this land")), Duration.Custom
).setTargetPointer(new FixedTarget(permanent, game)), source);
return true;
}
}
class RealmbreakerTheInvasionTreeReplacementEffect extends ReplacementEffectImpl {
RealmbreakerTheInvasionTreeReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Tap);
staticText = "If this land would leave the battlefield, exile it instead of putting it anywhere else";
}
private RealmbreakerTheInvasionTreeReplacementEffect(final RealmbreakerTheInvasionTreeReplacementEffect effect) {
super(effect);
}
@Override
public RealmbreakerTheInvasionTreeReplacementEffect copy() {
return new RealmbreakerTheInvasionTreeReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getTargetId().equals(source.getSourceId())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -8,9 +8,9 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileSourceReplacementEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -22,8 +22,6 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.SharesCardTypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@ -92,7 +90,7 @@ class SpiritSistersCallDoIfEffect extends OneShotEffect {
class SpiritSistersCallReturnToBattlefieldEffect extends OneShotEffect {
public SpiritSistersCallReturnToBattlefieldEffect() {
SpiritSistersCallReturnToBattlefieldEffect() {
super(Outcome.PutCardInPlay);
}
@ -116,46 +114,12 @@ class SpiritSistersCallReturnToBattlefieldEffect extends OneShotEffect {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(new SimpleStaticAbility(new SpiritSistersCallReplacementEffect()), Duration.Custom);
ContinuousEffect effect = new GainAbilityTargetEffect(
new SimpleStaticAbility(new LeaveBattlefieldExileSourceReplacementEffect("this permanent")),
Duration.Custom);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
return true;
}
}
class SpiritSistersCallReplacementEffect extends ReplacementEffectImpl {
public SpiritSistersCallReplacementEffect() {
super(Duration.WhileOnBattlefield, Outcome.Exile);
this.staticText = "If {this} would leave the battlefield, exile it instead of putting it anywhere else";
}
private SpiritSistersCallReplacementEffect(final SpiritSistersCallReplacementEffect effect) {
super(effect);
}
@Override
public SpiritSistersCallReplacementEffect copy() {
return new SpiritSistersCallReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
UUID targetId = zEvent.getTargetId();
return targetId != null && targetId.equals(source.getSourceId())
&& zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() != Zone.EXILED;
}
}

View file

@ -9,10 +9,10 @@ import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.replacement.LeaveBattlefieldExileTargetReplacementEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.Card;
@ -21,8 +21,6 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
@ -54,7 +52,7 @@ public final class WhipOfErebos extends CardImpl {
);
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
ability.addEffect(new WhipOfErebosReplacementEffect());
ability.addEffect(new LeaveBattlefieldExileTargetReplacementEffect("it"));
this.addAbility(ability);
}
@ -108,46 +106,3 @@ class WhipOfErebosEffect extends OneShotEffect {
return false;
}
}
class WhipOfErebosReplacementEffect extends ReplacementEffectImpl {
WhipOfErebosReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Tap);
staticText = "If it would leave the battlefield, exile it instead of putting it anywhere else";
}
private WhipOfErebosReplacementEffect(final WhipOfErebosReplacementEffect effect) {
super(effect);
}
@Override
public WhipOfErebosReplacementEffect copy() {
return new WhipOfErebosReplacementEffect(this);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getFirstTarget())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED) {
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
}

View file

@ -0,0 +1,49 @@
package mage.abilities.effects.common.replacement;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
/**
* @author xenohedron
*/
public class LeaveBattlefieldExileSourceReplacementEffect extends ReplacementEffectImpl {
public LeaveBattlefieldExileSourceReplacementEffect(String description) {
super(Duration.WhileOnBattlefield, Outcome.Exile);
staticText = "If " + description + " would leave the battlefield, exile it instead of putting it anywhere else";
}
protected LeaveBattlefieldExileSourceReplacementEffect(final LeaveBattlefieldExileSourceReplacementEffect effect) {
super(effect);
}
@Override
public LeaveBattlefieldExileSourceReplacementEffect copy() {
return new LeaveBattlefieldExileSourceReplacementEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return source.getSourceId().equals(event.getTargetId())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED;
}
}

View file

@ -0,0 +1,49 @@
package mage.abilities.effects.common.replacement;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
/**
* @author xenohedron
*/
public class LeaveBattlefieldExileTargetReplacementEffect extends ReplacementEffectImpl {
public LeaveBattlefieldExileTargetReplacementEffect(String description) {
super(Duration.OneUse, Outcome.Exile);
staticText = "If " + description + " would leave the battlefield, exile it instead of putting it anywhere else";
}
protected LeaveBattlefieldExileTargetReplacementEffect(final LeaveBattlefieldExileTargetReplacementEffect effect) {
super(effect);
}
@Override
public LeaveBattlefieldExileTargetReplacementEffect copy() {
return new LeaveBattlefieldExileTargetReplacementEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
((ZoneChangeEvent) event).setToZone(Zone.EXILED);
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return getTargetPointer().getTargets(game, source).contains(event.getTargetId())
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getToZone() != Zone.EXILED;
}
}