From 1ccaf06366e56bd4192ba329448cf811e9712733 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Wed, 5 Jul 2023 19:23:08 -0400 Subject: [PATCH] Refactor flicker effects to single common class (#10564) * New common class for flicker target effects * Update cards to ExileThenReturnTargetEffect * process game state before returning exiled card --- .../src/mage/cards/a/AcrobaticManeuver.java | 8 +- .../src/mage/cards/a/AgainstAllOdds.java | 7 +- .../mage/cards/a/AminatouTheFateshifter.java | 6 +- Mage.Sets/src/mage/cards/b/Blur.java | 6 +- .../src/mage/cards/b/BragoKingEternal.java | 7 +- Mage.Sets/src/mage/cards/c/Cloudshift.java | 7 +- .../src/mage/cards/c/ConjurersCloset.java | 6 +- Mage.Sets/src/mage/cards/d/Displace.java | 9 +- .../src/mage/cards/d/DisplacerKitten.java | 6 +- .../mage/cards/d/DistinguishedConjurer.java | 6 +- .../src/mage/cards/e/EldraziDisplacer.java | 8 +- .../src/mage/cards/e/EmielTheBlessed.java | 6 +- Mage.Sets/src/mage/cards/e/Ephemerate.java | 6 +- .../src/mage/cards/e/EscapeProtocol.java | 8 +- Mage.Sets/src/mage/cards/f/FarTraveler.java | 6 +- .../src/mage/cards/f/FelidarGuardian.java | 6 +- Mage.Sets/src/mage/cards/f/Flicker.java | 6 +- Mage.Sets/src/mage/cards/f/FlickerOfFate.java | 6 +- .../src/mage/cards/g/GhostlyFlicker.java | 7 +- .../src/mage/cards/h/HallowedRespite.java | 7 +- .../src/mage/cards/i/IcewindStalwart.java | 6 +- .../mage/cards/i/IllusionistsStratagem.java | 7 +- .../src/mage/cards/j/JusticiarsPortal.java | 6 +- .../src/mage/cards/m/MeneldorSwiftSavior.java | 8 +- .../src/mage/cards/m/MomentaryBlink.java | 7 +- .../src/mage/cards/n/NephaliaSmuggler.java | 6 +- .../mage/cards/o/OjiTheExquisiteBlade.java | 6 +- .../src/mage/cards/p/PegasusGuardian.java | 6 +- .../src/mage/cards/r/RestorationAngel.java | 7 +- Mage.Sets/src/mage/cards/r/RuinGhost.java | 6 +- Mage.Sets/src/mage/cards/s/Scrollshift.java | 6 +- .../src/mage/cards/s/SettleBeyondReality.java | 6 +- Mage.Sets/src/mage/cards/s/SlipOnTheRing.java | 10 +- Mage.Sets/src/mage/cards/s/Soulherder.java | 6 +- .../src/mage/cards/t/TeleportationCircle.java | 6 +- .../src/mage/cards/t/ThassaDeepDwelling.java | 6 +- Mage.Sets/src/mage/cards/t/TriadOfFates.java | 6 +- .../src/mage/cards/w/WispweaverAngel.java | 8 +- .../common/ExileThenReturnTargetEffect.java | 97 +++++++++++++++++++ 39 files changed, 176 insertions(+), 174 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java b/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java index ae08938f8c5..4a46784bd21 100644 --- a/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java +++ b/Mage.Sets/src/mage/cards/a/AcrobaticManeuver.java @@ -1,9 +1,7 @@ package mage.cards.a; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -21,9 +19,7 @@ public final class AcrobaticManeuver extends CardImpl { // Exile target creature you control, then return that card to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); - + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); // Draw a card. this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).concatBy("
")); } diff --git a/Mage.Sets/src/mage/cards/a/AgainstAllOdds.java b/Mage.Sets/src/mage/cards/a/AgainstAllOdds.java index 694ab005db0..fbffce54c96 100644 --- a/Mage.Sets/src/mage/cards/a/AgainstAllOdds.java +++ b/Mage.Sets/src/mage/cards/a/AgainstAllOdds.java @@ -1,9 +1,8 @@ package mage.cards.a; import mage.abilities.Mode; -import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -46,9 +45,7 @@ public final class AgainstAllOdds extends CardImpl { // * Exile target artifact or creature you control, then return it to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetControlledPermanent(filter)); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, - false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); // * Return target artifact or creature card with mana value 3 or less from your graveyard to the battlefield. Mode mode2 = new Mode(new ReturnFromGraveyardToBattlefieldTargetEffect()); diff --git a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java index e7ac7f4a13d..a506bd4ac80 100644 --- a/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java +++ b/Mage.Sets/src/mage/cards/a/AminatouTheFateshifter.java @@ -5,8 +5,7 @@ import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.continuous.GainControlTargetEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -52,8 +51,7 @@ public class AminatouTheFateshifter extends CardImpl { this.addAbility(ability); // −1: Exile another target permanent you own, then return it to the battlefield under your control. - ability = new LoyaltyAbility(new ExileTargetForSourceEffect(), -1); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); + ability = new LoyaltyAbility(new ExileThenReturnTargetEffect(true, false), -1); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/b/Blur.java b/Mage.Sets/src/mage/cards/b/Blur.java index 0669989b23a..e376a57e0d8 100644 --- a/Mage.Sets/src/mage/cards/b/Blur.java +++ b/Mage.Sets/src/mage/cards/b/Blur.java @@ -1,8 +1,7 @@ package mage.cards.b; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -19,8 +18,7 @@ public final class Blur extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Exile target creature you control, then return that card to the battlefield under its owner's control. - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); // Draw a card. diff --git a/Mage.Sets/src/mage/cards/b/BragoKingEternal.java b/Mage.Sets/src/mage/cards/b/BragoKingEternal.java index f73264ed752..79024cff742 100644 --- a/Mage.Sets/src/mage/cards/b/BragoKingEternal.java +++ b/Mage.Sets/src/mage/cards/b/BragoKingEternal.java @@ -3,15 +3,13 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnFromExileEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; import mage.constants.SuperType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; @@ -42,9 +40,8 @@ public final class BragoKingEternal extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Brago, King Eternal deals combat damage to a player, exile any number of target nonland permanents you control, then return those cards to the battlefield under their owner's control. - Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ExileTargetForSourceEffect().setText("exile any number of target nonland permanents you control"), false); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ExileThenReturnTargetEffect(false, true), false); ability.addTarget(new TargetPermanent(0, Integer.MAX_VALUE, filter, false)); - ability.addEffect(new ReturnFromExileEffect(Zone.BATTLEFIELD, ", then return those cards to the battlefield under their owner's control")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/Cloudshift.java b/Mage.Sets/src/mage/cards/c/Cloudshift.java index 97627071cf9..13f8fca4604 100644 --- a/Mage.Sets/src/mage/cards/c/Cloudshift.java +++ b/Mage.Sets/src/mage/cards/c/Cloudshift.java @@ -1,8 +1,6 @@ package mage.cards.c; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,8 +18,7 @@ public final class Cloudshift extends CardImpl { // Exile target creature you control, then return that card to the battlefield under your control. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(true, true)); } private Cloudshift(final Cloudshift card) { diff --git a/Mage.Sets/src/mage/cards/c/ConjurersCloset.java b/Mage.Sets/src/mage/cards/c/ConjurersCloset.java index 9ed28dc8360..47f77b67428 100644 --- a/Mage.Sets/src/mage/cards/c/ConjurersCloset.java +++ b/Mage.Sets/src/mage/cards/c/ConjurersCloset.java @@ -2,8 +2,7 @@ package mage.cards.c; import mage.abilities.Ability; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,8 +19,7 @@ public final class ConjurersCloset extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); // At the beginning of your end step, you may exile target creature you control, then return that card to the battlefield under your control. - Ability ability = new BeginningOfYourEndStepTriggeredAbility(new ExileTargetForSourceEffect(), true); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); + Ability ability = new BeginningOfYourEndStepTriggeredAbility(new ExileThenReturnTargetEffect(true, true), true); ability.addTarget(new TargetControlledCreaturePermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/d/Displace.java b/Mage.Sets/src/mage/cards/d/Displace.java index bb2de0b6542..fe45adc664d 100644 --- a/Mage.Sets/src/mage/cards/d/Displace.java +++ b/Mage.Sets/src/mage/cards/d/Displace.java @@ -1,8 +1,6 @@ package mage.cards.d; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -21,10 +19,7 @@ public final class Displace extends CardImpl { // Exile up to two target creatures you control, then return those cards to the battlefield under their owner's control. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 2, StaticFilters.FILTER_CONTROLLED_CREATURES, false)); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setText(", then return those cards to the battlefield under their owner's control") - ); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); } private Displace(final Displace card) { diff --git a/Mage.Sets/src/mage/cards/d/DisplacerKitten.java b/Mage.Sets/src/mage/cards/d/DisplacerKitten.java index 787d62defbb..98be0124d97 100644 --- a/Mage.Sets/src/mage/cards/d/DisplacerKitten.java +++ b/Mage.Sets/src/mage/cards/d/DisplacerKitten.java @@ -3,8 +3,7 @@ package mage.cards.d; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -38,9 +37,8 @@ public final class DisplacerKitten extends CardImpl { // Avoidance — Whenever you cast a noncreature spell, exile up to one target nonland permanent you control, then return that card to the battlefield under its owner's control. Ability ability = new SpellCastControllerTriggeredAbility( - new ExileTargetForSourceEffect(), StaticFilters.FILTER_SPELL_A_NON_CREATURE, false + new ExileThenReturnTargetEffect(false, true), StaticFilters.FILTER_SPELL_A_NON_CREATURE, false ); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability.withFlavorWord("Avoidance")); } diff --git a/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java b/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java index 68ec7d14c47..a0af654cbe2 100644 --- a/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java +++ b/Mage.Sets/src/mage/cards/d/DistinguishedConjurer.java @@ -6,9 +6,8 @@ import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -47,9 +46,8 @@ public final class DistinguishedConjurer extends CardImpl { this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), filter)); // {4}{W}, {T}: Exile another target creature you control, then return it to the battlefield under its owner’s control. - Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{4}{W}")); + Ability ability = new SimpleActivatedAbility(new ExileThenReturnTargetEffect(false, false), new ManaCostsImpl<>("{4}{W}")); ability.addCost(new TapSourceCost()); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); ability.addTarget(new TargetControlledCreaturePermanent(filter2)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EldraziDisplacer.java b/Mage.Sets/src/mage/cards/e/EldraziDisplacer.java index f1c88491256..b2399147e84 100644 --- a/Mage.Sets/src/mage/cards/e/EldraziDisplacer.java +++ b/Mage.Sets/src/mage/cards/e/EldraziDisplacer.java @@ -4,14 +4,13 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.DevoidAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import mage.constants.PutCards; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; import mage.target.common.TargetCreaturePermanent; @@ -32,8 +31,7 @@ public final class EldraziDisplacer extends CardImpl { this.addAbility(new DevoidAbility(this.color)); // {2}{C}: Exile another target creature, then return it to the battlefield tapped under its owner's control. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{2}{C}")); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(true, false, "it").concatBy(", then")); + Ability ability = new SimpleActivatedAbility(new ExileThenReturnTargetEffect(false, false, PutCards.BATTLEFIELD_TAPPED), new ManaCostsImpl<>("{2}{C}")); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/e/EmielTheBlessed.java b/Mage.Sets/src/mage/cards/e/EmielTheBlessed.java index 710b32d10de..fc44d28178a 100644 --- a/Mage.Sets/src/mage/cards/e/EmielTheBlessed.java +++ b/Mage.Sets/src/mage/cards/e/EmielTheBlessed.java @@ -8,8 +8,7 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -45,8 +44,7 @@ public final class EmielTheBlessed extends CardImpl { this.toughness = new MageInt(4); // {3}: Exile another target creature you control, then return it to the battlefield under its owner's control. - Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new GenericManaCost(3)); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + Ability ability = new SimpleActivatedAbility(new ExileThenReturnTargetEffect(false, false), new GenericManaCost(3)); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/e/Ephemerate.java b/Mage.Sets/src/mage/cards/e/Ephemerate.java index c832b3dd081..8d86c5e5e3b 100644 --- a/Mage.Sets/src/mage/cards/e/Ephemerate.java +++ b/Mage.Sets/src/mage/cards/e/Ephemerate.java @@ -1,7 +1,6 @@ package mage.cards.e; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.ReboundAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -20,8 +19,7 @@ public final class Ephemerate extends CardImpl { // Exile target creature you control, then return it to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); // Rebound this.addAbility(new ReboundAbility()); diff --git a/Mage.Sets/src/mage/cards/e/EscapeProtocol.java b/Mage.Sets/src/mage/cards/e/EscapeProtocol.java index a67aebae611..4eee372bacf 100644 --- a/Mage.Sets/src/mage/cards/e/EscapeProtocol.java +++ b/Mage.Sets/src/mage/cards/e/EscapeProtocol.java @@ -4,8 +4,7 @@ import mage.abilities.common.CycleControllerTriggeredAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.DoWhenCostPaid; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -36,11 +35,8 @@ public final class EscapeProtocol extends CardImpl { // Whenever you cycle a card, you may pay {1}. When you do, exile target artifact or creature you control, then return it to the battlefield under its owner's control. ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( - new ExileTargetForSourceEffect(), false, - "exile target artifact or creature you control, " + - "then return it to the battlefield under its owner's control" + new ExileThenReturnTargetEffect(false, false), false ); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false)); ability.addTarget(new TargetPermanent(filter)); this.addAbility(new CycleControllerTriggeredAbility(new DoWhenCostPaid( ability, new GenericManaCost(1), "Pay {1}?" diff --git a/Mage.Sets/src/mage/cards/f/FarTraveler.java b/Mage.Sets/src/mage/cards/f/FarTraveler.java index bcce9cd1bf7..9f4e2efbadf 100644 --- a/Mage.Sets/src/mage/cards/f/FarTraveler.java +++ b/Mage.Sets/src/mage/cards/f/FarTraveler.java @@ -3,8 +3,7 @@ package mage.cards.f; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -36,9 +35,8 @@ public final class FarTraveler extends CardImpl { // Commander creatures you own have "At the beginning of your end step, exile up to one target tapped creature you control, then return it to the battlefield under its owner's control." Ability ability = new BeginningOfEndStepTriggeredAbility( - new ExileTargetForSourceEffect(), TargetController.YOU, false + new ExileThenReturnTargetEffect(false, false), TargetController.YOU, false ); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(new SimpleStaticAbility(new GainAbilityAllEffect( ability, Duration.WhileOnBattlefield, diff --git a/Mage.Sets/src/mage/cards/f/FelidarGuardian.java b/Mage.Sets/src/mage/cards/f/FelidarGuardian.java index 347d4660233..c1ea8144bf0 100644 --- a/Mage.Sets/src/mage/cards/f/FelidarGuardian.java +++ b/Mage.Sets/src/mage/cards/f/FelidarGuardian.java @@ -3,8 +3,7 @@ package mage.cards.f; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -28,8 +27,7 @@ public final class FelidarGuardian extends CardImpl { this.toughness = new MageInt(4); // When Felidar Guardian enters the battlefield, you may exile another target permanent you control, then return that card to the battlefield under its owner's control. - Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect(), true); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileThenReturnTargetEffect(false, true), true); ability.addTarget(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_PERMANENT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/Flicker.java b/Mage.Sets/src/mage/cards/f/Flicker.java index 9f5555f5942..c08482da82e 100644 --- a/Mage.Sets/src/mage/cards/f/Flicker.java +++ b/Mage.Sets/src/mage/cards/f/Flicker.java @@ -1,7 +1,6 @@ package mage.cards.f; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -27,8 +26,7 @@ public final class Flicker extends CardImpl { // Exile target nontoken permanent, then return it to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetPermanent(filter)); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); } private Flicker(final Flicker card) { diff --git a/Mage.Sets/src/mage/cards/f/FlickerOfFate.java b/Mage.Sets/src/mage/cards/f/FlickerOfFate.java index 351c015790d..21356da3cdf 100644 --- a/Mage.Sets/src/mage/cards/f/FlickerOfFate.java +++ b/Mage.Sets/src/mage/cards/f/FlickerOfFate.java @@ -1,7 +1,6 @@ package mage.cards.f; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -29,8 +28,7 @@ public final class FlickerOfFate extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Exile target creature or enchantment, then return it to the battlefield under its owner's control. - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); this.getSpellAbility().addTarget(new TargetPermanent(filter)); } diff --git a/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java b/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java index cd72b525bbb..173e4b69a72 100644 --- a/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java +++ b/Mage.Sets/src/mage/cards/g/GhostlyFlicker.java @@ -1,8 +1,7 @@ package mage.cards.g; import java.util.UUID; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -29,9 +28,7 @@ public final class GhostlyFlicker extends CardImpl { // Exile two target artifacts, creatures, and/or lands you control, then return those cards to the battlefield under your control. this.getSpellAbility().addTarget(new TargetPermanent(2, filter)); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect() - .setText(", then return those cards to the battlefield under your control")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(true, true)); } private GhostlyFlicker(final GhostlyFlicker card) { diff --git a/Mage.Sets/src/mage/cards/h/HallowedRespite.java b/Mage.Sets/src/mage/cards/h/HallowedRespite.java index 51aea2aeef4..b37272c60bc 100644 --- a/Mage.Sets/src/mage/cards/h/HallowedRespite.java +++ b/Mage.Sets/src/mage/cards/h/HallowedRespite.java @@ -5,15 +5,13 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; -import mage.constants.TimingRule; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.Predicates; @@ -37,8 +35,7 @@ public final class HallowedRespite extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{U}"); // Exile target nonlegendary creature, then return it to the battlefield under its owner's control. If it entered under your control, put a +1/+1 counter on it. Otherwise, tap it. - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); this.getSpellAbility().addEffect(new HallowedRespiteEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/i/IcewindStalwart.java b/Mage.Sets/src/mage/cards/i/IcewindStalwart.java index 5ee1b95f20f..3f9ed8923a2 100644 --- a/Mage.Sets/src/mage/cards/i/IcewindStalwart.java +++ b/Mage.Sets/src/mage/cards/i/IcewindStalwart.java @@ -3,8 +3,7 @@ package mage.cards.i; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -37,8 +36,7 @@ public final class IcewindStalwart extends CardImpl { this.toughness = new MageInt(3); // Protection Fighting Style — When Icewind Stalwart enters the battlefield, exile up to one target non-Warrior creature you control, then return it to the battlefield under its owner's control. - Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect()); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileThenReturnTargetEffect(false, false)); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability.withFlavorWord("Protection Fighting Style")); } diff --git a/Mage.Sets/src/mage/cards/i/IllusionistsStratagem.java b/Mage.Sets/src/mage/cards/i/IllusionistsStratagem.java index 3d2c6a49c41..5c4992102ba 100644 --- a/Mage.Sets/src/mage/cards/i/IllusionistsStratagem.java +++ b/Mage.Sets/src/mage/cards/i/IllusionistsStratagem.java @@ -1,8 +1,7 @@ package mage.cards.i; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -20,9 +19,7 @@ public final class IllusionistsStratagem extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); // Exile up to two target creatures you control, then return those cards to the battlefield under their owner's control. - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setText(", then return those cards to the battlefield under their owner's control")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, 2, StaticFilters.FILTER_CONTROLLED_CREATURES, false)); diff --git a/Mage.Sets/src/mage/cards/j/JusticiarsPortal.java b/Mage.Sets/src/mage/cards/j/JusticiarsPortal.java index cbee0a1e1a0..23ab2f3476a 100644 --- a/Mage.Sets/src/mage/cards/j/JusticiarsPortal.java +++ b/Mage.Sets/src/mage/cards/j/JusticiarsPortal.java @@ -3,8 +3,7 @@ package mage.cards.j; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.cards.CardImpl; @@ -61,8 +60,7 @@ class JusticiarsPortalEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { UUID targetId = source.getFirstTarget(); - new ExileTargetForSourceEffect().apply(game, source); - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).apply(game, source); + new ExileThenReturnTargetEffect(false, true).apply(game, source); ContinuousEffect effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn); effect.setTargetPointer(new FixedTarget(targetId, game)); game.addEffect(effect, source); diff --git a/Mage.Sets/src/mage/cards/m/MeneldorSwiftSavior.java b/Mage.Sets/src/mage/cards/m/MeneldorSwiftSavior.java index e166d3b1d53..436b7e5c874 100644 --- a/Mage.Sets/src/mage/cards/m/MeneldorSwiftSavior.java +++ b/Mage.Sets/src/mage/cards/m/MeneldorSwiftSavior.java @@ -4,16 +4,13 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnFromExileEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.constants.*; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.Predicates; import mage.target.TargetPermanent; /** @@ -41,9 +38,8 @@ public final class MeneldorSwiftSavior extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // Whenever Meneldor, Swift Savior deals combat damage to a player, exile up to one target creature you own, then return it to the battlefield under your control. - Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ExileTargetForSourceEffect().setText("exile up to one target creature you own"), false); + Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ExileThenReturnTargetEffect(true, false), false); ability.addTarget(new TargetPermanent(0, 1, filter)); - ability.addEffect(new ReturnFromExileEffect(Zone.BATTLEFIELD, ", then return it to the battlefield under your control.")); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MomentaryBlink.java b/Mage.Sets/src/mage/cards/m/MomentaryBlink.java index 2883aceda59..37d2d53e1b5 100644 --- a/Mage.Sets/src/mage/cards/m/MomentaryBlink.java +++ b/Mage.Sets/src/mage/cards/m/MomentaryBlink.java @@ -1,13 +1,11 @@ package mage.cards.m; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlashbackAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.TimingRule; import mage.target.common.TargetControlledCreaturePermanent; import java.util.UUID; @@ -22,8 +20,7 @@ public final class MomentaryBlink extends CardImpl { // Exile target creature you control, then return it to the battlefield under its owner's control. this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); // Flashback {3}{U} this.addAbility(new FlashbackAbility(this, new ManaCostsImpl<>("{3}{U}"))); diff --git a/Mage.Sets/src/mage/cards/n/NephaliaSmuggler.java b/Mage.Sets/src/mage/cards/n/NephaliaSmuggler.java index 360a9c506ab..d0b1f0c19bc 100644 --- a/Mage.Sets/src/mage/cards/n/NephaliaSmuggler.java +++ b/Mage.Sets/src/mage/cards/n/NephaliaSmuggler.java @@ -5,8 +5,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -38,9 +37,8 @@ public final class NephaliaSmuggler extends CardImpl { this.toughness = new MageInt(1); // {3}{U}, {tap}: Exile another target creature you control, then return that card to the battlefield under your control. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{3}{U}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileThenReturnTargetEffect(true, true), new ManaCostsImpl<>("{3}{U}")); ability.addCost(new TapSourceCost()); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); ability.addTarget(new TargetControlledCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/OjiTheExquisiteBlade.java b/Mage.Sets/src/mage/cards/o/OjiTheExquisiteBlade.java index 20e6a099cfb..6045987357f 100644 --- a/Mage.Sets/src/mage/cards/o/OjiTheExquisiteBlade.java +++ b/Mage.Sets/src/mage/cards/o/OjiTheExquisiteBlade.java @@ -4,9 +4,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.CastSecondSpellTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,8 +36,7 @@ public final class OjiTheExquisiteBlade extends CardImpl { this.addAbility(ability); // Whenever you cast your second spell each turn, exile up to one target creature you control, then return it to the battlefield under its owner's control. - ability = new CastSecondSpellTriggeredAbility(new ExileTargetForSourceEffect()); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + ability = new CastSecondSpellTriggeredAbility(new ExileThenReturnTargetEffect(false, false)); ability.addTarget(new TargetControlledCreaturePermanent(0, 1)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PegasusGuardian.java b/Mage.Sets/src/mage/cards/p/PegasusGuardian.java index 955907501b8..683623c2a5f 100644 --- a/Mage.Sets/src/mage/cards/p/PegasusGuardian.java +++ b/Mage.Sets/src/mage/cards/p/PegasusGuardian.java @@ -4,8 +4,7 @@ import mage.MageInt; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.condition.common.RevoltCondition; import mage.abilities.effects.common.CreateTokenEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.AdventureCard; import mage.cards.CardSetInfo; @@ -41,8 +40,7 @@ public final class PegasusGuardian extends AdventureCard { // Rescue the Foal // Exile target creature you control, then return that card to the battlefield under its owner's control. - this.getSpellCard().getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellCard().getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); + this.getSpellCard().getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, true)); this.getSpellCard().getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/r/RestorationAngel.java b/Mage.Sets/src/mage/cards/r/RestorationAngel.java index baf9f6e2c2d..c1bdede38bd 100644 --- a/Mage.Sets/src/mage/cards/r/RestorationAngel.java +++ b/Mage.Sets/src/mage/cards/r/RestorationAngel.java @@ -1,12 +1,10 @@ - package mage.cards.r; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -41,8 +39,7 @@ public final class RestorationAngel extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Restoration Angel enters the battlefield, you may exile target non-Angel creature you control, then return that card to the battlefield under your control - Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect(), true); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileThenReturnTargetEffect(true, true), true); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/r/RuinGhost.java b/Mage.Sets/src/mage/cards/r/RuinGhost.java index 6e55f6735ff..8ca1d14eeba 100644 --- a/Mage.Sets/src/mage/cards/r/RuinGhost.java +++ b/Mage.Sets/src/mage/cards/r/RuinGhost.java @@ -5,8 +5,7 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -30,9 +29,8 @@ public final class RuinGhost extends CardImpl { this.toughness = new MageInt(1); // {W}, {T}: Exile target land you control, then return it to the battlefield under your control. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{W}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileThenReturnTargetEffect(true, false), new ManaCostsImpl<>("{W}")); ability.addCost(new TapSourceCost()); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect(false, "it").concatBy(", then")); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/Scrollshift.java b/Mage.Sets/src/mage/cards/s/Scrollshift.java index 24e85965d14..68f11cf6c37 100644 --- a/Mage.Sets/src/mage/cards/s/Scrollshift.java +++ b/Mage.Sets/src/mage/cards/s/Scrollshift.java @@ -1,8 +1,7 @@ package mage.cards.s; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -32,8 +31,7 @@ public final class Scrollshift extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}"); // Exile up to one target artifact, creature, or enchantment you control, then return it to the battlefield under its owner's control. - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - this.getSpellAbility().addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(false, false)); this.getSpellAbility().addTarget(new TargetPermanent(0, 1, filter)); // Draw a card. diff --git a/Mage.Sets/src/mage/cards/s/SettleBeyondReality.java b/Mage.Sets/src/mage/cards/s/SettleBeyondReality.java index fa08a601f1a..464adb4c0cb 100644 --- a/Mage.Sets/src/mage/cards/s/SettleBeyondReality.java +++ b/Mage.Sets/src/mage/cards/s/SettleBeyondReality.java @@ -2,8 +2,7 @@ package mage.cards.s; import mage.abilities.Mode; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -30,8 +29,7 @@ public final class SettleBeyondReality extends CardImpl { this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL)); // • Exile target creature you control, then return it to the battlefield under its owner's control. - Mode mode = new Mode(new ExileTargetForSourceEffect()); - mode.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); + Mode mode = new Mode(new ExileThenReturnTargetEffect(false, false)); mode.addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addMode(mode); } diff --git a/Mage.Sets/src/mage/cards/s/SlipOnTheRing.java b/Mage.Sets/src/mage/cards/s/SlipOnTheRing.java index 9a698e2bbe0..236b405d3b2 100644 --- a/Mage.Sets/src/mage/cards/s/SlipOnTheRing.java +++ b/Mage.Sets/src/mage/cards/s/SlipOnTheRing.java @@ -2,14 +2,12 @@ package mage.cards.s; import java.util.UUID; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnFromExileEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.keyword.TheRingTemptsYouEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.target.common.TargetCreaturePermanent; @@ -28,11 +26,9 @@ public final class SlipOnTheRing extends CardImpl { public SlipOnTheRing(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); - // Exile target creature you own + // Exile target creature you own, then return it to the battlefield under your control. this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); - this.getSpellAbility().addEffect(new ExileTargetForSourceEffect()); - // , then return it to the battlefield under your control. - this.getSpellAbility().addEffect(new ReturnFromExileEffect(Zone.BATTLEFIELD, ", then return it to the battlefield under your control.")); + this.getSpellAbility().addEffect(new ExileThenReturnTargetEffect(true, false)); // The Ring tempts you. this.getSpellAbility().addEffect(new TheRingTemptsYouEffect()); } diff --git a/Mage.Sets/src/mage/cards/s/Soulherder.java b/Mage.Sets/src/mage/cards/s/Soulherder.java index 04fbe50e58a..16a0d2c0684 100644 --- a/Mage.Sets/src/mage/cards/s/Soulherder.java +++ b/Mage.Sets/src/mage/cards/s/Soulherder.java @@ -4,8 +4,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.common.ZoneChangeTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,9 +47,8 @@ public final class Soulherder extends CardImpl { // At the beginning of your end step, you may exile another target creature you control, then return that card to the battlefield under its owner's control. Ability ability = new BeginningOfEndStepTriggeredAbility( - new ExileTargetForSourceEffect(), TargetController.YOU, true + new ExileThenReturnTargetEffect(false, true), TargetController.YOU, true ); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); ability.addTarget(new TargetControlledCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TeleportationCircle.java b/Mage.Sets/src/mage/cards/t/TeleportationCircle.java index 478b70d4495..00fff6f7ab2 100644 --- a/Mage.Sets/src/mage/cards/t/TeleportationCircle.java +++ b/Mage.Sets/src/mage/cards/t/TeleportationCircle.java @@ -2,8 +2,7 @@ package mage.cards.t; import mage.abilities.Ability; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -33,8 +32,7 @@ public final class TeleportationCircle extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); // At the beginning of your end step, exile up to one target artifact or creature you control, then return that card to the battlefield under its owner's control. - Ability ability = new BeginningOfYourEndStepTriggeredAbility(new ExileTargetForSourceEffect(), false); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); + Ability ability = new BeginningOfYourEndStepTriggeredAbility(new ExileThenReturnTargetEffect(false, true), false); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/ThassaDeepDwelling.java b/Mage.Sets/src/mage/cards/t/ThassaDeepDwelling.java index be503cae300..157acd6fdff 100644 --- a/Mage.Sets/src/mage/cards/t/ThassaDeepDwelling.java +++ b/Mage.Sets/src/mage/cards/t/ThassaDeepDwelling.java @@ -7,8 +7,7 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.dynamicvalue.common.DevotionCount; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.effects.common.continuous.LoseCreatureTypeSourceEffect; import mage.abilities.keyword.IndestructibleAbility; @@ -56,10 +55,9 @@ public final class ThassaDeepDwelling extends CardImpl { // At the beginning of your end step, exile up to one other target creature you control, then return that card to the battlefield under your control. Ability ability = new BeginningOfEndStepTriggeredAbility( - new ExileTargetForSourceEffect(), + new ExileThenReturnTargetEffect(true, true), TargetController.YOU, false ); - ability.addEffect(new ReturnToBattlefieldUnderYourControlTargetEffect().concatBy(", then")); ability.addTarget(new TargetPermanent( 0, 1, filterOther, false )); diff --git a/Mage.Sets/src/mage/cards/t/TriadOfFates.java b/Mage.Sets/src/mage/cards/t/TriadOfFates.java index 7f87af9bc8c..a16839eae60 100644 --- a/Mage.Sets/src/mage/cards/t/TriadOfFates.java +++ b/Mage.Sets/src/mage/cards/t/TriadOfFates.java @@ -7,8 +7,7 @@ import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -54,11 +53,10 @@ public final class TriadOfFates extends CardImpl { this.addAbility(ability); // {W}, {T}: Exile target creature that has a fate counter on it, then return it to the battlefield under its owner's control. - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{W}")); + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileThenReturnTargetEffect(false, false), new ManaCostsImpl<>("{W}")); ability.addCost(new TapSourceCost()); target = new TargetCreaturePermanent(filterCounter); ability.addTarget(target); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false, "it").concatBy(", then")); this.addAbility(ability); // {B}, {T}: Exile target creature that has a fate counter on it. Its controller draws two cards. diff --git a/Mage.Sets/src/mage/cards/w/WispweaverAngel.java b/Mage.Sets/src/mage/cards/w/WispweaverAngel.java index 207d082e621..bc7e0315329 100644 --- a/Mage.Sets/src/mage/cards/w/WispweaverAngel.java +++ b/Mage.Sets/src/mage/cards/w/WispweaverAngel.java @@ -3,8 +3,7 @@ package mage.cards.w; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.common.ExileTargetForSourceEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileThenReturnTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,9 +36,8 @@ public final class WispweaverAngel extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Wispweaver Angel enters the battlefield, you may exile another target creature you control, then return that card to the battlefield under its owner's control. - Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetForSourceEffect(), true); - ability.addEffect(new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false).concatBy(", then")); - ability.addTarget(new TargetControlledCreaturePermanent(1, 1, filter, false)); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileThenReturnTargetEffect(false, true), true); + ability.addTarget(new TargetControlledCreaturePermanent(filter)); this.addAbility(ability); } diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java new file mode 100644 index 00000000000..4973d7c61c5 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java @@ -0,0 +1,97 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.constants.Outcome; +import mage.constants.PutCards; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @author xenohedron + */ +public class ExileThenReturnTargetEffect extends OneShotEffect { + + private final boolean yourControl; + private final boolean textThatCard; + private final PutCards putCards; + + public ExileThenReturnTargetEffect(boolean yourControl, boolean textThatCard) { + this(yourControl, textThatCard, PutCards.BATTLEFIELD); + } + + public ExileThenReturnTargetEffect(boolean yourControl, boolean textThatCard, PutCards putCards) { + super(Outcome.Benefit); + this.yourControl = yourControl; + this.textThatCard = textThatCard; + this.putCards = putCards; + } + + protected ExileThenReturnTargetEffect(final ExileThenReturnTargetEffect effect) { + super(effect); + this.putCards = effect.putCards; + this.yourControl = effect.yourControl; + this.textThatCard = effect.textThatCard; + } + + @Override + public ExileThenReturnTargetEffect copy() { + return new ExileThenReturnTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Set toFlicker = new LinkedHashSet<>(); + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent == null) { + continue; + } + toFlicker.add(permanent); + } + if (controller == null || toFlicker.isEmpty()) { + return false; + } + controller.moveCards(toFlicker, Zone.EXILED, source, game); + game.getState().processAction(game); + for (Card card : toFlicker) { + putCards.moveCard( + yourControl ? controller : game.getPlayer(card.getOwnerId()), + card.getMainCard(), source, game, "card"); + } + return true; + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder("exile "); + sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that permanent")); + sb.append(", then return "); + if (getTargetPointer().isPlural(mode.getTargets())) { + sb.append(textThatCard ? "those cards " : "them"); + sb.append(putCards.getMessage(false, false).replace("onto", "to")); + sb.append(" under "); + sb.append(this.yourControl ? "your" : "their owner's"); + } else { + sb.append(textThatCard ? "that card " : "it"); + sb.append(putCards.getMessage(false, false).replace("onto", "to")); + sb.append(" under "); + sb.append(this.yourControl ? "your" : "its owner's"); + } + sb.append(" control"); + return sb.toString(); + } + +}