From 4d6644d095f21622af84a5ba779c208f5131d903 Mon Sep 17 00:00:00 2001 From: xenohedron Date: Tue, 4 Jul 2023 20:38:59 -0400 Subject: [PATCH] Cleanup: ExileUntilSourceLeavesEffect (#10527) * Refactor OnLeaveReturnExiledAbility to accommodate hand zone as well as battlefield * Cleanup Brain Maggot and Kitesail Freebooter * Refactor to include delayed trigger with main effect * minor cleanup * merge fix * further adjustments * Cleanup Valki, God of Lies * fix test choices --- .../mage/cards/a/AbdelAdrianGorionsWard.java | 4 +- .../cards/a/AlabasterHostIntercessor.java | 3 - .../mage/cards/a/AlignedHedronNetwork.java | 5 +- .../src/mage/cards/a/AngelOfCondemnation.java | 3 - .../src/mage/cards/a/AngelOfSanctions.java | 3 - Mage.Sets/src/mage/cards/a/AnnexSentry.java | 3 - .../src/mage/cards/b/BanisherPriest.java | 3 - .../src/mage/cards/b/BanishingLight.java | 3 - Mage.Sets/src/mage/cards/b/Banishment.java | 5 +- .../src/mage/cards/b/BishopOfBinding.java | 10 +- Mage.Sets/src/mage/cards/b/BorrowedTime.java | 3 - Mage.Sets/src/mage/cards/b/BrainMaggot.java | 104 +++------------ Mage.Sets/src/mage/cards/b/BrutalCathar.java | 3 - Mage.Sets/src/mage/cards/c/CastOut.java | 3 - .../src/mage/cards/c/ChainedToTheRocks.java | 3 - .../src/mage/cards/c/ChainsOfCustody.java | 3 - .../src/mage/cards/c/CircleOfConfinement.java | 3 - .../src/mage/cards/c/CitizensArrest.java | 3 - Mage.Sets/src/mage/cards/c/ColossalWhale.java | 3 - .../src/mage/cards/c/ConclaveTribunal.java | 3 - .../src/mage/cards/c/ConstableOfTheRealm.java | 3 - .../src/mage/cards/c/ConstrictingSliver.java | 3 - .../src/mage/cards/c/ConsulateCrackdown.java | 5 +- .../src/mage/cards/d/DeputyOfDetention.java | 5 +- .../src/mage/cards/f/FairgroundsWarden.java | 3 - Mage.Sets/src/mage/cards/f/FaithUnbroken.java | 4 - Mage.Sets/src/mage/cards/g/GOTOJAIL.java | 11 +- .../src/mage/cards/g/GelatinousCube.java | 3 - Mage.Sets/src/mage/cards/g/GlassCasket.java | 3 - .../src/mage/cards/g/GloriousProtector.java | 5 +- Mage.Sets/src/mage/cards/g/GraspOfFate.java | 3 - Mage.Sets/src/mage/cards/g/GraspingGiant.java | 3 - .../src/mage/cards/h/HieromancersCage.java | 3 - .../src/mage/cards/h/HixusPrisonWarden.java | 4 - Mage.Sets/src/mage/cards/h/HostageTaker.java | 5 +- Mage.Sets/src/mage/cards/i/InTheTrenches.java | 3 - Mage.Sets/src/mage/cards/i/IsolationZone.java | 3 - .../src/mage/cards/i/IxalansBinding.java | 3 - .../src/mage/cards/j/JourneyToOblivion.java | 3 - .../src/mage/cards/k/KitesailFreebooter.java | 98 ++------------ .../src/mage/cards/l/LagrellaTheMagpie.java | 5 +- .../src/mage/cards/l/LeylineBinding.java | 3 - .../src/mage/cards/l/LumberingBattlement.java | 13 +- .../src/mage/cards/l/LunarchInquisitors.java | 3 - .../src/mage/cards/m/MysteriousLimousine.java | 5 +- Mage.Sets/src/mage/cards/o/OnThinIce.java | 3 - Mage.Sets/src/mage/cards/o/Ossification.java | 5 - Mage.Sets/src/mage/cards/p/PhantomSteed.java | 3 - Mage.Sets/src/mage/cards/p/PortableHole.java | 3 - .../src/mage/cards/p/PrayerOfBinding.java | 3 - Mage.Sets/src/mage/cards/p/PrisonRealm.java | 3 - .../src/mage/cards/q/QuarantineField.java | 3 - Mage.Sets/src/mage/cards/s/SealAway.java | 3 - .../src/mage/cards/s/SealFromExistence.java | 3 - Mage.Sets/src/mage/cards/s/ShireShirriff.java | 5 +- .../src/mage/cards/s/SigridGodFavored.java | 3 - Mage.Sets/src/mage/cards/s/Silkwrap.java | 3 - Mage.Sets/src/mage/cards/s/StasisSnare.java | 3 - Mage.Sets/src/mage/cards/s/StaticNet.java | 3 - .../src/mage/cards/s/SuspensionField.java | 3 - .../src/mage/cards/t/TemporaryLockdown.java | 14 +- Mage.Sets/src/mage/cards/t/ThopterArrest.java | 3 - .../src/mage/cards/t/TouchTheSpiritRealm.java | 3 - Mage.Sets/src/mage/cards/t/TrapjawTyrant.java | 4 - .../src/mage/cards/v/ValkiGodOfLies.java | 122 ++++-------------- .../cards/y/YannikScavengingSentinel.java | 4 +- .../ModalDoubleFacedCardsTest.java | 4 - .../test/cards/single/chk/UbaMaskTest.java | 2 - .../cards/single/khm/ValkiGodOfLiesTest.java | 25 ++++ ...y.java => OnLeaveReturnExiledAbility.java} | 24 ++-- .../common/ExileUntilSourceLeavesEffect.java | 28 +++- 71 files changed, 168 insertions(+), 489 deletions(-) rename Mage/src/main/java/mage/abilities/common/delayed/{OnLeaveReturnExiledToBattlefieldAbility.java => OnLeaveReturnExiledAbility.java} (82%) diff --git a/Mage.Sets/src/mage/cards/a/AbdelAdrianGorionsWard.java b/Mage.Sets/src/mage/cards/a/AbdelAdrianGorionsWard.java index ddd3f386043..9d3bfcfa184 100644 --- a/Mage.Sets/src/mage/cards/a/AbdelAdrianGorionsWard.java +++ b/Mage.Sets/src/mage/cards/a/AbdelAdrianGorionsWard.java @@ -4,7 +4,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ChooseABackgroundAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -99,7 +99,7 @@ class AbdelAdrianGorionsWardEffect extends OneShotEffect { if (count > 0) { new SoldierToken().putOntoBattlefield(count, game, source); } - game.addDelayedTriggeredAbility(new OnLeaveReturnExiledToBattlefieldAbility(), source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/a/AlabasterHostIntercessor.java b/Mage.Sets/src/mage/cards/a/AlabasterHostIntercessor.java index 6737e855e10..714606d99fe 100644 --- a/Mage.Sets/src/mage/cards/a/AlabasterHostIntercessor.java +++ b/Mage.Sets/src/mage/cards/a/AlabasterHostIntercessor.java @@ -3,9 +3,7 @@ package mage.cards.a; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.PlainscyclingAbility; import mage.cards.CardImpl; @@ -32,7 +30,6 @@ public final class AlabasterHostIntercessor extends CardImpl { // When Alabaster Host Intercessor enters the battlefield, exile target creature an opponent controls until Alabaster Host Intercessor leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Plainscycling {2} diff --git a/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java b/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java index 44f3f17f562..1e1a40a93c2 100644 --- a/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java +++ b/Mage.Sets/src/mage/cards/a/AlignedHedronNetwork.java @@ -6,9 +6,8 @@ import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -79,7 +78,7 @@ class AlignedHedronNetworkExileEffect extends OneShotEffect { if (toExile.isEmpty()) { return false; } controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); - new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); return true; diff --git a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java index 8dc2b1e9770..c96a6ef1840 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java @@ -4,12 +4,10 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.common.ExertSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.keyword.FlyingAbility; @@ -60,7 +58,6 @@ public final class AngelOfCondemnation extends CardImpl { ability.addCost(new TapSourceCost()); ability.addCost(new ExertSourceCost()); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/a/AngelOfSanctions.java b/Mage.Sets/src/mage/cards/a/AngelOfSanctions.java index 4f00110627b..0b719a9d9de 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfSanctions.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfSanctions.java @@ -5,9 +5,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.EmbalmAbility; import mage.abilities.keyword.FlyingAbility; @@ -37,7 +35,6 @@ public final class AngelOfSanctions extends CardImpl { // When Angel of Sanctions enters the battlefield, you may exile target nonland permanent an opponent controls until Angel of Sanctions leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(), true); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Embalm {5}{W} diff --git a/Mage.Sets/src/mage/cards/a/AnnexSentry.java b/Mage.Sets/src/mage/cards/a/AnnexSentry.java index e45e09ea29f..b0768507065 100644 --- a/Mage.Sets/src/mage/cards/a/AnnexSentry.java +++ b/Mage.Sets/src/mage/cards/a/AnnexSentry.java @@ -3,8 +3,6 @@ package mage.cards.a; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.ToxicAbility; import mage.cards.CardImpl; @@ -49,7 +47,6 @@ public final class AnnexSentry extends CardImpl { // When Annex Sentry enters the battlefield, exile target artifact or creature an opponent controls with mana value 3 or less until Annex Sentry leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BanisherPriest.java b/Mage.Sets/src/mage/cards/b/BanisherPriest.java index 8594c76aae8..1541e8f6367 100644 --- a/Mage.Sets/src/mage/cards/b/BanisherPriest.java +++ b/Mage.Sets/src/mage/cards/b/BanisherPriest.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -29,7 +27,6 @@ public final class BanisherPriest extends CardImpl { // When Banisher Priest enters the battlefield, exile target creature an opponent controls until Banisher Priest leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BanishingLight.java b/Mage.Sets/src/mage/cards/b/BanishingLight.java index 77a53c3108d..64698770bb7 100644 --- a/Mage.Sets/src/mage/cards/b/BanishingLight.java +++ b/Mage.Sets/src/mage/cards/b/BanishingLight.java @@ -3,8 +3,6 @@ package mage.cards.b; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -24,7 +22,6 @@ public final class BanishingLight extends CardImpl { // When Banishing Light enters the battlefield, exile target nonland permanent an opponent controls until Banishing Light leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/Banishment.java b/Mage.Sets/src/mage/cards/b/Banishment.java index 0eec3d2f046..53055c83af4 100644 --- a/Mage.Sets/src/mage/cards/b/Banishment.java +++ b/Mage.Sets/src/mage/cards/b/Banishment.java @@ -2,9 +2,8 @@ package mage.cards.b; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -94,7 +93,7 @@ class BanishmentEffect extends OneShotEffect { if (!toExile.isEmpty()) { controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); - new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); } return true; } diff --git a/Mage.Sets/src/mage/cards/b/BishopOfBinding.java b/Mage.Sets/src/mage/cards/b/BishopOfBinding.java index ba8519aeb0f..872dd1a5aa7 100644 --- a/Mage.Sets/src/mage/cards/b/BishopOfBinding.java +++ b/Mage.Sets/src/mage/cards/b/BishopOfBinding.java @@ -5,11 +5,10 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.cards.Card; @@ -44,7 +43,6 @@ public final class BishopOfBinding extends CardImpl { // When Bishop of Binding enters the battlefield, exile target creature an opponent controls until Bishop of Binding leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new BishopOfBindingExileEffect()); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Whenever Bishop of Binding attacks, target Vampire gets +X/+X until end of turn, where X is the power of the exiled card. @@ -85,7 +83,11 @@ class BishopOfBindingExileEffect extends OneShotEffect { // If this leaves the battlefield before its triggered ability resolves, // the target creature won't be exiled. if (permanent != null) { - return new ExileTargetEffect(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName()).apply(game, source); + new ExileTargetEffect( + CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName() + ).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/b/BorrowedTime.java b/Mage.Sets/src/mage/cards/b/BorrowedTime.java index d575c08eadc..f76ab6df201 100644 --- a/Mage.Sets/src/mage/cards/b/BorrowedTime.java +++ b/Mage.Sets/src/mage/cards/b/BorrowedTime.java @@ -2,8 +2,6 @@ package mage.cards.b; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -25,7 +23,6 @@ public final class BorrowedTime extends CardImpl { // When Borrowed Time enters the battlefield, exile target nonland permanent an opponent controls until Borrowed Time leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/b/BrainMaggot.java b/Mage.Sets/src/mage/cards/b/BrainMaggot.java index 108af829b73..121077abe6f 100644 --- a/Mage.Sets/src/mage/cards/b/BrainMaggot.java +++ b/Mage.Sets/src/mage/cards/b/BrainMaggot.java @@ -1,29 +1,28 @@ - package mage.cards.b; -import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; -import mage.game.ExileZone; 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; import mage.target.common.TargetOpponent; -import mage.util.CardUtil; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @@ -41,7 +40,6 @@ public final class BrainMaggot extends CardImpl { // When Brain Maggot enters the battlefield, target opponent reveals their hand and you choose a nonland card from it. Exile that card until Brain Maggot leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new BrainMaggotExileEffect()); ability.addTarget(new TargetOpponent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new BrainMaggotReturnExiledCardAbility())); this.addAbility(ability); } @@ -57,12 +55,12 @@ public final class BrainMaggot extends CardImpl { class BrainMaggotExileEffect extends OneShotEffect { - public BrainMaggotExileEffect() { + BrainMaggotExileEffect() { super(Outcome.Benefit); this.staticText = "target opponent reveals their hand and you choose a nonland card from it. Exile that card until {this} leaves the battlefield"; } - public BrainMaggotExileEffect(final BrainMaggotExileEffect effect) { + private BrainMaggotExileEffect(final BrainMaggotExileEffect effect) { super(effect); } @@ -84,10 +82,13 @@ class BrainMaggotExileEffect extends OneShotEffect { TargetCard target = new TargetCard(Zone.HAND, filter); if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, source, game)) { Card card = opponent.getHand().get(target.getFirstTarget(), game); - // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. - if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { - controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source, game, Zone.HAND, true); + if (card == null) { + return true; } + // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. + Effect effect = new ExileUntilSourceLeavesEffect(Zone.HAND); + effect.setTargetPointer(new FixedTarget(card, game)); + return effect.apply(game, source); } } return true; @@ -96,74 +97,3 @@ class BrainMaggotExileEffect extends OneShotEffect { } } - -/** - * Returns the exiled card as source permanent leaves battlefield Uses no stack - * - * @author LevelX2 - */ -class BrainMaggotReturnExiledCardAbility extends DelayedTriggeredAbility { - - public BrainMaggotReturnExiledCardAbility() { - super(new BrainMaggotReturnExiledCardEffect(), Duration.OneUse); - this.usesStack = false; - this.setRuleVisible(false); - } - - public BrainMaggotReturnExiledCardAbility(final BrainMaggotReturnExiledCardAbility ability) { - super(ability); - } - - @Override - public BrainMaggotReturnExiledCardAbility copy() { - return new BrainMaggotReturnExiledCardAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(this.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - return true; - } - } - return false; - } -} - -class BrainMaggotReturnExiledCardEffect extends OneShotEffect { - - public BrainMaggotReturnExiledCardEffect() { - super(Outcome.Benefit); - this.staticText = "Return exiled nonland card to its owner's hand"; - } - - public BrainMaggotReturnExiledCardEffect(final BrainMaggotReturnExiledCardEffect effect) { - super(effect); - } - - @Override - public BrainMaggotReturnExiledCardEffect copy() { - return new BrainMaggotReturnExiledCardEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && controller != null) { - ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (exile != null && sourcePermanent != null) { - controller.moveCards(exile, Zone.HAND, source, game); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BrutalCathar.java b/Mage.Sets/src/mage/cards/b/BrutalCathar.java index ca77a3e0bf1..12eb86f0834 100644 --- a/Mage.Sets/src/mage/cards/b/BrutalCathar.java +++ b/Mage.Sets/src/mage/cards/b/BrutalCathar.java @@ -3,8 +3,6 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.TransformsOrEntersTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.DayboundAbility; import mage.cards.CardImpl; @@ -35,7 +33,6 @@ public final class BrutalCathar extends CardImpl { new ExileUntilSourceLeavesEffect(), false ).setTriggerPhrase("When this creature enters the battlefield or transforms into {this}, "); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Daybound diff --git a/Mage.Sets/src/mage/cards/c/CastOut.java b/Mage.Sets/src/mage/cards/c/CastOut.java index 4b162b424f6..e2170824cef 100644 --- a/Mage.Sets/src/mage/cards/c/CastOut.java +++ b/Mage.Sets/src/mage/cards/c/CastOut.java @@ -3,9 +3,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.CyclingAbility; import mage.abilities.keyword.FlashAbility; @@ -30,7 +28,6 @@ public final class CastOut extends CardImpl { // When Cast Out enters the battlefield, exile target nonland permanent an opponent controls until Cast Out leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Cycling {W} diff --git a/Mage.Sets/src/mage/cards/c/ChainedToTheRocks.java b/Mage.Sets/src/mage/cards/c/ChainedToTheRocks.java index cb19b8605d2..08ed0dc1f50 100644 --- a/Mage.Sets/src/mage/cards/c/ChainedToTheRocks.java +++ b/Mage.Sets/src/mage/cards/c/ChainedToTheRocks.java @@ -3,9 +3,7 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -43,7 +41,6 @@ public final class ChainedToTheRocks extends CardImpl { // When Chained to the Rocks enters the battlefield, exile target creature an opponent controls until Chained to the Rocks leaves the battlefield. (That creature returns under its owner's control.) ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java b/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java index c42c59ed255..b7d0b686cd5 100644 --- a/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java +++ b/Mage.Sets/src/mage/cards/c/ChainsOfCustody.java @@ -3,10 +3,8 @@ package mage.cards.c; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.keyword.EnchantAbility; @@ -41,7 +39,6 @@ public final class ChainsOfCustody extends CardImpl { //exile until leaves the battlefield Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); //more than just creatures - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // ward 2 diff --git a/Mage.Sets/src/mage/cards/c/CircleOfConfinement.java b/Mage.Sets/src/mage/cards/c/CircleOfConfinement.java index b9163a4754d..6cf0daf23f3 100644 --- a/Mage.Sets/src/mage/cards/c/CircleOfConfinement.java +++ b/Mage.Sets/src/mage/cards/c/CircleOfConfinement.java @@ -5,8 +5,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; @@ -44,7 +42,6 @@ public final class CircleOfConfinement extends CardImpl { // When Circle of Confinement enters the battlefield, exile target creature an opponent controls with mana value 3 or less until Circle of Confinement leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Whenever an opponent casts a Vampire spell with the same name as a card exiled with Circle of Confinement, you gain 2 life. diff --git a/Mage.Sets/src/mage/cards/c/CitizensArrest.java b/Mage.Sets/src/mage/cards/c/CitizensArrest.java index 464975c9980..0692ca301b5 100644 --- a/Mage.Sets/src/mage/cards/c/CitizensArrest.java +++ b/Mage.Sets/src/mage/cards/c/CitizensArrest.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -33,7 +31,6 @@ public final class CitizensArrest extends CardImpl { // When Citizen's Arrest enters the battlefield, exile target creature or planeswalker an opponent controls until Citizen's Arrest leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ColossalWhale.java b/Mage.Sets/src/mage/cards/c/ColossalWhale.java index cdffc0cff63..147a8fdb5c7 100644 --- a/Mage.Sets/src/mage/cards/c/ColossalWhale.java +++ b/Mage.Sets/src/mage/cards/c/ColossalWhale.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.IslandwalkAbility; import mage.cards.CardImpl; @@ -42,7 +40,6 @@ public final class ColossalWhale extends CardImpl { // Whenever Colossal Whale attacks, you may exile target creature defending player controls until Colossal Whale leaves the battlefield. Ability ability = new AttacksTriggeredAbility(new ExileUntilSourceLeavesEffect(), true); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ConclaveTribunal.java b/Mage.Sets/src/mage/cards/c/ConclaveTribunal.java index 880190eb966..a68f16370f7 100644 --- a/Mage.Sets/src/mage/cards/c/ConclaveTribunal.java +++ b/Mage.Sets/src/mage/cards/c/ConclaveTribunal.java @@ -3,8 +3,6 @@ package mage.cards.c; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.ConvokeAbility; import mage.cards.CardImpl; @@ -28,7 +26,6 @@ public final class ConclaveTribunal extends CardImpl { // When Conclave Tribunal enters the battlefield, exile target nonland permanent an opponent controls until Conclave Tribunal leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ConstableOfTheRealm.java b/Mage.Sets/src/mage/cards/c/ConstableOfTheRealm.java index 1f775e8ebf9..d3c73f0eec7 100644 --- a/Mage.Sets/src/mage/cards/c/ConstableOfTheRealm.java +++ b/Mage.Sets/src/mage/cards/c/ConstableOfTheRealm.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.OneOrMoreCountersAddedTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.constants.SubType; import mage.abilities.keyword.RenownAbility; @@ -43,7 +41,6 @@ public final class ConstableOfTheRealm extends CardImpl { // Whenever one or more +1/+1 counters are put on Constable of the Realm, exile up to one other target nonland permanent until Constable of the Realm leaves the battlefield. Ability ability = new OneOrMoreCountersAddedTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(0, 1, filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java index 727dbf7a72b..b8756d69712 100644 --- a/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java +++ b/Mage.Sets/src/mage/cards/c/ConstrictingSliver.java @@ -5,8 +5,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; import mage.cards.CardImpl; @@ -32,7 +30,6 @@ public final class ConstrictingSliver extends CardImpl { // until this creature leaves the battlefield." Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(), true); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_ALL_SLIVERS) diff --git a/Mage.Sets/src/mage/cards/c/ConsulateCrackdown.java b/Mage.Sets/src/mage/cards/c/ConsulateCrackdown.java index 4439718ea66..27f549a8174 100644 --- a/Mage.Sets/src/mage/cards/c/ConsulateCrackdown.java +++ b/Mage.Sets/src/mage/cards/c/ConsulateCrackdown.java @@ -6,9 +6,8 @@ import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -76,7 +75,7 @@ class ConsulateCracksownExileEffect extends OneShotEffect { if (!toExile.isEmpty()) { controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); - new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); } return true; diff --git a/Mage.Sets/src/mage/cards/d/DeputyOfDetention.java b/Mage.Sets/src/mage/cards/d/DeputyOfDetention.java index a9908d8f4ca..f64494d42a5 100644 --- a/Mage.Sets/src/mage/cards/d/DeputyOfDetention.java +++ b/Mage.Sets/src/mage/cards/d/DeputyOfDetention.java @@ -3,9 +3,8 @@ package mage.cards.d; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -96,7 +95,7 @@ class DeputyOfDetentionExileEffect extends OneShotEffect { if (!toExile.isEmpty()) { controller.moveCardsToExile(toExile, source, game, true, CardUtil.getCardExileZoneId(game, source), permanent.getIdName()); - new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FairgroundsWarden.java b/Mage.Sets/src/mage/cards/f/FairgroundsWarden.java index 2c156fa09d3..dd07bdd56da 100644 --- a/Mage.Sets/src/mage/cards/f/FairgroundsWarden.java +++ b/Mage.Sets/src/mage/cards/f/FairgroundsWarden.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -29,7 +27,6 @@ public final class FairgroundsWarden extends CardImpl { // When Fairgrounds Warden enters the battlefield, exile target creature an opponent controls until Fairgrounds Warden leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/f/FaithUnbroken.java b/Mage.Sets/src/mage/cards/f/FaithUnbroken.java index 4ba049a2ec6..a4c53722373 100644 --- a/Mage.Sets/src/mage/cards/f/FaithUnbroken.java +++ b/Mage.Sets/src/mage/cards/f/FaithUnbroken.java @@ -4,10 +4,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.continuous.BoostEnchantedEffect; import mage.abilities.keyword.EnchantAbility; @@ -38,7 +35,6 @@ public final class FaithUnbroken extends CardImpl { // When Faith Unbroken enters the battlefield, exile target creature an opponent controls until Faith Unbroken leaves the battlefield. ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Enchanted creature gets +2/+2. diff --git a/Mage.Sets/src/mage/cards/g/GOTOJAIL.java b/Mage.Sets/src/mage/cards/g/GOTOJAIL.java index 2a5e96172bf..da3b6168c73 100644 --- a/Mage.Sets/src/mage/cards/g/GOTOJAIL.java +++ b/Mage.Sets/src/mage/cards/g/GOTOJAIL.java @@ -1,14 +1,12 @@ - package mage.cards.g; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ChooseOpponentEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -37,7 +35,6 @@ public final class GOTOJAIL extends CardImpl { // When GO TO JAIL enters the battlefield, exile target creature an opponent controls until GO TO JAIL leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new GoToJailExileEffect()); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // At the beginning of the upkeep of the exiled card's owner, that player rolls two six-sided dice. If they roll doubles, sacrifice GO TO JAIL. @@ -81,7 +78,11 @@ class GoToJailExileEffect extends OneShotEffect { Player controller = game.getPlayer(targetPermanent.getControllerId()); if (controller != null) { game.getState().setValue(permanent.getId() + ChooseOpponentEffect.VALUE_KEY, controller.getId()); - return new ExileTargetEffect(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName()).apply(game, source); + new ExileTargetEffect( + CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), permanent.getIdName() + ).apply(game, source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); + return true; } } return false; diff --git a/Mage.Sets/src/mage/cards/g/GelatinousCube.java b/Mage.Sets/src/mage/cards/g/GelatinousCube.java index 86bf4059657..99bb1224c36 100644 --- a/Mage.Sets/src/mage/cards/g/GelatinousCube.java +++ b/Mage.Sets/src/mage/cards/g/GelatinousCube.java @@ -4,10 +4,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -49,7 +47,6 @@ public final class GelatinousCube extends CardImpl { // Engulf — When Gelatinous Cube enters the battlefield, exile target non-Ooze creature an opponent controls until Gelatinous Cube leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability.withFlavorWord("Engulf")); // Dissolve — {X}{B}: Put target creature card with mana value X exiled with Gelatinous Cube into its owner's graveyard. diff --git a/Mage.Sets/src/mage/cards/g/GlassCasket.java b/Mage.Sets/src/mage/cards/g/GlassCasket.java index ba568bd56cc..396680df008 100644 --- a/Mage.Sets/src/mage/cards/g/GlassCasket.java +++ b/Mage.Sets/src/mage/cards/g/GlassCasket.java @@ -2,8 +2,6 @@ package mage.cards.g; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -34,7 +32,6 @@ public final class GlassCasket extends CardImpl { // When Glass Casket enters the battlefield, exile target creature an opponent controls with converted mana cost 3 or less until Glass Casket leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GloriousProtector.java b/Mage.Sets/src/mage/cards/g/GloriousProtector.java index d5ee8068c57..f667a959a5e 100644 --- a/Mage.Sets/src/mage/cards/g/GloriousProtector.java +++ b/Mage.Sets/src/mage/cards/g/GloriousProtector.java @@ -3,9 +3,8 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.ForetellAbility; @@ -47,7 +46,6 @@ public final class GloriousProtector extends CardImpl { // When Glorious Protector enters the battlefield, you may exile any number of non-Angel creatures you control until Glorious Protector leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new GloriousProtectorEffect(),true); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Foretell {2}{W} @@ -105,6 +103,7 @@ class GloriousProtectorEffect extends OneShotEffect { game, source.getSourceId(), source.getSourceObjectZoneChangeCounter() ), sourceObject.getIdName() ); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/g/GraspOfFate.java b/Mage.Sets/src/mage/cards/g/GraspOfFate.java index ef38fe6ffdb..985edb6b32c 100644 --- a/Mage.Sets/src/mage/cards/g/GraspOfFate.java +++ b/Mage.Sets/src/mage/cards/g/GraspOfFate.java @@ -2,8 +2,6 @@ package mage.cards.g; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -32,7 +30,6 @@ public final class GraspOfFate extends CardImpl { .setTargetPointer(new EachTargetPointer()) .setText("for each opponent, exile up to one target nonland permanent that player controls until {this} leaves the battlefield") ); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.setTargetAdjuster(GraspOfFateAdjuster.instance); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/g/GraspingGiant.java b/Mage.Sets/src/mage/cards/g/GraspingGiant.java index 6a0b7b9136c..87ca3495a05 100644 --- a/Mage.Sets/src/mage/cards/g/GraspingGiant.java +++ b/Mage.Sets/src/mage/cards/g/GraspingGiant.java @@ -3,8 +3,6 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; @@ -31,7 +29,6 @@ public final class GraspingGiant extends CardImpl { // Whenever Grasping Giant becomes blocked by a creature, exile that creature until Grasping Giant leaves the battlefield. Ability ability = new BecomesBlockedByCreatureTriggeredAbility(new ExileUntilSourceLeavesEffect(), false); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HieromancersCage.java b/Mage.Sets/src/mage/cards/h/HieromancersCage.java index 83081e9059b..962a72ee353 100644 --- a/Mage.Sets/src/mage/cards/h/HieromancersCage.java +++ b/Mage.Sets/src/mage/cards/h/HieromancersCage.java @@ -3,8 +3,6 @@ package mage.cards.h; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -24,7 +22,6 @@ public final class HieromancersCage extends CardImpl { // When Hieromancer's Cage enters the battlefield, exile target nonland permanent an opponent controls until Hieromancer's Cage leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/h/HixusPrisonWarden.java b/Mage.Sets/src/mage/cards/h/HixusPrisonWarden.java index 7bd99896583..13d1dca64e2 100644 --- a/Mage.Sets/src/mage/cards/h/HixusPrisonWarden.java +++ b/Mage.Sets/src/mage/cards/h/HixusPrisonWarden.java @@ -3,10 +3,7 @@ package mage.cards.h; import java.util.UUID; import mage.MageInt; import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.TriggeredAbilityImpl; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; @@ -56,7 +53,6 @@ class HixusPrisonWardenTriggeredAbility extends TriggeredAbilityImpl { public HixusPrisonWardenTriggeredAbility() { super(Zone.BATTLEFIELD, new ExileUntilSourceLeavesEffect()); - addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); setTriggerPhrase("Whenever a creature deals combat damage to you, if {this} entered the battlefield this turn, "); } diff --git a/Mage.Sets/src/mage/cards/h/HostageTaker.java b/Mage.Sets/src/mage/cards/h/HostageTaker.java index e170e5f9822..db57d2d719f 100644 --- a/Mage.Sets/src/mage/cards/h/HostageTaker.java +++ b/Mage.Sets/src/mage/cards/h/HostageTaker.java @@ -3,9 +3,8 @@ package mage.cards.h; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -46,7 +45,6 @@ public final class HostageTaker extends CardImpl { // When Hostage Taker enters the battlefield, exile another target artifact or creature until Hostage Taker leaves the battlefield. You may cast that card as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell. Ability ability = new EntersBattlefieldTriggeredAbility(new HostageTakerExileEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } @@ -94,6 +92,7 @@ class HostageTakerExileEffect extends OneShotEffect { controller.moveCardToExileWithInfo(card, exileId, permanent.getIdName(), source, game, Zone.BATTLEFIELD, true); // allow to cast the card and you may spend mana as though it were mana of any color to cast it CardUtil.makeCardPlayable(game, source, card, Duration.Custom, true); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/i/InTheTrenches.java b/Mage.Sets/src/mage/cards/i/InTheTrenches.java index a0d431020dc..fc77994f254 100644 --- a/Mage.Sets/src/mage/cards/i/InTheTrenches.java +++ b/Mage.Sets/src/mage/cards/i/InTheTrenches.java @@ -5,9 +5,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.ActivateOncePerGameActivatedAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.cards.CardImpl; @@ -37,7 +35,6 @@ public final class InTheTrenches extends CardImpl { // {5}{W}: Exile target nonland permanent you don't control until In the Trenches leaves the battlefield. Activate only as a sorcery and only once. Ability ability = new ActivateOncePerGameActivatedAbility(Zone.BATTLEFIELD, new ExileUntilSourceLeavesEffect(), new ManaCostsImpl<>("{5}{W}"), TimingRule.SORCERY); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IsolationZone.java b/Mage.Sets/src/mage/cards/i/IsolationZone.java index a833eb5efe3..41894de5f0e 100644 --- a/Mage.Sets/src/mage/cards/i/IsolationZone.java +++ b/Mage.Sets/src/mage/cards/i/IsolationZone.java @@ -4,8 +4,6 @@ package mage.cards.i; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -35,7 +33,6 @@ public final class IsolationZone extends CardImpl { // When Isolation Zone enters the battlefield, exile target creature or enchantment an opponent controls until Isolation Zone leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/i/IxalansBinding.java b/Mage.Sets/src/mage/cards/i/IxalansBinding.java index ebe9ab55fa8..be23d4a3431 100644 --- a/Mage.Sets/src/mage/cards/i/IxalansBinding.java +++ b/Mage.Sets/src/mage/cards/i/IxalansBinding.java @@ -3,9 +3,7 @@ package mage.cards.i; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -32,7 +30,6 @@ public final class IxalansBinding extends CardImpl { // When Ixalan's Binding enters the battlefield, exile target nonland permanent an opponent controls until Ixalan's Binding leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Your opponents can't cast spells with the same name as the exiled card. diff --git a/Mage.Sets/src/mage/cards/j/JourneyToOblivion.java b/Mage.Sets/src/mage/cards/j/JourneyToOblivion.java index 1f769bccd87..2a854774b9c 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToOblivion.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToOblivion.java @@ -3,9 +3,7 @@ package mage.cards.j; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.dynamicvalue.common.PartyCount; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect; import mage.abilities.hint.common.PartyCountHint; @@ -34,7 +32,6 @@ public final class JourneyToOblivion extends CardImpl { // When Journey to Oblivion enters the battlefield, exile target nonland permanent an opponent controls until Journey to Oblivion leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java index d06a321f11f..a21f3844150 100644 --- a/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java +++ b/Mage.Sets/src/mage/cards/k/KitesailFreebooter.java @@ -1,35 +1,30 @@ - package mage.cards.k; -import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; -import mage.game.ExileZone; 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; import mage.target.common.TargetOpponent; -import mage.util.CardUtil; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @@ -51,7 +46,6 @@ public final class KitesailFreebooter extends CardImpl { // When Kitesail Freebooter enters the battlefield, target opponent reveals their hand. You choose a noncreature, nonland card from it. Exile that card until Kitesail Freebooter leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new KitesailFreebooterExileEffect()); ability.addTarget(new TargetOpponent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new KitesailFreebooterReturnExiledCardAbility())); this.addAbility(ability); } @@ -95,10 +89,13 @@ class KitesailFreebooterExileEffect extends OneShotEffect { TargetCard target = new TargetCard(Zone.HAND, filter); if (opponent.getHand().count(filter, game) > 0 && controller.choose(Outcome.Exile, opponent.getHand(), target, source, game)) { Card card = opponent.getHand().get(target.getFirstTarget(), game); - // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. - if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { - controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source, game, Zone.HAND, true); + if (card == null) { + return true; } + // If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled. + Effect effect = new ExileUntilSourceLeavesEffect(Zone.HAND); + effect.setTargetPointer(new FixedTarget(card, game)); + return effect.apply(game, source); } } return true; @@ -107,74 +104,3 @@ class KitesailFreebooterExileEffect extends OneShotEffect { } } - -/** - * Returns the exiled card as source permanent leaves battlefield Uses no stack - * - * @author LevelX2 - */ -class KitesailFreebooterReturnExiledCardAbility extends DelayedTriggeredAbility { - - public KitesailFreebooterReturnExiledCardAbility() { - super(new KitesailFreebooterReturnExiledCardEffect(), Duration.OneUse); - this.usesStack = false; - this.setRuleVisible(false); - } - - public KitesailFreebooterReturnExiledCardAbility(final KitesailFreebooterReturnExiledCardAbility ability) { - super(ability); - } - - @Override - public KitesailFreebooterReturnExiledCardAbility copy() { - return new KitesailFreebooterReturnExiledCardAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(this.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - return true; - } - } - return false; - } -} - -class KitesailFreebooterReturnExiledCardEffect extends OneShotEffect { - - public KitesailFreebooterReturnExiledCardEffect() { - super(Outcome.Benefit); - this.staticText = "Return exiled nonland card to its owner's hand"; - } - - public KitesailFreebooterReturnExiledCardEffect(final KitesailFreebooterReturnExiledCardEffect effect) { - super(effect); - } - - @Override - public KitesailFreebooterReturnExiledCardEffect copy() { - return new KitesailFreebooterReturnExiledCardEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && controller != null) { - ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (exile != null && sourcePermanent != null) { - controller.moveCards(exile, Zone.HAND, source, game); - return true; - } - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LagrellaTheMagpie.java b/Mage.Sets/src/mage/cards/l/LagrellaTheMagpie.java index 05ce77dc75c..78297738ed4 100644 --- a/Mage.Sets/src/mage/cards/l/LagrellaTheMagpie.java +++ b/Mage.Sets/src/mage/cards/l/LagrellaTheMagpie.java @@ -5,9 +5,8 @@ import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.DelayedTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -48,7 +47,6 @@ public final class LagrellaTheMagpie extends CardImpl { // When Lagrella, the Magpie enters the battlefield, exile any number of other target creatures controlled by different players until Lagrella leaves the battlefield. When an exiled card enters the battlefield under your control this way, put two +1/+1 counters on it. Ability ability = new EntersBattlefieldTriggeredAbility(new LagrellaTheMagpieEffect(), false); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addTarget(new LagrellaTheMagpieTarget()); this.addAbility(ability); } @@ -103,6 +101,7 @@ class LagrellaTheMagpieEffect extends OneShotEffect { CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source) ); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); game.addDelayedTriggeredAbility(new LagrellaTheMagpieTriggeredAbility(cards, game), source); return true; } diff --git a/Mage.Sets/src/mage/cards/l/LeylineBinding.java b/Mage.Sets/src/mage/cards/l/LeylineBinding.java index 861d19ac80c..0c34533c321 100644 --- a/Mage.Sets/src/mage/cards/l/LeylineBinding.java +++ b/Mage.Sets/src/mage/cards/l/LeylineBinding.java @@ -3,9 +3,7 @@ package mage.cards.l; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.dynamicvalue.common.DomainValue; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; import mage.abilities.hint.common.DomainHint; @@ -40,7 +38,6 @@ public final class LeylineBinding extends CardImpl { // When Leyline Binding enters the battlefield, exile target nonland permanent an opponent controls until Leyline Binding leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/l/LumberingBattlement.java b/Mage.Sets/src/mage/cards/l/LumberingBattlement.java index 43a0161993f..5f370aa09ed 100644 --- a/Mage.Sets/src/mage/cards/l/LumberingBattlement.java +++ b/Mage.Sets/src/mage/cards/l/LumberingBattlement.java @@ -4,11 +4,10 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.Card; @@ -52,9 +51,7 @@ public final class LumberingBattlement extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // When Lumbering Battlement enters the battlefield, exile any number of other nontoken creatures you control until it leaves the battlefield. - Ability ability = new EntersBattlefieldTriggeredAbility(new LumberingBattlementEffect()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldTriggeredAbility(new LumberingBattlementEffect())); // Lumbering Battlement gets +2/+2 for each card exiled with it. this.addAbility(new SimpleStaticAbility(new BoostSourceEffect( @@ -116,10 +113,12 @@ class LumberingBattlementEffect extends OneShotEffect { cards.add(permanent); } } - return player.moveCardsToExile( + player.moveCardsToExile( cards, source, game, true, CardUtil.getCardExileZoneId(game, source), sourcePerm.getIdName() ); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); + return true; } } @@ -160,4 +159,4 @@ enum LumberingBattlementValue implements DynamicValue { public String getMessage() { return ""; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/l/LunarchInquisitors.java b/Mage.Sets/src/mage/cards/l/LunarchInquisitors.java index d08f2a8338b..715cfc59b25 100644 --- a/Mage.Sets/src/mage/cards/l/LunarchInquisitors.java +++ b/Mage.Sets/src/mage/cards/l/LunarchInquisitors.java @@ -3,8 +3,6 @@ package mage.cards.l; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.TransformIntoSourceTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -42,7 +40,6 @@ public final class LunarchInquisitors extends CardImpl { // When this creature transforms into Lunarch Inquisitors, you may exile another target creature until Lunarch Inquisitors leaves the battlefield. Ability ability = new TransformIntoSourceTriggeredAbility(new ExileUntilSourceLeavesEffect(), true); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/MysteriousLimousine.java b/Mage.Sets/src/mage/cards/m/MysteriousLimousine.java index 7236d32dbb2..23512bf2b65 100644 --- a/Mage.Sets/src/mage/cards/m/MysteriousLimousine.java +++ b/Mage.Sets/src/mage/cards/m/MysteriousLimousine.java @@ -3,9 +3,8 @@ package mage.cards.m; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.keyword.CrewAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -47,7 +46,6 @@ public final class MysteriousLimousine extends CardImpl { // Whenever Mysterious Limousine enters the battlefield or attacks, exile up to one other target creature until Mysterious Limousine leaves the battlefield. If a creature is put into exile this way, return each other card exiled with Mysterious Limousine to the battlefield under its owner's control. Ability ability = new EntersBattlefieldOrAttacksSourceTriggeredAbility(new MysteriousLimousineEffect()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability); @@ -103,6 +101,7 @@ class MysteriousLimousineEffect extends OneShotEffect { false, false, true, null ); } + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); return true; } } diff --git a/Mage.Sets/src/mage/cards/o/OnThinIce.java b/Mage.Sets/src/mage/cards/o/OnThinIce.java index b4b29052671..72b3d69f545 100644 --- a/Mage.Sets/src/mage/cards/o/OnThinIce.java +++ b/Mage.Sets/src/mage/cards/o/OnThinIce.java @@ -2,9 +2,7 @@ package mage.cards.o; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.effects.common.AttachEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -47,7 +45,6 @@ public final class OnThinIce extends CardImpl { // When On Thin Ice enters the battlefield, exile target creature an opponent controls until On Thin Ice leaves the battlefield. ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/o/Ossification.java b/Mage.Sets/src/mage/cards/o/Ossification.java index f29c4a3bba9..bf035a48020 100644 --- a/Mage.Sets/src/mage/cards/o/Ossification.java +++ b/Mage.Sets/src/mage/cards/o/Ossification.java @@ -4,20 +4,16 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.constants.*; import mage.abilities.effects.common.AttachEffect; import mage.filter.FilterPermanent; -import mage.filter.StaticFilters; import mage.filter.common.FilterControlledLandPermanent; import mage.filter.predicate.Predicates; import mage.target.TargetPermanent; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.target.common.TargetLandPermanent; /** * @@ -54,7 +50,6 @@ public final class Ossification extends CardImpl { // When Ossification enters the battlefield, exile target creature or planeswalker an opponent controls until Ossification leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter2)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PhantomSteed.java b/Mage.Sets/src/mage/cards/p/PhantomSteed.java index d7c36640aac..1613cbb2233 100644 --- a/Mage.Sets/src/mage/cards/p/PhantomSteed.java +++ b/Mage.Sets/src/mage/cards/p/PhantomSteed.java @@ -5,9 +5,7 @@ import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlashAbility; @@ -59,7 +57,6 @@ public final class PhantomSteed extends CardImpl { // When Phantom Steed enters the battlefield, exile another target creature you control until Phantom Steed leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Whenever Phantom Steed attacks, create a tapped and attacking token that's a copy of the exiled creature, except it's an Illusion in addition to its other types. Sacrifice that token at end of combat. diff --git a/Mage.Sets/src/mage/cards/p/PortableHole.java b/Mage.Sets/src/mage/cards/p/PortableHole.java index 3c771229629..6c8ad70b8d0 100644 --- a/Mage.Sets/src/mage/cards/p/PortableHole.java +++ b/Mage.Sets/src/mage/cards/p/PortableHole.java @@ -2,8 +2,6 @@ package mage.cards.p; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -36,7 +34,6 @@ public final class PortableHole extends CardImpl { // When Portable Hole enters the battlefield, exile target nonland permanent an opponent controls with mana value 2 or less until Portable Hole leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/p/PrayerOfBinding.java b/Mage.Sets/src/mage/cards/p/PrayerOfBinding.java index 244663a5d6a..2f2c582f43d 100644 --- a/Mage.Sets/src/mage/cards/p/PrayerOfBinding.java +++ b/Mage.Sets/src/mage/cards/p/PrayerOfBinding.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.keyword.FlashAbility; @@ -29,7 +27,6 @@ public final class PrayerOfBinding extends CardImpl { // When Prayer of Binding enters the battlefield, exile up to one target nonland permanent an opponent controls until Prayer of Binding leaves the battlefield. You gain 2 life. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.addEffect(new GainLifeEffect(2)); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/p/PrisonRealm.java b/Mage.Sets/src/mage/cards/p/PrisonRealm.java index 25ba4f1ef53..b44075dcd16 100644 --- a/Mage.Sets/src/mage/cards/p/PrisonRealm.java +++ b/Mage.Sets/src/mage/cards/p/PrisonRealm.java @@ -2,8 +2,6 @@ package mage.cards.p; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; @@ -34,7 +32,6 @@ public final class PrisonRealm extends CardImpl { // When Prison Realm enters the battlefield, exile target creature or planeswalker an opponent controls until Prison Realm leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // When Prison Realm enters the battlefield, scry 1. diff --git a/Mage.Sets/src/mage/cards/q/QuarantineField.java b/Mage.Sets/src/mage/cards/q/QuarantineField.java index 1b27e49a86d..f86cf2d5a41 100644 --- a/Mage.Sets/src/mage/cards/q/QuarantineField.java +++ b/Mage.Sets/src/mage/cards/q/QuarantineField.java @@ -4,8 +4,6 @@ package mage.cards.q; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.EntersBattlefieldWithXCountersEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; @@ -36,7 +34,6 @@ public final class QuarantineField extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect() .setText("for each isolation counter on it, exile up to one target nonland permanent an opponent controls until {this} leaves the battlefield") ); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); ability.setTargetAdjuster(QuarantineFieldAdjuster.instance); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SealAway.java b/Mage.Sets/src/mage/cards/s/SealAway.java index 58665cf257e..7cff4873271 100644 --- a/Mage.Sets/src/mage/cards/s/SealAway.java +++ b/Mage.Sets/src/mage/cards/s/SealAway.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; @@ -38,7 +36,6 @@ public final class SealAway extends CardImpl { //When Seal Away enters the battlefield, exile target tapped creature an opponent controls until Seal Away leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/SealFromExistence.java b/Mage.Sets/src/mage/cards/s/SealFromExistence.java index 775a9dec289..33f7cec43d6 100644 --- a/Mage.Sets/src/mage/cards/s/SealFromExistence.java +++ b/Mage.Sets/src/mage/cards/s/SealFromExistence.java @@ -2,9 +2,7 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.WardAbility; import mage.cards.CardImpl; @@ -29,7 +27,6 @@ public final class SealFromExistence extends CardImpl { // When Seal from Existence enters the battlefield, exile target nonland permanent an opponent controls until Seal from Existence leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/ShireShirriff.java b/Mage.Sets/src/mage/cards/s/ShireShirriff.java index 82b8b7953da..8dc0dab1332 100644 --- a/Mage.Sets/src/mage/cards/s/ShireShirriff.java +++ b/Mage.Sets/src/mage/cards/s/ShireShirriff.java @@ -2,10 +2,8 @@ package mage.cards.s; import mage.MageInt; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.costs.common.SacrificeTargetCost; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DoWhenCostPaid; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.VigilanceAbility; @@ -50,7 +48,6 @@ public final class ShireShirriff extends CardImpl { "exile target creature an opponent controls until {this} leaves the battlefield." ); reflexive.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_CREATURE)); - reflexive.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid( reflexive, @@ -67,4 +64,4 @@ public final class ShireShirriff extends CardImpl { public ShireShirriff copy() { return new ShireShirriff(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SigridGodFavored.java b/Mage.Sets/src/mage/cards/s/SigridGodFavored.java index 4928bd43c70..66707558451 100644 --- a/Mage.Sets/src/mage/cards/s/SigridGodFavored.java +++ b/Mage.Sets/src/mage/cards/s/SigridGodFavored.java @@ -3,8 +3,6 @@ package mage.cards.s; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FlashAbility; @@ -51,7 +49,6 @@ public final class SigridGodFavored extends CardImpl { // When Sigrid, God-Favored enters the battlefield, exile up to one target attacking or blocking creature until Sigrid leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetAttackingOrBlockingCreature(0, 1)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/Silkwrap.java b/Mage.Sets/src/mage/cards/s/Silkwrap.java index 45a739a9698..e71ebb4ff84 100644 --- a/Mage.Sets/src/mage/cards/s/Silkwrap.java +++ b/Mage.Sets/src/mage/cards/s/Silkwrap.java @@ -3,8 +3,6 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -34,7 +32,6 @@ public final class Silkwrap extends CardImpl { // When Silkwrap enters the battlefield, exile target creature with mana value 3 or less an opponent controls until Silkwrap leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StasisSnare.java b/Mage.Sets/src/mage/cards/s/StasisSnare.java index da38d4395a4..0f766cee519 100644 --- a/Mage.Sets/src/mage/cards/s/StasisSnare.java +++ b/Mage.Sets/src/mage/cards/s/StasisSnare.java @@ -3,8 +3,6 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; @@ -27,7 +25,6 @@ public final class StasisSnare extends CardImpl { // When Stasis Snare enters the battlefield, exile target creature an opponent controls until Stasis Snare leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/s/StaticNet.java b/Mage.Sets/src/mage/cards/s/StaticNet.java index e5620648176..f131da8536a 100644 --- a/Mage.Sets/src/mage/cards/s/StaticNet.java +++ b/Mage.Sets/src/mage/cards/s/StaticNet.java @@ -4,8 +4,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.GainLifeEffect; @@ -28,7 +26,6 @@ public final class StaticNet extends CardImpl { // When Static Net enters the battlefield, exile target nonland permanent an opponent controls until Static Net leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_NON_LAND)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // When Static Net enters the battlefield, you gain 2 life and create a tapped Powerstone token. diff --git a/Mage.Sets/src/mage/cards/s/SuspensionField.java b/Mage.Sets/src/mage/cards/s/SuspensionField.java index 08373547d32..42d3e391cd4 100644 --- a/Mage.Sets/src/mage/cards/s/SuspensionField.java +++ b/Mage.Sets/src/mage/cards/s/SuspensionField.java @@ -3,8 +3,6 @@ package mage.cards.s; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -32,7 +30,6 @@ public final class SuspensionField extends CardImpl { // When Suspension Field enters the battlefield, you may exile target creature with toughness 3 or greater until Suspension Field leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect(), true); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TemporaryLockdown.java b/Mage.Sets/src/mage/cards/t/TemporaryLockdown.java index 9c9cc37f4ed..b1177d50d65 100644 --- a/Mage.Sets/src/mage/cards/t/TemporaryLockdown.java +++ b/Mage.Sets/src/mage/cards/t/TemporaryLockdown.java @@ -2,9 +2,8 @@ package mage.cards.t; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; @@ -30,9 +29,7 @@ public final class TemporaryLockdown extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); // When Temporary Lockdown enters the battlefield, exile each nonland permanent with mana value 2 or less until Temporary Lockdown leaves the battlefield. - Ability ability = new EntersBattlefieldTriggeredAbility(new TemporaryLockdownEffect()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldTriggeredAbility(new TemporaryLockdownEffect())); } private TemporaryLockdown(final TemporaryLockdown card) { @@ -74,10 +71,15 @@ class TemporaryLockdownEffect extends OneShotEffect { return false; } Cards cards = new CardsImpl(game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game)); - return !cards.isEmpty() && player.moveCardsToExile( + if (cards.isEmpty()) { + return false; + } + player.moveCardsToExile( cards.getCards(game), source, game, true, CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source) ); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/t/ThopterArrest.java b/Mage.Sets/src/mage/cards/t/ThopterArrest.java index a66cd689fb6..e09e8415be0 100644 --- a/Mage.Sets/src/mage/cards/t/ThopterArrest.java +++ b/Mage.Sets/src/mage/cards/t/ThopterArrest.java @@ -3,8 +3,6 @@ package mage.cards.t; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -36,7 +34,6 @@ public final class ThopterArrest extends CardImpl { // When Thopter Arrest enters the battlefield, exile target artifact or creature an opponent controls until Thopter Arrest leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(filter)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java b/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java index 001ccda98a4..d10305db0c9 100644 --- a/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java +++ b/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java @@ -5,9 +5,7 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.keyword.ChannelAbility; @@ -37,7 +35,6 @@ public final class TouchTheSpiritRealm extends CardImpl { // Touch the Spirit Realm leaves the battlefield. Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect()); ability.addTarget(new TargetPermanent(0, 1, StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); // Channel - {1}{W}, Discard Touch the Spirit Realm: Exile target artifact or creature. diff --git a/Mage.Sets/src/mage/cards/t/TrapjawTyrant.java b/Mage.Sets/src/mage/cards/t/TrapjawTyrant.java index c1d8dd4994a..569b06a3df1 100644 --- a/Mage.Sets/src/mage/cards/t/TrapjawTyrant.java +++ b/Mage.Sets/src/mage/cards/t/TrapjawTyrant.java @@ -4,14 +4,11 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealtDamageToSourceTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; -import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.TargetController; import mage.target.common.TargetOpponentsCreaturePermanent; /** @@ -30,7 +27,6 @@ public final class TrapjawTyrant extends CardImpl { // Enrage — Whenever Trapjaw Tyrant is dealt damage, exile target creature an opponent controls until Trapjaw Tyrant leaves the battlefield. Ability ability = new DealtDamageToSourceTriggeredAbility(new ExileUntilSourceLeavesEffect(), false, true); ability.addTarget(new TargetOpponentsCreaturePermanent()); - ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/v/ValkiGodOfLies.java b/Mage.Sets/src/mage/cards/v/ValkiGodOfLies.java index dbb823abe8a..112e223b680 100644 --- a/Mage.Sets/src/mage/cards/v/ValkiGodOfLies.java +++ b/Mage.Sets/src/mage/cards/v/ValkiGodOfLies.java @@ -4,15 +4,16 @@ import mage.MageInt; import mage.MageObject; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.DelayedTriggeredAbility; import mage.abilities.LoyaltyAbility; import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CopyEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.cards.Card; import mage.cards.CardSetInfo; @@ -22,17 +23,15 @@ import mage.constants.*; import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.ManaValuePredicate; -import mage.game.ExileZone; import mage.game.Game; import mage.game.command.emblems.TibaltCosmicImpostorEmblem; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPermanent; import mage.target.common.TargetCardInExile; import mage.target.targetpointer.FixedTarget; +import mage.target.targetpointer.FixedTargets; import mage.util.CardUtil; import java.util.LinkedHashSet; @@ -113,103 +112,34 @@ class ValkiGodOfLiesRevealExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject Valki = game.getObject(source); + if (controller == null) { + return false; + } Set cardsToExile = new LinkedHashSet<>(); - if (controller != null - && Valki != null) { - UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + Valki.getZoneChangeCounter(game), game); - for (UUID opponentId : game.getOpponents(controller.getId())) { - Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - opponent.revealCards(source, opponent.getHand(), game); - TargetCard targetToExile = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_CREATURE); - targetToExile.withChooseHint("card to exile"); - targetToExile.setNotTarget(true); - if (controller.choose(Outcome.Exile, opponent.getHand(), targetToExile, source, game)) { - Card targetedCardToExile = game.getCard(targetToExile.getFirstTarget()); - if (targetedCardToExile != null - && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { - cardsToExile.add(targetedCardToExile); - } + for (UUID opponentId : game.getOpponents(controller.getId())) { + Player opponent = game.getPlayer(opponentId); + if (opponent != null && !opponent.getHand().isEmpty()) { + opponent.revealCards(source, opponent.getHand(), game); + TargetCard targetToExile = new TargetCard(Zone.HAND, StaticFilters.FILTER_CARD_CREATURE); + targetToExile.withChooseHint("card to exile"); + targetToExile.setNotTarget(true); + if (opponent.getHand().count(StaticFilters.FILTER_CARD_CREATURE, game) > 0 && + controller.choose(Outcome.Exile, opponent.getHand(), targetToExile, source, game)) { + Card targetedCardToExile = game.getCard(targetToExile.getFirstTarget()); + if (targetedCardToExile != null + && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) { + cardsToExile.add(targetedCardToExile); } } } - // exile all cards at one time - controller.moveCardsToExile(cardsToExile, source, game, true, exileId, Valki.getName()); - game.addDelayedTriggeredAbility(new ValkiGodOfLiesReturnExiledCardAbility(), source); + } + // exile all cards at one time + if (cardsToExile.isEmpty()) { return true; } - return false; - } -} - -class ValkiGodOfLiesReturnExiledCardAbility extends DelayedTriggeredAbility { - - public ValkiGodOfLiesReturnExiledCardAbility() { - super(new ValkiGodOfLiesReturnExiledCardEffect(), Duration.OneUse); - this.usesStack = false; - this.setRuleVisible(false); - } - - public ValkiGodOfLiesReturnExiledCardAbility(final ValkiGodOfLiesReturnExiledCardAbility ability) { - super(ability); - } - - @Override - public ValkiGodOfLiesReturnExiledCardAbility copy() { - return new ValkiGodOfLiesReturnExiledCardAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ZONE_CHANGE; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (event.getTargetId().equals(this.getSourceId())) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - return true; - } - } - return false; - } -} - -class ValkiGodOfLiesReturnExiledCardEffect extends OneShotEffect { - - public ValkiGodOfLiesReturnExiledCardEffect() { - super(Outcome.Neutral); - this.staticText = "Return exiled card to its owner's hand"; - } - - public ValkiGodOfLiesReturnExiledCardEffect(final ValkiGodOfLiesReturnExiledCardEffect effect) { - super(effect); - } - - @Override - public ValkiGodOfLiesReturnExiledCardEffect copy() { - return new ValkiGodOfLiesReturnExiledCardEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject ValkiOnBattlefield = game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if (controller != null - && ValkiOnBattlefield != null) { - // Valki, God of Lies has changed zone, so make sure to get the exile zone via its last known battlefield state - UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + (ValkiOnBattlefield.getZoneChangeCounter(game)), game); - ExileZone exile = game.getExile().getExileZone(exileId); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (exile != null - && sourcePermanent != null) { - controller.moveCards(exile, Zone.HAND, source, game); - return true; - } - } - return false; + Effect effect = new ExileUntilSourceLeavesEffect(Zone.HAND); + effect.setTargetPointer(new FixedTargets(cardsToExile, game)); + return effect.apply(game, source); } } @@ -235,7 +165,7 @@ class ValkiGodOfLiesCopyExiledEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && Valki != null) { - UUID exileId = CardUtil.getExileZoneId(source.getSourceId().toString() + (Valki.getZoneChangeCounter(game)), game); + UUID exileId = CardUtil.getCardExileZoneId(game, source); FilterCard filter = new FilterCard(); filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, source.getManaCostsToPay().getX())); TargetCardInExile target = new TargetCardInExile(filter, exileId); diff --git a/Mage.Sets/src/mage/cards/y/YannikScavengingSentinel.java b/Mage.Sets/src/mage/cards/y/YannikScavengingSentinel.java index b9b685c2a47..894385fc145 100644 --- a/Mage.Sets/src/mage/cards/y/YannikScavengingSentinel.java +++ b/Mage.Sets/src/mage/cards/y/YannikScavengingSentinel.java @@ -3,7 +3,7 @@ package mage.cards.y; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.common.delayed.ReflexiveTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ExileTargetEffect; @@ -105,7 +105,7 @@ class YannikScavengingSentinelEffect extends OneShotEffect { new ExileTargetEffect(CardUtil.getExileZoneId( game, source.getSourceId(), source.getSourceObjectZoneChangeCounter() ), permanent.getIdName()).setTargetPointer(new FixedTarget(permanent, game)).apply(game, source); - game.addDelayedTriggeredAbility(new OnLeaveReturnExiledToBattlefieldAbility(), source); + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(), source); if (game.getState().getZone(permanent.getId()) != Zone.BATTLEFIELD) { ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility( new DistributeCountersEffect( diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modaldoublefaced/ModalDoubleFacedCardsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modaldoublefaced/ModalDoubleFacedCardsTest.java index c3d9333775f..f6d7f704213 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/cost/modaldoublefaced/ModalDoubleFacedCardsTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/cost/modaldoublefaced/ModalDoubleFacedCardsTest.java @@ -10,9 +10,7 @@ import mage.game.permanent.PermanentCard; import mage.util.CardUtil; import mage.util.ManaUtil; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; -import org.mage.test.player.TestPlayer; import org.mage.test.serverside.base.CardTestPlayerBase; /** @@ -800,7 +798,6 @@ public class ModalDoubleFacedCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Bloodbraid Elf"); setChoice(playerA, true); // use free cast //setChoice(playerA, "Cast Valki, God of Lies"); possible bug: you can see two spell abilities to choose, but only one allows here - setChoice(playerA, TestPlayer.CHOICE_SKIP); // no choices for valki's etb exile setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); @@ -848,7 +845,6 @@ public class ModalDoubleFacedCardsTest extends CardTestPlayerBase { castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Sram's Expertise"); setChoice(playerA, true); // use free cast - setChoice(playerA, TestPlayer.CHOICE_SKIP); // no choices for valki's etb exile setStrictChooseMode(true); setStopAt(1, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/chk/UbaMaskTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/chk/UbaMaskTest.java index 7238a810393..5412995b8fa 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/chk/UbaMaskTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/chk/UbaMaskTest.java @@ -3,7 +3,6 @@ package org.mage.test.cards.single.chk; import mage.constants.PhaseStep; import mage.constants.Zone; import org.junit.Test; -import org.mage.test.player.TestPlayer; import org.mage.test.serverside.base.CardTestPlayerBase; /** @@ -75,7 +74,6 @@ public class UbaMaskTest extends CardTestPlayerBase { // cast valki castSpell(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Valki, God of Lies"); - setChoice(playerB, TestPlayer.CHOICE_SKIP); setStrictChooseMode(true); setStopAt(2, PhaseStep.END_TURN); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/ValkiGodOfLiesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/ValkiGodOfLiesTest.java index 64c077437d8..1c33f5068f8 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/ValkiGodOfLiesTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/ValkiGodOfLiesTest.java @@ -7,6 +7,31 @@ import org.mage.test.serverside.base.CardTestPlayerBase; public class ValkiGodOfLiesTest extends CardTestPlayerBase { + private final static String valki = "Valki, God of Lies"; + private final static String kraken = "Kraken Hatchling"; + + @Test + public void testBecomeCopyOfExiledCreatureCard() { + addCard(Zone.HAND, playerA, valki); + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3); + addCard(Zone.HAND, playerB, kraken); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, valki); + setChoice(playerA, kraken); + waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN); + activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{X}: Choose a creature card"); + setChoice(playerA, "X=1"); + setChoice(playerA, kraken); + + setStrictChooseMode(true); + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + assertExileCount(playerB, kraken, 1); + assertPowerToughness(playerA, kraken, 0, 4); + assertPermanentCount(playerA, 4); + } + @Test public void ephmerateTest() { removeAllCardsFromLibrary(playerB); diff --git a/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledAbility.java similarity index 82% rename from Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java rename to Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledAbility.java index 8ec64e77600..16a1eca3213 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledToBattlefieldAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/OnLeaveReturnExiledAbility.java @@ -30,21 +30,25 @@ import mage.util.CardUtil; * * @author LevelX2 */ -public class OnLeaveReturnExiledToBattlefieldAbility extends DelayedTriggeredAbility { +public class OnLeaveReturnExiledAbility extends DelayedTriggeredAbility { - public OnLeaveReturnExiledToBattlefieldAbility() { - super(new ReturnExiledPermanentsEffect(), Duration.OneUse); + public OnLeaveReturnExiledAbility() { + this(Zone.BATTLEFIELD); + } + + public OnLeaveReturnExiledAbility(Zone zone) { + super(new ReturnExiledPermanentsEffect(zone), Duration.OneUse); this.usesStack = false; this.setRuleVisible(false); } - public OnLeaveReturnExiledToBattlefieldAbility(final OnLeaveReturnExiledToBattlefieldAbility ability) { + public OnLeaveReturnExiledAbility(final OnLeaveReturnExiledAbility ability) { super(ability); } @Override - public OnLeaveReturnExiledToBattlefieldAbility copy() { - return new OnLeaveReturnExiledToBattlefieldAbility(this); + public OnLeaveReturnExiledAbility copy() { + return new OnLeaveReturnExiledAbility(this); } @Override @@ -66,13 +70,17 @@ public class OnLeaveReturnExiledToBattlefieldAbility extends DelayedTriggeredAbi class ReturnExiledPermanentsEffect extends OneShotEffect { - public ReturnExiledPermanentsEffect() { + private final Zone zone; + + ReturnExiledPermanentsEffect(Zone zone) { super(Outcome.Benefit); + this.zone = zone; this.staticText = "Return exiled permanents"; } public ReturnExiledPermanentsEffect(final ReturnExiledPermanentsEffect effect) { super(effect); + this.zone = effect.zone; } @Override @@ -87,7 +95,7 @@ class ReturnExiledPermanentsEffect extends OneShotEffect { if (sourceObject != null && controller != null) { ExileZone exile = getExileIfPossible(game, source); if (exile != null) { - return controller.moveCards(new LinkedHashSet<>(exile.getCards(game)), Zone.BATTLEFIELD, source, game, false, false, true, null); + return controller.moveCards(new LinkedHashSet<>(exile.getCards(game)), zone, source, game, false, false, true, null); } } return false; diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java index 32399f77dfc..fa15bbe4c86 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileUntilSourceLeavesEffect.java @@ -2,11 +2,13 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.Mode; +import mage.abilities.common.delayed.OnLeaveReturnExiledAbility; import mage.abilities.effects.OneShotEffect; import mage.constants.Outcome; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.target.Target; + import mage.util.CardUtil; /** @@ -15,12 +17,28 @@ import mage.util.CardUtil; */ public class ExileUntilSourceLeavesEffect extends OneShotEffect { + private final Zone returnToZone; + + /** + * Exiles target(s) until source leaves battlefield + * Includes effect that returns exiled card to battlefield when source leaves + */ public ExileUntilSourceLeavesEffect() { + this(Zone.BATTLEFIELD); + } + + /** + * Exiles target(s) until source leaves battlefield + * @param returnToZone The zone to which the exiled card will be returned when source leaves + */ + public ExileUntilSourceLeavesEffect(Zone returnToZone) { super(Outcome.Removal); + this.returnToZone = returnToZone; } public ExileUntilSourceLeavesEffect(final ExileUntilSourceLeavesEffect effect) { super(effect); + this.returnToZone = effect.returnToZone; } @Override @@ -32,7 +50,7 @@ public class ExileUntilSourceLeavesEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = source.getSourcePermanentIfItStillExists(game); - // If Banishing Light leaves the battlefield before its triggered ability resolves, the target permanent won't be exiled. + // If source permanent leaves the battlefield before its triggered ability resolves, the target permanent won't be exiled. if (permanent == null) { return false; } @@ -41,7 +59,11 @@ public class ExileUntilSourceLeavesEffect extends OneShotEffect { if (targetPointer != null) { // Grasping Giant effect.setTargetPointer(targetPointer); } - return effect.apply(game, source); + if (effect.apply(game, source)) { + game.addDelayedTriggeredAbility(new OnLeaveReturnExiledAbility(returnToZone), source); + return true; + } + return false; } @Override