diff --git a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java index c96a6ef1840..acfc126d0b0 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java @@ -3,27 +3,19 @@ package mage.cards.a; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; 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.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -47,7 +39,7 @@ public final class AngelOfCondemnation extends CardImpl { // {2}{W}, {T}: Exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. Ability ability = new SimpleActivatedAbility( - new AngelOfCondemnationExileUntilEOTEffect(), new ManaCostsImpl<>("{2}{W}") + new ExileReturnBattlefieldNextEndStepTargetEffect(), new ManaCostsImpl<>("{2}{W}") ); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); @@ -70,37 +62,3 @@ public final class AngelOfCondemnation extends CardImpl { return new AngelOfCondemnation(this); } } - -class AngelOfCondemnationExileUntilEOTEffect extends OneShotEffect { - - AngelOfCondemnationExileUntilEOTEffect() { - super(Outcome.Detriment); - staticText = "exile another target creature. Return that card to the battlefield " + - "under its owner's control at the beginning of the next end step"; - } - - private AngelOfCondemnationExileUntilEOTEffect(final AngelOfCondemnationExileUntilEOTEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null || permanent == null) { - return false; - } - controller.moveCards(permanent, Zone.EXILED, source, game); - //create delayed triggered ability - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setTargetPointer(new FixedTarget(source.getFirstTarget(), game)) - ), source); - return true; - } - - @Override - public AngelOfCondemnationExileUntilEOTEffect copy() { - return new AngelOfCondemnationExileUntilEOTEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java index 02e8e274073..70f720e55bb 100644 --- a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java +++ b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java @@ -3,24 +3,20 @@ package mage.cards.b; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlashAbility; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -56,7 +52,7 @@ public final class BlizzardStrix extends CardImpl { // When Blizzard Strix enters the battlefield, if you control another snow permanent, exile target permanent other than Blizzard Strix. Return that card to the battlefield under its owner's control at the beginning of the next end step. Ability ability = new ConditionalInterveningIfTriggeredAbility( - new EntersBattlefieldTriggeredAbility(new BlizzardStrixEffect()), condition, + new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()), condition, "When {this} enters the battlefield, if you control another snow permanent, " + "exile target permanent other than {this}. Return that card to the battlefield " + "under its owner's control at the beginning of the next end step." @@ -74,35 +70,3 @@ public final class BlizzardStrix extends CardImpl { return new BlizzardStrix(this); } } - -class BlizzardStrixEffect extends OneShotEffect { - - BlizzardStrixEffect() { - super(Outcome.Detriment); - } - - private BlizzardStrixEffect(final BlizzardStrixEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null || permanent == null) { - return false; - } - controller.moveCards(permanent, Zone.EXILED, source, game); - //create delayed triggered ability - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setTargetPointer(new FixedTarget(source.getFirstTarget(), game)) - ), source); - return true; - } - - @Override - public BlizzardStrixEffect copy() { - return new BlizzardStrixEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/c/CharmingPrince.java b/Mage.Sets/src/mage/cards/c/CharmingPrince.java index 16623a0ebca..3f1f0928239 100644 --- a/Mage.Sets/src/mage/cards/c/CharmingPrince.java +++ b/Mage.Sets/src/mage/cards/c/CharmingPrince.java @@ -1,27 +1,21 @@ package mage.cards.c; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.effects.common.GainLifeEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; import mage.abilities.effects.keyword.ScryEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.filter.FilterPermanent; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -30,8 +24,7 @@ import java.util.UUID; */ public final class CharmingPrince extends CardImpl { - - private static final FilterPermanent filter = new FilterCreaturePermanent("another creature you own"); + private static final FilterPermanent filter = new FilterCreaturePermanent("another target creature you own"); static { filter.add(TargetController.YOU.getOwnerPredicate()); @@ -54,7 +47,7 @@ public final class CharmingPrince extends CardImpl { ability.addMode(new Mode(new GainLifeEffect(3))); // • Exile another target creature you own. Return it to the battlefield under your control at the beginning of the next end step. - Mode mode = new Mode(new CharmingPrinceEffect()); + Mode mode = new Mode(new ExileReturnBattlefieldNextEndStepTargetEffect().underYourControl(true).withTextThatCard(false)); mode.addTarget(new TargetPermanent(filter)); ability.addMode(mode); this.addAbility(ability); @@ -69,42 +62,3 @@ public final class CharmingPrince extends CardImpl { return new CharmingPrince(this); } } - -class CharmingPrinceEffect extends OneShotEffect { - - CharmingPrinceEffect() { - super(Outcome.Benefit); - staticText = "Exile another target creature you own. " + - "Return it to the battlefield under your control at the beginning of the next end step."; - } - - private CharmingPrinceEffect(final CharmingPrinceEffect effect) { - super(effect); - } - - @Override - public CharmingPrinceEffect copy() { - return new CharmingPrinceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (controller == null || sourceObject == null) { - return false; - } - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent == null) { - return false; - } - controller.moveCards(permanent, Zone.EXILED, source, game); - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect(); - effect.setText("Return it to the battlefield under your control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(permanent.getId(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/e/EerieInterlude.java b/Mage.Sets/src/mage/cards/e/EerieInterlude.java index 2d05e905d47..d4268449675 100644 --- a/Mage.Sets/src/mage/cards/e/EerieInterlude.java +++ b/Mage.Sets/src/mage/cards/e/EerieInterlude.java @@ -1,25 +1,12 @@ package mage.cards.e; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; -import mage.cards.*; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.StaticFilters; import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.targetpointer.FixedTargets; -import mage.util.CardUtil; -import mage.util.ExileUtil; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -32,8 +19,8 @@ public final class EerieInterlude extends CardImpl { // Exile any number of target creatures you control. Return those cards to the // battlefield under their owner's control at the beginning of the next end step. - this.getSpellAbility().addEffect(new EerieInterludeEffect()); - this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, new FilterControlledCreaturePermanent(), false)); + this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect()); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE, StaticFilters.FILTER_CONTROLLED_CREATURES, false)); } private EerieInterlude(final EerieInterlude card) { @@ -45,46 +32,3 @@ public final class EerieInterlude extends CardImpl { return new EerieInterlude(this); } } - -class EerieInterludeEffect extends OneShotEffect { - - public EerieInterludeEffect() { - super(Outcome.Neutral); - staticText = "Exile any number of target creatures you control. Return those cards to the battlefield under their owner's control at the beginning of the next end step"; - } - - private EerieInterludeEffect(final EerieInterludeEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && controller != null) { - Set toExile = new HashSet<>(); - for (UUID targetId : getTargetPointer().getTargets(game, source)) { - Permanent targetCreature = game.getPermanent(targetId); - if (targetCreature != null) { - toExile.add(targetCreature); - } - } - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName()); - - Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game); - - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTargets(cardsToReturn, game)); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - return true; - } - return false; - } - - @Override - public EerieInterludeEffect copy() { - return new EerieInterludeEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/f/Flickerwisp.java b/Mage.Sets/src/mage/cards/f/Flickerwisp.java index 43de4b73bf3..2ba4d1fe1b8 100644 --- a/Mage.Sets/src/mage/cards/f/Flickerwisp.java +++ b/Mage.Sets/src/mage/cards/f/Flickerwisp.java @@ -3,24 +3,15 @@ package mage.cards.f; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -46,7 +37,7 @@ public final class Flickerwisp extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Flickerwisp enters the battlefield, exile another target permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new EntersBattlefieldTriggeredAbility(new FlickerwispEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } @@ -60,38 +51,3 @@ public final class Flickerwisp extends CardImpl { return new Flickerwisp(this); } } - -class FlickerwispEffect extends OneShotEffect { - - public FlickerwispEffect() { - super(Outcome.Detriment); - staticText = "exile another target permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private FlickerwispEffect(final FlickerwispEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (controller != null && permanent != null && sourcePermanent != null) { - if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - } - return false; - } - - @Override - public FlickerwispEffect copy() { - return new FlickerwispEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/g/GalepowderMage.java b/Mage.Sets/src/mage/cards/g/GalepowderMage.java index b97dc266ea4..91b441fdc4a 100644 --- a/Mage.Sets/src/mage/cards/g/GalepowderMage.java +++ b/Mage.Sets/src/mage/cards/g/GalepowderMage.java @@ -1,27 +1,16 @@ package mage.cards.g; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -41,7 +30,7 @@ public final class GalepowderMage extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // Whenever Galepowder Mage attacks, exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new AttacksTriggeredAbility(new GalepowderMageEffect(), false); + Ability ability = new AttacksTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect(), false); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); this.addAbility(ability); } @@ -55,45 +44,3 @@ public final class GalepowderMage extends CardImpl { return new GalepowderMage(this); } } - -class GalepowderMageEffect extends OneShotEffect { - - public GalepowderMageEffect() { - super(Outcome.Benefit); - this.staticText = "exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private GalepowderMageEffect(final GalepowderMageEffect effect) { - super(effect); - } - - @Override - public GalepowderMageEffect copy() { - return new GalepowderMageEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (controller != null && sourceObject != null) { - if (getTargetPointer().getFirst(game, source) != null) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - UUID exileId = UUID.randomUUID(); - if (controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - Card card = game.getCard(getTargetPointer().getFirst(game, source)); - if (card != null) { - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTarget(card.getId(), game.getState().getZoneChangeCounter(card.getId()))); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/g/GlimmerpointStag.java b/Mage.Sets/src/mage/cards/g/GlimmerpointStag.java index 3df760a52f3..98f7ee88615 100644 --- a/Mage.Sets/src/mage/cards/g/GlimmerpointStag.java +++ b/Mage.Sets/src/mage/cards/g/GlimmerpointStag.java @@ -3,24 +3,15 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.filter.FilterPermanent; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -46,7 +37,7 @@ public final class GlimmerpointStag extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // When Glimmerpoint Stag enters the battlefield, exile another target permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability etbAbility = new EntersBattlefieldTriggeredAbility(new GlimmerpointStagEffect()); + Ability etbAbility = new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()); etbAbility.addTarget(new TargetPermanent(filter)); this.addAbility(etbAbility); } @@ -60,42 +51,3 @@ public final class GlimmerpointStag extends CardImpl { return new GlimmerpointStag(this); } } - -class GlimmerpointStagEffect extends OneShotEffect { - - private static final String effectText = "exile another target permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - - GlimmerpointStagEffect() { - super(Outcome.Detriment); - staticText = effectText; - } - - private GlimmerpointStagEffect(final GlimmerpointStagEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - int zcc = permanent.getZoneChangeCounter(game); - controller.moveCards(permanent, Zone.EXILED, source, game); - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTarget(permanent.getId(), zcc + 1)); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } - return true; - } - return false; - } - - @Override - public GlimmerpointStagEffect copy() { - return new GlimmerpointStagEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/g/GuardianOfGhirapur.java b/Mage.Sets/src/mage/cards/g/GuardianOfGhirapur.java index 509517b066e..f6e9a2e9ceb 100644 --- a/Mage.Sets/src/mage/cards/g/GuardianOfGhirapur.java +++ b/Mage.Sets/src/mage/cards/g/GuardianOfGhirapur.java @@ -3,22 +3,16 @@ package mage.cards.g; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AnotherPredicate; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -27,6 +21,15 @@ import java.util.UUID; */ public final class GuardianOfGhirapur extends CardImpl { + private static final FilterControlledPermanent filter = new FilterControlledPermanent("other target creature or artifact you control"); + static { + filter.add(Predicates.or( + CardType.CREATURE.getPredicate(), + CardType.ARTIFACT.getPredicate() + )); + filter.add(AnotherPredicate.instance); + } + public GuardianOfGhirapur(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); @@ -38,10 +41,8 @@ public final class GuardianOfGhirapur extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Guardian of Ghirapur enters the battlefield, exile up to one other target creature or artifact you control. Return it to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new EntersBattlefieldTriggeredAbility(new GuardianOfGhirapurEffect()); - ability.addTarget(new TargetPermanent( - 0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_ARTIFACT_OR_CREATURE - )); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); + ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability); } @@ -54,36 +55,3 @@ public final class GuardianOfGhirapur extends CardImpl { return new GuardianOfGhirapur(this); } } - -class GuardianOfGhirapurEffect extends OneShotEffect { - - GuardianOfGhirapurEffect() { - super(Outcome.Benefit); - staticText = "exile up to one other target creature or artifact you control. " + - "Return it to the battlefield under its owner's control at the beginning of the next end step"; - } - - private GuardianOfGhirapurEffect(final GuardianOfGhirapurEffect effect) { - super(effect); - } - - @Override - public GuardianOfGhirapurEffect copy() { - return new GuardianOfGhirapurEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (player == null || permanent == null) { - return false; - } - player.moveCards(permanent, Zone.EXILED, source, game); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setTargetPointer(new FixedTarget(permanent.getId(), game)) - ), source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/l/LaezelsAcrobatics.java b/Mage.Sets/src/mage/cards/l/LaezelsAcrobatics.java index 664d353afec..20258b8cb21 100644 --- a/Mage.Sets/src/mage/cards/l/LaezelsAcrobatics.java +++ b/Mage.Sets/src/mage/cards/l/LaezelsAcrobatics.java @@ -1,139 +1,97 @@ package mage.cards.l; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.InfoEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; -import mage.abilities.effects.common.RollDieWithResultTableEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; +import mage.abilities.effects.common.*; +import mage.cards.*; import mage.constants.CardType; +import mage.constants.PutCards; +import mage.constants.Zone; import mage.filter.common.FilterControlledCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.filter.predicate.permanent.TokenPredicate; +import mage.game.Game; import mage.players.Player; import mage.target.targetpointer.FixedTargets; -import mage.util.CardUtil; -import mage.util.ExileUtil; -import java.util.HashSet; -import java.util.List; -import java.util.Set; import java.util.UUID; /** - * @author TheElk801 + * @author xenohedron */ public final class LaezelsAcrobatics extends CardImpl { - public LaezelsAcrobatics(UUID ownerId, CardSetInfo setInfo) { - super(ownerId, setInfo, new CardType[] { CardType.INSTANT }, "{3}{W}"); + public LaezelsAcrobatics(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}"); - this.getSpellAbility().addEffect(new LaezelsAcrobaticsEffect()); - } + this.getSpellAbility().addEffect(new LaezelsAcrobaticsEffect()); + } - private LaezelsAcrobatics(final LaezelsAcrobatics card) { - super(card); - } + private LaezelsAcrobatics(final LaezelsAcrobatics card) { + super(card); + } - @Override - public LaezelsAcrobatics copy() { - return new LaezelsAcrobatics(this); - } + @Override + public LaezelsAcrobatics copy() { + return new LaezelsAcrobatics(this); + } } class LaezelsAcrobaticsEffect extends RollDieWithResultTableEffect { - LaezelsAcrobaticsEffect() { - super(20, "Exile all nontoken creatures you control, then roll a d20"); - this.addTableEntry( - 1, 9, - new InfoEffect("Return those cards to the battlefield under their owner's control at the " + - "beginning of the next end step.")); - this.addTableEntry( - 10, 20, - new InfoEffect( - "Return those cards to the battlefield under their owner's control, then exile them again. Return those cards to the battlefield under their owner's control at the beginning of the next end step.")); - } + private static final FilterControlledCreaturePermanent creatureFilter = new FilterControlledCreaturePermanent(); - private LaezelsAcrobaticsEffect(final LaezelsAcrobaticsEffect effect) { - super(effect); - } - - @Override - public LaezelsAcrobaticsEffect copy() { - return new LaezelsAcrobaticsEffect(this); - } - - private static final FilterControlledCreaturePermanent creatureFilter = new FilterControlledCreaturePermanent(); - - static { - creatureFilter.add(TokenPredicate.FALSE); - } - - private Set getNontokenCreatureCards(Game game, Player player) { - List playerPermanents = game - .getState() - .getBattlefield() - .getActivePermanents(creatureFilter, player.getId(), game); - - Set toExile = new HashSet<>(); - - for (Permanent permanent : playerPermanents) { - if (permanent != null) { - toExile.add(permanent); - } + static { + creatureFilter.add(TokenPredicate.FALSE); } - return toExile; - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - - if (player == null) { - return false; + LaezelsAcrobaticsEffect() { + super(20, "Exile all nontoken creatures you control, then roll a d20"); + this.addTableEntry( + 1, 9, + new InfoEffect("Return those cards to the battlefield under their owner's control at the " + + "beginning of the next end step.")); + this.addTableEntry( + 10, 20, + new InfoEffect( + "Return those cards to the battlefield under their owner's control, then exile them again. Return those cards to the battlefield under their owner's control at the beginning of the next end step.")); } - Set toExile = getNontokenCreatureCards(game, player); - - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - player.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName()); - - Integer result = player.rollDice(outcome, source, game, 20); - - Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game); - - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTargets(cardsToReturn, game)); - - if (result < 10) { - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } else { - effect.apply(game, source); - - toExile = getNontokenCreatureCards(game, player); - exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - player.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName()); - - cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game); - effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTargets(cardsToReturn, game)); - - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - effect); - game.addDelayedTriggeredAbility(delayedAbility, source); + private LaezelsAcrobaticsEffect(final LaezelsAcrobaticsEffect effect) { + super(effect); } - return true; - } + @Override + public LaezelsAcrobaticsEffect copy() { + return new LaezelsAcrobaticsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Cards toFlicker = new CardsImpl(game.getBattlefield().getActivePermanents(creatureFilter, controller.getId(), game)); + controller.moveCards(toFlicker, Zone.EXILED, source, game); + game.getState().processAction(game); + int result = controller.rollDice(outcome, source, game, 20); + if (result >= 1 && result <= 9) { + Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); + effect.setTargetPointer(new FixedTargets(new CardsImpl(toFlicker), game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); + } else if (result >= 10 && result <= 20) { + for (UUID cardId : toFlicker) { + Card card = game.getCard(cardId); + if (card != null) { + PutCards.BATTLEFIELD.moveCard(game.getPlayer(card.getOwnerId()), card.getMainCard(), source, game, "card"); + } + } + game.getState().processAction(game); + Effect effect = new ExileReturnBattlefieldNextEndStepTargetEffect(); + effect.setTargetPointer(new FixedTargets(toFlicker, game)); + effect.apply(game, source); + } + return true; + } } diff --git a/Mage.Sets/src/mage/cards/l/Liberate.java b/Mage.Sets/src/mage/cards/l/Liberate.java index dab284fb181..da9ecdbc5e3 100644 --- a/Mage.Sets/src/mage/cards/l/Liberate.java +++ b/Mage.Sets/src/mage/cards/l/Liberate.java @@ -1,20 +1,11 @@ package mage.cards.l; -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; -import mage.cards.Card; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetControlledCreaturePermanent; -import mage.target.targetpointer.FixedTarget; +import mage.filter.StaticFilters; +import mage.target.TargetPermanent; import java.util.UUID; @@ -27,8 +18,8 @@ public final class Liberate extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Exile target creature you control. Return that card to the battlefield under its owner's control at the beginning of the next end step. - this.getSpellAbility().addEffect(new LiberateEffect()); - this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED)); } private Liberate(final Liberate card) { @@ -40,38 +31,3 @@ public final class Liberate extends CardImpl { return new Liberate(this); } } - -class LiberateEffect extends OneShotEffect { - - LiberateEffect() { - super(Outcome.Detriment); - staticText = "exile target creature you control. Return that card to the battlefield " + - "under its owner's control at the beginning of the next end step"; - } - - private LiberateEffect(final LiberateEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (player == null || permanent == null) { - return false; - } - Card card = permanent.getMainCard(); - player.moveCards(permanent, Zone.EXILED, source, game); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setText("Return that card to the battlefield under its owner's control at the beginning of the next end step") - .setTargetPointer(new FixedTarget(card, game)) - ), source); - return true; - } - - @Override - public LiberateEffect copy() { - return new LiberateEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/m/MistmeadowVanisher.java b/Mage.Sets/src/mage/cards/m/MistmeadowVanisher.java index 78f513a9730..abcf0c4529a 100644 --- a/Mage.Sets/src/mage/cards/m/MistmeadowVanisher.java +++ b/Mage.Sets/src/mage/cards/m/MistmeadowVanisher.java @@ -3,20 +3,15 @@ package mage.cards.m; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesTappedSourceTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; import mage.filter.FilterPermanent; import mage.filter.common.FilterNonlandPermanent; import mage.filter.predicate.permanent.TokenPredicate; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -40,7 +35,7 @@ public final class MistmeadowVanisher extends CardImpl { this.toughness = new MageInt(2); // Whenever Mistmeadow Vanisher becomes tapped, exile up to one target nonland, nontoken permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new BecomesTappedSourceTriggeredAbility(new MistmeadowVanisherEffect()); + Ability ability = new BecomesTappedSourceTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect()); ability.addTarget(new TargetPermanent(0, 1, filter)); this.addAbility(ability); } @@ -54,37 +49,3 @@ public final class MistmeadowVanisher extends CardImpl { return new MistmeadowVanisher(this); } } - -class MistmeadowVanisherEffect extends OneShotEffect { - - MistmeadowVanisherEffect() { - super(Outcome.Benefit); - staticText = "exile up to one target nonland, nontoken permanent. Return that card to the battlefield " + - "under its owner's control at the beginning of the next end step"; - } - - private MistmeadowVanisherEffect(final MistmeadowVanisherEffect effect) { - super(effect); - } - - @Override - public MistmeadowVanisherEffect copy() { - return new MistmeadowVanisherEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (player == null || permanent == null) { - return false; - } - player.moveCards(permanent, Zone.EXILED, source, game); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( - new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) - .setTargetPointer(new FixedTarget(permanent, game)), - TargetController.ANY - ), source); - return true; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MistmeadowWitch.java b/Mage.Sets/src/mage/cards/m/MistmeadowWitch.java index 33c2a0c3a29..9b455c58d17 100644 --- a/Mage.Sets/src/mage/cards/m/MistmeadowWitch.java +++ b/Mage.Sets/src/mage/cards/m/MistmeadowWitch.java @@ -1,4 +1,3 @@ - package mage.cards.m; import java.util.UUID; @@ -6,7 +5,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.common.MistmeadowWitchEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -29,7 +28,7 @@ public final class MistmeadowWitch extends CardImpl { this.toughness = new MageInt(1); // {2}{W}{U}: Exile target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MistmeadowWitchEffect(), new ManaCostsImpl<>("{2}{W}{U}")); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldNextEndStepTargetEffect(), new ManaCostsImpl<>("{2}{W}{U}")); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } @@ -43,4 +42,3 @@ public final class MistmeadowWitch extends CardImpl { return new MistmeadowWitch(this); } } - diff --git a/Mage.Sets/src/mage/cards/o/OathOfTeferi.java b/Mage.Sets/src/mage/cards/o/OathOfTeferi.java index db126e00780..53732db55ff 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfTeferi.java +++ b/Mage.Sets/src/mage/cards/o/OathOfTeferi.java @@ -3,20 +3,15 @@ package mage.cards.o; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -31,7 +26,7 @@ public final class OathOfTeferi extends CardImpl { this.supertype.add(SuperType.LEGENDARY); // When Oath of Teferi enters the battlefield, exile another target permanent you control. Return it to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new EntersBattlefieldTriggeredAbility(new OathOfTeferiBlinkEffect()); + Ability ability = new EntersBattlefieldTriggeredAbility(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_PERMANENT)); this.addAbility(ability); @@ -49,45 +44,6 @@ public final class OathOfTeferi extends CardImpl { } } -class OathOfTeferiBlinkEffect extends OneShotEffect { - - private static final String effectText = "exile another target permanent you control. Return it to the battlefield under its owner's control at the beginning of the next end step"; - - OathOfTeferiBlinkEffect() { - super(Outcome.Detriment); - staticText = effectText; - } - - private OathOfTeferiBlinkEffect(final OathOfTeferiBlinkEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - int zcc = permanent.getZoneChangeCounter(game); - controller.moveCards(permanent, Zone.EXILED, source, game); - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTarget(permanent.getId(), zcc + 1)); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } - return true; - } - return false; - } - - @Override - public OathOfTeferiBlinkEffect copy() { - return new OathOfTeferiBlinkEffect(this); - } - -} - class OathOfTeferiLoyaltyEffect extends ContinuousEffectImpl { public OathOfTeferiLoyaltyEffect() { diff --git a/Mage.Sets/src/mage/cards/r/RoonOfTheHiddenRealm.java b/Mage.Sets/src/mage/cards/r/RoonOfTheHiddenRealm.java index bc5fc376508..eafd2fc37d6 100644 --- a/Mage.Sets/src/mage/cards/r/RoonOfTheHiddenRealm.java +++ b/Mage.Sets/src/mage/cards/r/RoonOfTheHiddenRealm.java @@ -1,26 +1,21 @@ package mage.cards.r; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.VigilanceAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.*; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.Zone; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -43,7 +38,7 @@ public final class RoonOfTheHiddenRealm extends CardImpl { // Trample this.addAbility(TrampleAbility.getInstance()); // {2}, {tap}: Exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RoonOfTheHiddenRealmEffect(), new GenericManaCost(2)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExileReturnBattlefieldNextEndStepTargetEffect(), new GenericManaCost(2)); ability.addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_ANOTHER_TARGET_CREATURE)); ability.addCost(new TapSourceCost()); this.addAbility(ability); @@ -59,43 +54,3 @@ public final class RoonOfTheHiddenRealm extends CardImpl { return new RoonOfTheHiddenRealm(this); } } - -class RoonOfTheHiddenRealmEffect extends OneShotEffect { - - public RoonOfTheHiddenRealmEffect() { - super(Outcome.Benefit); - this.staticText = "Exile another target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private RoonOfTheHiddenRealmEffect(final RoonOfTheHiddenRealmEffect effect) { - super(effect); - } - - @Override - public RoonOfTheHiddenRealmEffect copy() { - return new RoonOfTheHiddenRealmEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (controller != null && sourceObject != null) { - if (getTargetPointer().getFirst(game, source) != null) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - int zcc = permanent.getZoneChangeCounter(game); - if (controller.moveCards(permanent, Zone.EXILED, source, game)) { - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTarget(permanent.getId(), zcc + 1)); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility - = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/s/Skybind.java b/Mage.Sets/src/mage/cards/s/Skybind.java index f070690cf60..c3ce69947a3 100644 --- a/Mage.Sets/src/mage/cards/s/Skybind.java +++ b/Mage.Sets/src/mage/cards/s/Skybind.java @@ -2,20 +2,13 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.abilityword.ConstellationAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicates; -import mage.game.Game; -import mage.game.permanent.Permanent; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -34,7 +27,7 @@ public final class Skybind extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}"); // Constellation — When Skybind or another enchantment enters the battlefield under your control, exile target nonenchantment permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new ConstellationAbility(new SkybindEffect(), false); + Ability ability = new ConstellationAbility(new ExileReturnBattlefieldNextEndStepTargetEffect(), false); ability.addTarget(new TargetPermanent(filter)); this.addAbility(ability); } @@ -48,36 +41,3 @@ public final class Skybind extends CardImpl { return new Skybind(this); } } - -class SkybindEffect extends OneShotEffect { - - public SkybindEffect() { - super(Outcome.Detriment); - staticText = "exile target nonenchantment permanent. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private SkybindEffect(final SkybindEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (permanent != null && sourcePermanent != null) { - if (permanent.moveToExile(source.getSourceId(), sourcePermanent.getName(), source, game)) { - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - } - return false; - } - - @Override - public SkybindEffect copy() { - return new SkybindEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/s/SuddenDisappearance.java b/Mage.Sets/src/mage/cards/s/SuddenDisappearance.java index cafe7861ea1..c3e2fe5d527 100644 --- a/Mage.Sets/src/mage/cards/s/SuddenDisappearance.java +++ b/Mage.Sets/src/mage/cards/s/SuddenDisappearance.java @@ -1,22 +1,21 @@ package mage.cards.s; -import mage.MageObject; import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; -import mage.cards.*; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.common.FilterNonlandPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.targetpointer.FixedTargets; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -45,9 +44,7 @@ public final class SuddenDisappearance extends CardImpl { class SuddenDisappearanceEffect extends OneShotEffect { - private static FilterNonlandPermanent filter = new FilterNonlandPermanent(); - - public SuddenDisappearanceEffect() { + SuddenDisappearanceEffect() { super(Outcome.Exile); staticText = "Exile all nonland permanents target player controls. Return the exiled cards to the battlefield under their owner's control at the beginning of the next end step"; } @@ -58,25 +55,17 @@ class SuddenDisappearanceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject != null) { - Set permsSet = new HashSet<>(game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game)); - if (!permsSet.isEmpty()) { - controller.moveCardsToExile(permsSet, source, game, true, source.getSourceId(), sourceObject.getIdName()); - Cards targets = new CardsImpl(); - for (Card card : permsSet) { - targets.add(card.getId()); - } - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, true); - effect.setText("Return the exiled cards to the battlefield under their owner's control"); - effect.setTargetPointer(new FixedTargets(targets, game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - } - return true; + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null) { + return false; } - - return false; + Cards targets = new CardsImpl(game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENTS_NON_LAND, player.getId(), game)); + if (targets.isEmpty()) { + return false; + } + Effect effect = new ExileReturnBattlefieldNextEndStepTargetEffect().returnExiledOnly(true); + effect.setTargetPointer(new FixedTargets(targets, game)); + return effect.apply(game, source); } @Override diff --git a/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java b/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java index d10305db0c9..58b0c55e6f8 100644 --- a/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java +++ b/Mage.Sets/src/mage/cards/t/TouchTheSpiritRealm.java @@ -1,26 +1,17 @@ - package mage.cards.t; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.keyword.ChannelAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; + +import java.util.UUID; /** * @@ -39,7 +30,8 @@ public final class TouchTheSpiritRealm extends CardImpl { // Channel - {1}{W}, Discard Touch the Spirit Realm: Exile target artifact or creature. // Return it to the battlefield under its owner's control at the beginning of the next end step. - Ability channelAbility = new ChannelAbility("{1}{W}", new TouchTheSpiritRealmEffect()); + Ability channelAbility = new ChannelAbility("{1}{W}", + new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); channelAbility.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_CREATURE)); this.addAbility(channelAbility); } @@ -53,35 +45,3 @@ public final class TouchTheSpiritRealm extends CardImpl { return new TouchTheSpiritRealm(this); } } - -class TouchTheSpiritRealmEffect extends OneShotEffect { - - public TouchTheSpiritRealmEffect() { - super(Outcome.Detriment); - staticText = "Exile target artifact or creature. Return it to the battlefield under its owner's control at the beginning of the next end step"; - } - - private TouchTheSpiritRealmEffect(final TouchTheSpiritRealmEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (player == null || permanent == null) { - return false; - } - Card card = permanent.getMainCard(); - player.moveCardsToExile(permanent, source, game, true, CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source)); - ReturnToBattlefieldUnderOwnerControlTargetEffect returnEffect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - returnEffect.setTargetPointer(new FixedTarget(card,game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(returnEffect), source); - return true; - } - - @Override - public TouchTheSpiritRealmEffect copy() { - return new TouchTheSpiritRealmEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/t/TurnToMist.java b/Mage.Sets/src/mage/cards/t/TurnToMist.java index d6b78407334..dc0d991e4d1 100644 --- a/Mage.Sets/src/mage/cards/t/TurnToMist.java +++ b/Mage.Sets/src/mage/cards/t/TurnToMist.java @@ -2,7 +2,7 @@ package mage.cards.t; import java.util.UUID; -import mage.abilities.effects.common.MistmeadowWitchEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -19,7 +19,7 @@ public final class TurnToMist extends CardImpl { // Exile target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step. - this.getSpellAbility().addEffect(new MistmeadowWitchEffect()); + this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/cards/t/TwiningTwins.java b/Mage.Sets/src/mage/cards/t/TwiningTwins.java index 6d0f5b5a8ce..b0406116218 100644 --- a/Mage.Sets/src/mage/cards/t/TwiningTwins.java +++ b/Mage.Sets/src/mage/cards/t/TwiningTwins.java @@ -1,27 +1,18 @@ package mage.cards.t; import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.WardAbility; import mage.cards.AdventureCard; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.filter.StaticFilters; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.TokenPredicate; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; import java.util.UUID; @@ -30,6 +21,11 @@ import java.util.UUID; */ public final class TwiningTwins extends AdventureCard { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature"); + static { + filter.add(TokenPredicate.FALSE); + } + public TwiningTwins(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, new CardType[]{CardType.INSTANT}, "{2}{U}{U}", "Swift Spiral", "{1}{W}"); @@ -49,8 +45,8 @@ public final class TwiningTwins extends AdventureCard { // Swift Spiral // Exile target nontoken creature. Return it to the battlefield under its owner’s control at the beginning of the next end step. - this.getSpellCard().getSpellAbility().addEffect(new TwiningTwinsEffect()); - this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent(StaticFilters.FILTER_CREATURE_NON_TOKEN)); + this.getSpellCard().getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); + this.getSpellCard().getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); this.finalizeAdventure(); } @@ -64,36 +60,3 @@ public final class TwiningTwins extends AdventureCard { return new TwiningTwins(this); } } - -class TwiningTwinsEffect extends OneShotEffect { - - TwiningTwinsEffect() { - super(Outcome.Detriment); - staticText = "Exile target nontoken creature. Return it to the battlefield under its " - + "owner's control at the beginning of the next end step"; - } - - private TwiningTwinsEffect(final TwiningTwinsEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (player == null || permanent == null) { - return false; - } - player.moveCardsToExile(permanent, source, game, true, CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source)); - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setText("Return the exiled card to the battlefield under its owner's control"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - - @Override - public TwiningTwinsEffect copy() { - return new TwiningTwinsEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VenserTheSojourner.java b/Mage.Sets/src/mage/cards/v/VenserTheSojourner.java index 62755d7c195..4016886b624 100644 --- a/Mage.Sets/src/mage/cards/v/VenserTheSojourner.java +++ b/Mage.Sets/src/mage/cards/v/VenserTheSojourner.java @@ -1,28 +1,19 @@ - package mage.cards.v; -import java.util.UUID; -import mage.MageObject; -import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.effects.common.GetEmblemEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlTargetEffect; import mage.abilities.effects.common.combat.CantBeBlockedAllEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.filter.FilterPermanent; import mage.filter.StaticFilters; -import mage.game.Game; import mage.game.command.emblems.VenserTheSojournerEmblem; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; /** * @author nantuko @@ -43,7 +34,7 @@ public final class VenserTheSojourner extends CardImpl { this.setStartingLoyalty(3); // +2: Exile target permanent you own. Return it to the battlefield under your control at the beginning of the next end step. - LoyaltyAbility ability1 = new LoyaltyAbility(new VenserTheSojournerEffect(), 2); + LoyaltyAbility ability1 = new LoyaltyAbility(new ExileReturnBattlefieldNextEndStepTargetEffect().underYourControl(true).withTextThatCard(false), 2); Target target = new TargetPermanent(filter); ability1.addTarget(target); this.addAbility(ability1); @@ -66,46 +57,3 @@ public final class VenserTheSojourner extends CardImpl { } } - -class VenserTheSojournerEffect extends OneShotEffect { - - private static final String effectText = "Exile target permanent you own. Return it to the battlefield under your control at the beginning of the next end step"; - - VenserTheSojournerEffect() { - super(Outcome.Benefit); - staticText = effectText; - } - - private VenserTheSojournerEffect(final VenserTheSojournerEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (controller != null && sourceObject != null) { - if (getTargetPointer().getFirst(game, source) != null) { - Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (permanent != null) { - if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderYourControlTargetEffect(); - effect.setText("Return it to the battlefield under your control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(permanent.getId(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - } - } - - } - return false; - } - - @Override - public VenserTheSojournerEffect copy() { - return new VenserTheSojournerEffect(this); - } - -} diff --git a/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java b/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java index 9b6c5910cb5..efef911ca39 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfDeferment.java @@ -3,20 +3,17 @@ package mage.cards.v; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.FlashAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; -import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.target.targetpointer.FixedTarget; import mage.watchers.common.AttackedThisTurnWatcher; @@ -60,7 +57,7 @@ public final class VizierOfDeferment extends CardImpl { class VizierOfDefermentEffect extends OneShotEffect { - public VizierOfDefermentEffect() { + VizierOfDefermentEffect() { super(Outcome.Detriment); staticText = "you may exile target creature if it attacked or blocked this turn. " + "Return that card to the battlefield under its owner's control at the beginning of the next end step"; @@ -73,8 +70,6 @@ class VizierOfDefermentEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); AttackedThisTurnWatcher watcherAttacked = game.getState().getWatcher(AttackedThisTurnWatcher.class); BlockedThisTurnWatcher watcherBlocked = game.getState().getWatcher(BlockedThisTurnWatcher.class); boolean attackedOrBlocked = false; @@ -84,18 +79,12 @@ class VizierOfDefermentEffect extends OneShotEffect { if (watcherBlocked != null && watcherBlocked.checkIfBlocked(permanent, game)) { attackedOrBlocked = true; } - if (controller != null - && attackedOrBlocked - && sourcePermanent != null) { - if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } + if (!attackedOrBlocked) { + return false; } - return false; + Effect effect = new ExileReturnBattlefieldNextEndStepTargetEffect(); + effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); + return effect.apply(game, source); } @Override diff --git a/Mage.Sets/src/mage/cards/v/Voidwalk.java b/Mage.Sets/src/mage/cards/v/Voidwalk.java index 01896df48a0..8aa01009a51 100644 --- a/Mage.Sets/src/mage/cards/v/Voidwalk.java +++ b/Mage.Sets/src/mage/cards/v/Voidwalk.java @@ -1,22 +1,11 @@ package mage.cards.v; -import mage.MageObject; -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CipherEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -29,7 +18,7 @@ public final class Voidwalk extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}"); // Exile target creature. Return it to the battlefield under its owner's control at the beginning of the next end step. - this.getSpellAbility().addEffect(new VoidwalkEffect()); + this.getSpellAbility().addEffect(new ExileReturnBattlefieldNextEndStepTargetEffect().withTextThatCard(false)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); // Cipher @@ -45,38 +34,3 @@ public final class Voidwalk extends CardImpl { return new Voidwalk(this); } } - -class VoidwalkEffect extends OneShotEffect { - - public VoidwalkEffect() { - super(Outcome.Detriment); - staticText = "Exile target creature. Return it to the battlefield under its owner's control at the beginning of the next end step"; - } - - private VoidwalkEffect(final VoidwalkEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source); - if (controller != null && permanent != null && sourceObject != null) { - if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - } - return false; - } - - @Override - public VoidwalkEffect copy() { - return new VoidwalkEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/v/VoyagerStaff.java b/Mage.Sets/src/mage/cards/v/VoyagerStaff.java index 47c75c97ca5..73425c0f89b 100644 --- a/Mage.Sets/src/mage/cards/v/VoyagerStaff.java +++ b/Mage.Sets/src/mage/cards/v/VoyagerStaff.java @@ -2,22 +2,14 @@ package mage.cards.v; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.mana.GenericManaCost; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; -import mage.target.targetpointer.FixedTarget; import java.util.UUID; @@ -30,7 +22,9 @@ public final class VoyagerStaff extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); // {2}, Sacrifice Voyager Staff: Exile target creature. Return the exiled card to the battlefield under its owner's control at the beginning of the next end step. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VoyagerStaffEffect(), new GenericManaCost(2)); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new ExileReturnBattlefieldNextEndStepTargetEffect().returnExiledOnly(true), + new GenericManaCost(2)); ability.addCost(new SacrificeSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); @@ -45,38 +39,3 @@ public final class VoyagerStaff extends CardImpl { return new VoyagerStaff(this); } } - -class VoyagerStaffEffect extends OneShotEffect { - - public VoyagerStaffEffect() { - super(Outcome.Detriment); - staticText = "exile target creature. Return the exiled card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private VoyagerStaffEffect(final VoyagerStaffEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source)); - Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (controller != null && creature != null && sourcePermanent != null) { - if (controller.moveCardToExileWithInfo(creature, source.getSourceId(), sourcePermanent.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - //create delayed triggered ability - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, true); - effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step"); - effect.setTargetPointer(new FixedTarget(creature.getId(), game.getState().getZoneChangeCounter(creature.getId()))); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - } - return false; - } - - @Override - public VoyagerStaffEffect copy() { - return new VoyagerStaffEffect(this); - } -} diff --git a/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java index bf9f657b750..f85ab9ecd3e 100644 --- a/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java +++ b/Mage.Sets/src/mage/cards/y/YorionSkyNomad.java @@ -1,38 +1,42 @@ package mage.cards.y; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; +import mage.abilities.effects.common.ExileReturnBattlefieldNextEndStepTargetEffect; import mage.abilities.keyword.CompanionAbility; import mage.abilities.keyword.CompanionCondition; import mage.abilities.keyword.FlyingAbility; -import mage.cards.*; -import mage.constants.*; -import mage.filter.FilterPermanent; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.SuperType; +import mage.constants.TargetController; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.AnotherPredicate; -import mage.game.Game; -import mage.players.Player; import mage.target.TargetPermanent; -import mage.target.targetpointer.FixedTargets; -import mage.util.CardUtil; -import mage.util.ExileUtil; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; /** * @author TheElk801 */ public final class YorionSkyNomad extends CardImpl { + private static final FilterControlledPermanent filter = + new FilterControlledPermanent("other nonland permanents you own and control"); + static { + filter.add(Predicates.not(CardType.LAND.getPredicate())); + filter.add(TargetController.YOU.getOwnerPredicate()); + filter.add(AnotherPredicate.instance); + } + private static final String ruleText = "exile any number of other nonland permanents you own and control. " + + "Return those cards to the battlefield at the beginning of the next end step."; + public YorionSkyNomad(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[] {CardType.CREATURE}, "{3}{W/U}{W/U}"); @@ -50,7 +54,10 @@ public final class YorionSkyNomad extends CardImpl { // When Yorion enters the battlefield, exile any number of other nonland permanents you own // and control. Return those cards to the battlefield at the beginning of the next end step. - this.addAbility(new EntersBattlefieldTriggeredAbility(new YorionSkyNomadEffect())); + Ability ability = new EntersBattlefieldTriggeredAbility( + new ExileReturnBattlefieldNextEndStepTargetEffect().setText(ruleText)); + ability.addTarget(new TargetPermanent(0, Integer.MAX_VALUE, filter, true)); + this.addAbility(ability); } private YorionSkyNomad(final YorionSkyNomad card) { @@ -76,51 +83,3 @@ enum YorionSkyNomadCompanionCondition implements CompanionCondition { return deck.size() >= minimumDeckSize + 20; } } - -class YorionSkyNomadEffect extends OneShotEffect { - - private static final FilterPermanent filter = new FilterControlledPermanent("other nonland permanents you own and control"); - - static { - filter.add(Predicates.not(CardType.LAND.getPredicate())); - filter.add(TargetController.YOU.getOwnerPredicate()); - filter.add(AnotherPredicate.instance); - } - - YorionSkyNomadEffect() { - super(Outcome.Benefit); - staticText = "exile any number of other nonland permanents you own and control. " + - "Return those cards to the battlefield at the beginning of the next end step."; - } - - private YorionSkyNomadEffect(final YorionSkyNomadEffect effect) { - super(effect); - } - - @Override - public YorionSkyNomadEffect copy() { - return new YorionSkyNomadEffect(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) { - return false; - } - TargetPermanent target = new TargetPermanent(0, Integer.MAX_VALUE, filter, true); - controller.choose(outcome, target, source, game); - Set toExile = target.getTargets().stream().map(game::getPermanent).collect(Collectors.toSet()); - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - controller.moveCardsToExile(toExile, source, game, true, exileId, sourceObject.getIdName()); - - Cards cardsToReturn = ExileUtil.returnCardsFromExile(toExile, game); - - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setTargetPointer(new FixedTargets(cardsToReturn, game)); - AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); - game.addDelayedTriggeredAbility(delayedAbility, source); - return true; - } -} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/LaezelsAcrobaticsTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/LaezelsAcrobaticsTest.java new file mode 100644 index 00000000000..62ee8b77469 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/clb/LaezelsAcrobaticsTest.java @@ -0,0 +1,83 @@ +package org.mage.test.cards.single.clb; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +public class LaezelsAcrobaticsTest extends CardTestPlayerBase { + + // {3}{W} Instant + // Exile all nontoken creatures you control, then roll a d20. + // 1—9 | Return those cards to the battlefield under their owner’s control at the beginning of the next end step. + // 10—20 | Return those cards to the battlefield under their owner’s control, then exile them again. Return those cards to the battlefield under their owner’s control at the beginning of the next end step. + private static final String acrobatics = "Lae'zel's Acrobatics"; + + // {2}{W} Creature — Human Knight + // First strike + // When Attended Knight enters the battlefield, create a 1/1 white Soldier creature token. + private static final String knight = "Attended Knight"; + // When Auramancer enters the battlefield, you may return target enchantment card from your graveyard to your hand. + private static final String auramancer = "Auramancer"; + private static final String wings = "Nimbus Wings"; // aura + // Whenever you roll one or more dice, Brazen Dwarf deals 1 damage to each opponent. + private static final String dwarf = "Brazen Dwarf"; // not on the battlefield when die rolled, so should not trigger + + @Test + public void testRollLow() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 7); + addCard(Zone.BATTLEFIELD, playerA, auramancer); + addCard(Zone.BATTLEFIELD, playerA, dwarf); + addCard(Zone.HAND, playerA, knight); + addCard(Zone.HAND, playerA, acrobatics); + addCard(Zone.GRAVEYARD, playerA, wings, 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, knight); + setDieRollResult(playerA, 9); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, acrobatics); + setChoice(playerA, "When {this} enters the battlefield, create"); // order triggers + setChoice(playerA, true); // Auramancer: yes to return + addTarget(playerA, wings); // enchantment to return + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertGraveyardCount(playerA, wings, 1); + assertHandCount(playerA, wings, 1); + assertPermanentCount(playerA, "Soldier Token", 2); + assertLife(playerA, 20); + assertLife(playerB, 20); + } + + @Test + public void testRollHigh() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 7); + addCard(Zone.BATTLEFIELD, playerA, auramancer); + addCard(Zone.BATTLEFIELD, playerA, dwarf); + addCard(Zone.HAND, playerA, knight); + addCard(Zone.HAND, playerA, acrobatics); + addCard(Zone.GRAVEYARD, playerA, wings, 2); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, knight); + setDieRollResult(playerA, 10); + castSpell(1, PhaseStep.BEGIN_COMBAT, playerA, acrobatics); + setChoice(playerA, "When {this} enters the battlefield, create"); // order triggers + setChoice(playerA, true); // Auramancer: yes to return + addTarget(playerA, wings); // enchantment to return + setChoice(playerA, "When {this} enters the battlefield, create"); // order triggers + setChoice(playerA, true); // Auramancer: yes to return + addTarget(playerA, wings); // enchantment to return + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.UPKEEP); + execute(); + + assertGraveyardCount(playerA, wings, 0); + assertHandCount(playerA, wings, 2); + assertPermanentCount(playerA, "Soldier Token", 3); + assertLife(playerA, 20); + assertLife(playerB, 20); + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldNextEndStepTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldNextEndStepTargetEffect.java new file mode 100644 index 00000000000..d1513b2090f --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileReturnBattlefieldNextEndStepTargetEffect.java @@ -0,0 +1,110 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTargets; +import mage.util.CardUtil; + +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author xenohedron + */ +public class ExileReturnBattlefieldNextEndStepTargetEffect extends OneShotEffect { + + private boolean yourControl; + private boolean textThatCard; + private boolean exiledOnly; + + public ExileReturnBattlefieldNextEndStepTargetEffect() { + super(Outcome.Neutral); + this.yourControl = false; + this.textThatCard = true; + this.exiledOnly = false; + } + + protected ExileReturnBattlefieldNextEndStepTargetEffect(final ExileReturnBattlefieldNextEndStepTargetEffect effect) { + super(effect); + this.yourControl = effect.yourControl; + this.textThatCard = effect.textThatCard; + this.exiledOnly = effect.exiledOnly; + } + + public ExileReturnBattlefieldNextEndStepTargetEffect underYourControl(boolean yourControl) { + this.yourControl = yourControl; + return this; + } + + public ExileReturnBattlefieldNextEndStepTargetEffect withTextThatCard(boolean textThatCard) { + this.textThatCard = textThatCard; + return this; + } + + public ExileReturnBattlefieldNextEndStepTargetEffect returnExiledOnly(boolean exiledOnly) { + this.exiledOnly = exiledOnly; + return this; + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + Set toExile = getTargetPointer().getTargets(game, source) + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); + if (toExile.isEmpty()) { + return false; + } + controller.moveCardsToExile(toExile, source, game, true, CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source)); + Effect effect = yourControl + ? new ReturnToBattlefieldUnderYourControlTargetEffect(exiledOnly) + : new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, exiledOnly); + effect.setTargetPointer(new FixedTargets(new CardsImpl(toExile), game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); + return true; + } + + @Override + public ExileReturnBattlefieldNextEndStepTargetEffect copy() { + return new ExileReturnBattlefieldNextEndStepTargetEffect(this); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + String text = "exile " + getTargetPointer().describeTargets(mode.getTargets(), "that creature") + ". Return "; + boolean plural = getTargetPointer().isPlural(mode.getTargets()); + if (exiledOnly) { + text += plural ? "the exiled cards" : "the exiled card"; + } else if (textThatCard) { + text += plural ? "those cards" : "that card"; + } else { + text += plural ? "them" : "it"; + } + text += " to the battlefield"; + if (yourControl) { + text += " under your control"; + } else { + text += " under " + (plural ? "their" : "its") + " owner's control"; + } + return text + " at the beginning of the next end step"; + } + +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java index 7d6a35a8db6..13252efdfa8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ExileThenReturnTargetEffect.java @@ -8,12 +8,12 @@ import mage.constants.Outcome; import mage.constants.PutCards; import mage.constants.Zone; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; import java.util.LinkedHashSet; +import java.util.Objects; import java.util.Set; -import java.util.UUID; +import java.util.stream.Collectors; /** * @author xenohedron @@ -50,15 +50,15 @@ public class ExileThenReturnTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Set toFlicker = new LinkedHashSet<>(); - for (UUID targetId : getTargetPointer().getTargets(game, source)) { - Permanent permanent = game.getPermanent(targetId); - if (permanent == null) { - continue; - } - toFlicker.add(permanent); + if (controller == null) { + return false; } - if (controller == null || toFlicker.isEmpty()) { + Set toFlicker = getTargetPointer().getTargets(game, source) + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); + if (toFlicker.isEmpty()) { return false; } controller.moveCards(toFlicker, Zone.EXILED, source, game); diff --git a/Mage/src/main/java/mage/abilities/effects/common/MistmeadowWitchEffect.java b/Mage/src/main/java/mage/abilities/effects/common/MistmeadowWitchEffect.java deleted file mode 100644 index 0f546759dfe..00000000000 --- a/Mage/src/main/java/mage/abilities/effects/common/MistmeadowWitchEffect.java +++ /dev/null @@ -1,47 +0,0 @@ -package mage.abilities.effects.common; - -import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; -import mage.util.CardUtil; - -/** - * Created by Eric on 9/24/2016. - */ -public class MistmeadowWitchEffect extends OneShotEffect { - - public MistmeadowWitchEffect() { - super(Outcome.Detriment); - staticText = "Exile target creature. Return that card to the battlefield under its owner's control at the beginning of the next end step"; - } - - private MistmeadowWitchEffect(final MistmeadowWitchEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (player == null || permanent == null) { - return false; - } - player.moveCardsToExile(permanent, source, game, true, CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source)); - Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false); - effect.setText("Return the exiled card to the battlefield under its owner's control"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } - - @Override - public MistmeadowWitchEffect copy() { - return new MistmeadowWitchEffect(this); - } -} diff --git a/Mage/src/main/java/mage/util/ExileUtil.java b/Mage/src/main/java/mage/util/ExileUtil.java deleted file mode 100644 index 2cf1673af18..00000000000 --- a/Mage/src/main/java/mage/util/ExileUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package mage.util; - -import java.util.Set; - -import mage.cards.Card; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.cards.MeldCard; -import mage.game.Game; -import mage.game.permanent.PermanentCard; -import mage.game.permanent.PermanentMeld; - -public class ExileUtil { - public static Cards returnCardsFromExile(Set cards, Game game) { - Cards cardsToReturn = new CardsImpl(); - for (Card exiled : cards) { - if (exiled instanceof PermanentMeld) { - MeldCard meldCard = (MeldCard) ((PermanentCard) exiled).getCard(); - Card topCard = meldCard.getTopHalfCard(); - Card bottomCard = meldCard.getBottomHalfCard(); - if (topCard.getZoneChangeCounter(game) == meldCard.getTopLastZoneChangeCounter()) { - cardsToReturn.add(topCard); - } - if (bottomCard.getZoneChangeCounter(game) == meldCard.getBottomLastZoneChangeCounter()) { - cardsToReturn.add(bottomCard); - } - } else if (exiled.getZoneChangeCounter(game) == game.getState().getZoneChangeCounter(exiled.getId()) - 1) { - cardsToReturn.add(exiled); - } - } - - return cardsToReturn; - } -}