From 06eeb90b3d9cbaf02c121963f7e711fdb3a8346f Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 15 Mar 2022 18:08:36 -0400 Subject: [PATCH] replaced some more card moving method calls --- .../src/mage/cards/a/AngelOfCondemnation.java | 39 +++--- .../mage/cards/a/AshiokNightmareWeaver.java | 123 ++++++------------ Mage.Sets/src/mage/cards/b/BitterOrdeal.java | 35 +++-- Mage.Sets/src/mage/cards/b/BlizzardStrix.java | 22 ++-- Mage.Sets/src/mage/cards/c/Cannibalize.java | 79 +++++++---- .../src/mage/cards/c/ChaosHarlequin.java | 37 +++--- .../src/mage/cards/c/CharmingPrince.java | 4 +- .../mage/cards/c/CircuDimirLobotomist.java | 50 +++---- Mage.Sets/src/mage/cards/d/Deicide.java | 56 ++++---- Mage.Sets/src/mage/cards/d/DenyingWind.java | 39 +++--- ...st.java => AshiokNightmareWeaverTest.java} | 13 +- .../abilities/keyword/GravestormAbility.java | 3 +- 12 files changed, 224 insertions(+), 276 deletions(-) rename Mage.Tests/src/test/java/org/mage/test/cards/single/ths/{AshiokNightmareWaeverTest.java => AshiokNightmareWeaverTest.java} (96%) diff --git a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java index d1740013eb..37f3d1bdce 100644 --- a/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java +++ b/Mage.Sets/src/mage/cards/a/AngelOfCondemnation.java @@ -8,7 +8,6 @@ import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; import mage.abilities.costs.common.ExertSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; @@ -56,15 +55,19 @@ public final class AngelOfCondemnation extends CardImpl { this.addAbility(VigilanceAbility.getInstance()); // {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(Zone.BATTLEFIELD, new AngelOfCondemnationExileUntilEOTEffect(), new ManaCostsImpl<>("{2}{W}")); + Ability ability = new SimpleActivatedAbility( + new AngelOfCondemnationExileUntilEOTEffect(), new ManaCostsImpl<>("{2}{W}") + ); ability.addCost(new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent(filter)); this.addAbility(ability); // {2}{W}, {T}, Exert Angel of Condemnation: Exile another target creature until Angel of Condemnation leaves the battlefield. - Effect effect = new ExileUntilSourceLeavesEffect(""); - effect.setText("Exile another target creature until {this} leaves the battlefield"); - ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{2}{W}")); + ability = new SimpleActivatedAbility( + new ExileUntilSourceLeavesEffect("") + .setText("Exile another target creature until {this} leaves the battlefield"), + new ManaCostsImpl<>("{2}{W}") + ); ability.addCost(new TapSourceCost()); ability.addCost(new ExertSourceCost()); ability.addTarget(new TargetCreaturePermanent(filter)); @@ -86,10 +89,11 @@ 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"; + staticText = "exile another target creature. Return that card to the battlefield " + + "under its owner's control at the beginning of the next end step"; } - AngelOfCondemnationExileUntilEOTEffect(final AngelOfCondemnationExileUntilEOTEffect effect) { + private AngelOfCondemnationExileUntilEOTEffect(final AngelOfCondemnationExileUntilEOTEffect effect) { super(effect); } @@ -97,18 +101,17 @@ class AngelOfCondemnationExileUntilEOTEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); 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"); - effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); - game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); - return true; - } + if (controller == null || permanent == null) { + return false; } - return false; + controller.moveCards(permanent, Zone.EXILED, source, game); + //create delayed triggered ability + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility( + new ReturnToBattlefieldUnderOwnerControlTargetEffect(false, false) + .setText("return that card to the battlefield under its owner's control") + .setTargetPointer(new FixedTarget(source.getFirstTarget(), game)) + ), source); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java b/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java index 5dbeb2719a..e44f88853b 100644 --- a/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java +++ b/Mage.Sets/src/mage/cards/a/AshiokNightmareWeaver.java @@ -1,13 +1,11 @@ - package mage.cards.a; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; -import mage.abilities.costs.Cost; +import mage.abilities.costs.VariableCostImpl; import mage.abilities.costs.common.PayVariableLoyaltyCost; -import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect; import mage.cards.*; import mage.constants.*; import mage.filter.FilterCard; @@ -79,15 +77,14 @@ class AshiokNightmareWeaverExileEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && opponent != null && controller != null) { - UUID exileZone = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - if (exileZone != null) { - controller.moveCardsToExile(opponent.getLibrary().getTopCards(game, 3), source, game, true, exileZone, sourceObject.getIdName()); - return true; - } + if (opponent == null || controller == null) { + return false; } - return false; + controller.moveCardsToExile( + opponent.getLibrary().getTopCards(game, 3), source, game, true, + CardUtil.getExileZoneId(game, source), CardUtil.getSourceName(game, source) + ); + return true; } } @@ -110,65 +107,34 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject == null || controller == null) { + if (controller == null) { return false; } - int cmc = 0; - for (Cost cost : source.getCosts()) { - if (cost instanceof PayVariableLoyaltyCost) { - cmc = ((PayVariableLoyaltyCost) cost).getAmount(); - } - } + int cmc = CardUtil.castStream( + source.getCosts().stream(), PayVariableLoyaltyCost.class + ).mapToInt(VariableCostImpl::getAmount).sum(); - FilterCard filter = new FilterCreatureCard("creature card with mana value {" + cmc + "} exiled with " + sourceObject.getIdName()); + FilterCard filter = new FilterCreatureCard("creature card with mana value " + cmc); filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, cmc)); - Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter())); + Target target = new TargetCardInExile(filter, CardUtil.getExileZoneId(game, source)); - if (target.canChoose(source.getSourceId(), controller.getId(), game)) { - if (controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null - && controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { - Permanent permanent = game.getPermanent(card.getId()); - if (permanent != null) { - ContinuousEffectImpl effect = new AshiokNightmareWeaverAddTypeEffect(); - effect.setTargetPointer(new FixedTarget(permanent, game)); - game.addEffect(effect, source); - } - } - } - } - return true; - } -} - -class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl { - - public AshiokNightmareWeaverAddTypeEffect() { - super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral); - staticText = "That creature is a Nightmare in addition to its other types"; - } - - public AshiokNightmareWeaverAddTypeEffect(final AshiokNightmareWeaverAddTypeEffect effect) { - super(effect); - } - - @Override - public AshiokNightmareWeaverAddTypeEffect copy() { - return new AshiokNightmareWeaverAddTypeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (creature == null) { - this.used = true; + if (!target.canChoose(source.getSourceId(), controller.getId(), game)) { return false; } - creature.addSubType(game, SubType.NIGHTMARE); + controller.chooseTarget(Outcome.PutCreatureInPlay, target, source, game); + Card card = game.getCard(target.getFirstTarget()); + if (card == null) { + return true; + } + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + game.addEffect(new AddCardSubTypeTargetEffect( + SubType.NIGHTMARE, Duration.EndOfTurn + ).setTargetPointer(new FixedTarget(permanent, game)), source); + } return true; } } @@ -192,34 +158,23 @@ class AshiokNightmareWeaverExileAllEffect extends OneShotEffect { @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; - } - UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()); - if (exileId == null) { + if (controller == null) { return false; } + Cards cards = new CardsImpl(); for (UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); - if (opponent != null) { - Cards cards = new CardsImpl(opponent.getHand()); - for (UUID cardId : cards) { - Card card = game.getCard(cardId); - if (card != null) { - controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source, game, Zone.HAND, true); - } - } - cards.clear(); - cards.addAll(opponent.getGraveyard()); - for (UUID cardId : cards) { - Card card = game.getCard(cardId); - if (card != null) { - controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source, game, Zone.GRAVEYARD, true); - } - } + if (opponent == null) { + continue; } + cards.addAll(opponent.getHand()); + cards.addAll(opponent.getGraveyard()); } + controller.moveCardsToExile( + cards.getCards(game), source, game, true, + CardUtil.getExileZoneId(game, source), + CardUtil.getSourceName(game, source) + ); return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BitterOrdeal.java b/Mage.Sets/src/mage/cards/b/BitterOrdeal.java index 2e445d8d26..d728780daa 100644 --- a/Mage.Sets/src/mage/cards/b/BitterOrdeal.java +++ b/Mage.Sets/src/mage/cards/b/BitterOrdeal.java @@ -1,7 +1,5 @@ - package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.GravestormAbility; @@ -15,23 +13,23 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; -import mage.watchers.common.GravestormWatcher; + +import java.util.UUID; /** - * * @author emerald000 */ public final class BitterOrdeal extends CardImpl { public BitterOrdeal(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Search target player's library for a card and exile it. Then that player shuffles their library. this.getSpellAbility().addEffect(new BitterOrdealEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); - + // Gravestorm - this.addAbility(new GravestormAbility(), new GravestormWatcher()); + this.addAbility(new GravestormAbility()); } private BitterOrdeal(final BitterOrdeal card) { @@ -62,19 +60,18 @@ class BitterOrdealEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && targetPlayer != null) { - TargetCardInLibrary target = new TargetCardInLibrary(); - if (controller.searchLibrary(target, source, game, targetPlayer.getId())) { - Card card = targetPlayer.getLibrary().getCard(target.getFirstTarget(), game); - if (card != null) { - controller.moveCardToExileWithInfo(card, null, null, source, game, Zone.LIBRARY, true); - } - } - targetPlayer.shuffleLibrary(source, game); - return true; + Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (controller == null || targetPlayer == null) { + return false; } - return false; + TargetCardInLibrary target = new TargetCardInLibrary(); + controller.searchLibrary(target, source, game, targetPlayer.getId()); + Card card = targetPlayer.getLibrary().getCard(target.getFirstTarget(), game); + if (card != null) { + controller.moveCards(card, Zone.EXILED, source, game); + } + targetPlayer.shuffleLibrary(source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java index b45eaca2a0..01a422fdf7 100644 --- a/Mage.Sets/src/mage/cards/b/BlizzardStrix.java +++ b/Mage.Sets/src/mage/cards/b/BlizzardStrix.java @@ -7,7 +7,6 @@ import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbil import mage.abilities.condition.Condition; import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.keyword.FlashAbility; @@ -90,18 +89,17 @@ class BlizzardStrixEffect extends OneShotEffect { 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; - } + if (controller == null || permanent == null) { + return false; } - return false; + controller.moveCards(permanent, Zone.EXILED, source, game); + //create delayed triggered ability + 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(source.getFirstTarget(), game)) + ), source); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/c/Cannibalize.java b/Mage.Sets/src/mage/cards/c/Cannibalize.java index 60c47cc463..32a4d8eac1 100644 --- a/Mage.Sets/src/mage/cards/c/Cannibalize.java +++ b/Mage.Sets/src/mage/cards/c/Cannibalize.java @@ -1,8 +1,5 @@ - package mage.cards.c; -import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; @@ -17,8 +14,12 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCreaturePermanentSameController; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author LevelX2 */ public final class Cannibalize extends CardImpl { @@ -28,7 +29,9 @@ public final class Cannibalize extends CardImpl { // Choose two target creatures controlled by the same player. Exile one of the creatures and put two +1/+1 counters on the other. this.getSpellAbility().addEffect(new CannibalizeEffect()); - this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController(2, 2, StaticFilters.FILTER_PERMANENT_CREATURE, false)); + this.getSpellAbility().addTarget(new TargetCreaturePermanentSameController( + 2, 2, StaticFilters.FILTER_PERMANENT_CREATURE, false + )); } private Cannibalize(final Cannibalize card) { @@ -45,7 +48,8 @@ class CannibalizeEffect extends OneShotEffect { public CannibalizeEffect() { super(Outcome.Benefit); - this.staticText = "Choose two target creatures controlled by the same player. Exile one of the creatures and put two +1/+1 counters on the other"; + this.staticText = "Choose two target creatures controlled by the same player. " + + "Exile one of the creatures and put two +1/+1 counters on the other"; } public CannibalizeEffect(final CannibalizeEffect effect) { @@ -59,27 +63,48 @@ class CannibalizeEffect 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) { - boolean exileDone = false; - int count = 0; - for (UUID targetId : getTargetPointer().getTargets(game, source)) { - Permanent creature = game.getPermanent(targetId); - if (creature != null) { - if ((count == 0 && controller.chooseUse(Outcome.Exile, "Exile " + creature.getLogName() + '?', source, game)) - || (count == 1 && !exileDone)) { - controller.moveCardToExileWithInfo(creature, null, "", source, game, Zone.BATTLEFIELD, true); - exileDone = true; - } else { - creature.addCounters(CounterType.P1P1.createInstance(2), source.getControllerId(), source, game); - game.informPlayers("Added two +1/+1 counters on " + creature.getLogName()); - } - count++; - } - } - return true; + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; } - return false; + List permanents = this + .getTargetPointer() + .getTargets(game, source) + .stream() + .map(game::getPermanent) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + switch (permanents.size()) { + case 0: + return false; + case 1: + Permanent permanent = permanents.get(0); + if (player.chooseUse( + outcome, "Exile " + permanent.getIdName() + + " or put two +1/+1 counters on it?", null, + "Exile", "Add counters", source, game + )) { + player.moveCards(permanent, Zone.EXILED, source, game); + } else { + permanent.addCounters(CounterType.P1P1.createInstance(2), source, game); + } + return true; + } + Permanent permanent1 = permanents.get(0); + Permanent permanent2 = permanents.get(1); + if (player.chooseUse( + outcome, "Exile " + permanent1.getIdName() + + " or " + permanent2.getIdName() + '?', + "The other creature will get two +1/+1 counters", + "Exile " + permanent1.getIdName(), + "Exile " + permanent2.getIdName(), source, game + )) { + player.moveCards(permanent1, Zone.EXILED, source, game); + permanent2.addCounters(CounterType.P1P1.createInstance(2), source, game); + } else { + player.moveCards(permanent2, Zone.EXILED, source, game); + permanent1.addCounters(CounterType.P1P1.createInstance(2), source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java index 09751d5786..9137e0b68d 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java +++ b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java @@ -1,7 +1,5 @@ - package mage.cards.c; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -11,16 +9,13 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author L_J */ public final class ChaosHarlequin extends CardImpl { @@ -32,7 +27,7 @@ public final class ChaosHarlequin extends CardImpl { this.toughness = new MageInt(4); // {R}: Exile the top card of your library. If that card is a land card, Chaos Harlequin gets -4/-0 until end of turn. Otherwise, Chaos Harlequin gets +2/+0 until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChaosHarlequinEffect(), new ManaCostsImpl("{R}"))); + this.addAbility(new SimpleActivatedAbility(new ChaosHarlequinEffect(), new ManaCostsImpl<>("{R}"))); } private ChaosHarlequin(final ChaosHarlequin card) { @@ -49,7 +44,8 @@ class ChaosHarlequinEffect extends OneShotEffect { public ChaosHarlequinEffect() { super(Outcome.Benefit); - this.staticText = "Exile the top card of your library. If that card is a land card, {this} gets -4/-0 until end of turn. Otherwise, {this} gets +2/+0 until end of turn"; + this.staticText = "Exile the top card of your library. If that card is a land card, " + + "{this} gets -4/-0 until end of turn. Otherwise, {this} gets +2/+0 until end of turn"; } public ChaosHarlequinEffect(final ChaosHarlequinEffect effect) { @@ -64,18 +60,15 @@ class ChaosHarlequinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Card card = player.getLibrary().getFromTop(game); - if (card != null) { - player.moveCardToExileWithInfo(card, null, "", source, game, Zone.LIBRARY, true); - if (card.isLand(game)) { - game.addEffect(new BoostSourceEffect(-4, 0, Duration.EndOfTurn), source); - } else { - game.addEffect(new BoostSourceEffect(2, 0, Duration.EndOfTurn), source); - } - } - return true; + if (player == null) { + return false; } - return false; + Card card = player.getLibrary().getFromTop(game); + if (card == null) { + return false; + } + player.moveCards(card, Zone.EXILED, source, game); + game.addEffect(new BoostSourceEffect(card.isLand(game) ? -4 : 2, 0, Duration.EndOfTurn), source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CharmingPrince.java b/Mage.Sets/src/mage/cards/c/CharmingPrince.java index da9fde8577..8dbcf612dc 100644 --- a/Mage.Sets/src/mage/cards/c/CharmingPrince.java +++ b/Mage.Sets/src/mage/cards/c/CharmingPrince.java @@ -98,9 +98,7 @@ class CharmingPrinceEffect extends OneShotEffect { if (permanent == null) { return false; } - if (!controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true)) { - 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"); diff --git a/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java b/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java index b1940d5e15..c10debb4e4 100644 --- a/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java +++ b/Mage.Sets/src/mage/cards/c/CircuDimirLobotomist.java @@ -8,7 +8,6 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -17,8 +16,6 @@ import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.ExileZone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; import mage.util.CardUtil; @@ -58,7 +55,7 @@ public final class CircuDimirLobotomist extends CardImpl { this.addAbility(ability); // Your opponents can't cast nonland cards with the same name as a card exiled with Circu, Dimir Lobotomist. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CircuDimirLobotomistRuleModifyingEffect())); + this.addAbility(new SimpleStaticAbility(new CircuDimirLobotomistRuleModifyingEffect())); } private CircuDimirLobotomist(final CircuDimirLobotomist card) { @@ -91,14 +88,14 @@ class CircuDimirLobotomistEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player playerTargetLibrary = game.getPlayer(getTargetPointer().getFirst(game, source)); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (controller != null && playerTargetLibrary != null && sourcePermanent != null) { - UUID exileId = CardUtil.getCardExileZoneId(game, source); - controller.moveCardToExileWithInfo(playerTargetLibrary.getLibrary().getFromTop(game), exileId, - sourcePermanent.getIdName() + " (" + sourcePermanent.getZoneChangeCounter(game) + ')', source, game, Zone.BATTLEFIELD, true); - return true; + if (controller == null || playerTargetLibrary == null) { + return false; } - return false; + controller.moveCardsToExile( + playerTargetLibrary.getLibrary().getFromTop(game), source, game, true, + CardUtil.getCardExileZoneId(game, source), CardUtil.getSourceName(game, source) + ); + return true; } } @@ -120,28 +117,23 @@ class CircuDimirLobotomistRuleModifyingEffect extends ContinuousRuleModifyingEff @Override public String getInfoMessage(Ability source, GameEvent event, Game game) { - MageObject mageObject = game.getObject(source.getSourceId()); - if (mageObject != null) { - return "You can't cast this spell because a card with the same name is exiled by " + mageObject.getLogName() + '.'; - } - return null; + return "You can't cast this spell because a card with the same name is exiled by " + CardUtil.getSourceName(game, source) + '.'; } @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - MageObject object = game.getObject(event.getSourceId()); - if (object != null) { - ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); - if ((exileZone != null)) { - for (Card card : exileZone.getCards(game)) { - if (CardUtil.haveSameNames(card, object)) { - return true; - } - } - } - } + if (event.getType() != GameEvent.EventType.CAST_SPELL + || !game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { + return false; } - return false; + MageObject object = game.getObject(event.getSourceId()); + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); + return object != null + && exileZone != null + && !exileZone.isEmpty() + && exileZone + .getCards(game) + .stream() + .anyMatch(card -> CardUtil.haveSameNames(card, object)); } } diff --git a/Mage.Sets/src/mage/cards/d/Deicide.java b/Mage.Sets/src/mage/cards/d/Deicide.java index 9effd337a8..3a104ea027 100644 --- a/Mage.Sets/src/mage/cards/d/Deicide.java +++ b/Mage.Sets/src/mage/cards/d/Deicide.java @@ -1,7 +1,5 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect; @@ -16,17 +14,15 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetEnchantmentPermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class Deicide extends CardImpl { - - public Deicide(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}"); // Exile target enchantment. If the exiled card is a God card, search its controller's graveyard, hand, and library for any number of cards with the same name as that card and exile them, then that player shuffles their library. this.getSpellAbility().addEffect(new DeicideExileEffect()); @@ -45,32 +41,34 @@ public final class Deicide extends CardImpl { class DeicideExileEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect { - public DeicideExileEffect() { - super(true, "its controller's","any number of cards with the same name as that card"); + DeicideExileEffect() { + super(true, "its controller's", "any number of cards with the same name as that card"); } - public DeicideExileEffect(final DeicideExileEffect effect) { + private DeicideExileEffect(final DeicideExileEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Card sourceCard = game.getCard(source.getSourceId()); - if (controller != null && sourceCard != null) { - Permanent targetEnchantment = game.getPermanent(getTargetPointer().getFirst(game, source)); - if (targetEnchantment != null) { - controller.moveCardToExileWithInfo(targetEnchantment, null, "", source, game, Zone.BATTLEFIELD, true); - // 4/26/2014 - // Deicide looks at the card in exile, not the permanent that was exiled, to determine - // if it is a God. For each of the Gods in the Theros block, it won't matter what your - // devotion to its color(s) was. The card is a God card when not on the battlefield. - Card cardInExile = game.getExile().getCard(targetEnchantment.getId(), game); - if (cardInExile != null && cardInExile.hasSubtype(SubType.GOD, game)) { - Player enchantmentController = game.getPlayer(targetEnchantment.getControllerId()); - return enchantmentController != null && super.applySearchAndExile(game, source, cardInExile.getName(), enchantmentController.getId()); - } - } + if (controller == null || sourceCard == null) { + return false; + } + Permanent targetEnchantment = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (targetEnchantment == null) { + return false; + } + controller.moveCards(targetEnchantment, Zone.EXILED, source, game); + // 4/26/2014 + // Deicide looks at the card in exile, not the permanent that was exiled, to determine + // if it is a God. For each of the Gods in the Theros block, it won't matter what your + // devotion to its color(s) was. The card is a God card when not on the battlefield. + Card cardInExile = game.getExile().getCard(targetEnchantment.getId(), game); + if (cardInExile != null && cardInExile.hasSubtype(SubType.GOD, game)) { + Player enchantmentController = game.getPlayer(targetEnchantment.getControllerId()); + return enchantmentController != null && super.applySearchAndExile(game, source, cardInExile.getName(), enchantmentController.getId()); } return false; } @@ -82,10 +80,6 @@ class DeicideExileEffect extends SearchTargetGraveyardHandLibraryForCardNameAndE @Override public String getText(Mode mode) { - StringBuilder sb = new StringBuilder(); - sb.append("Exile target enchantment. If the exiled card is a God card, "); - sb.append(super.getText(mode)); - return sb.toString(); + return "Exile target enchantment. If the exiled card is a God card, " + super.getText(mode); } - -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/d/DenyingWind.java b/Mage.Sets/src/mage/cards/d/DenyingWind.java index aa69afb4ac..398220fa45 100644 --- a/Mage.Sets/src/mage/cards/d/DenyingWind.java +++ b/Mage.Sets/src/mage/cards/d/DenyingWind.java @@ -1,30 +1,29 @@ - package mage.cards.d; -import java.util.List; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetCardInLibrary; +import java.util.UUID; + /** - * * @author fireshoes */ public final class DenyingWind extends CardImpl { public DenyingWind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{7}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{7}{U}{U}"); // Search target player's library for up to seven cards and exile them. Then that player shuffles their library. getSpellAbility().addEffect(new DenyingWindEffect()); @@ -61,20 +60,18 @@ class DenyingWindEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && player != null) { - TargetCardInLibrary target = new TargetCardInLibrary(0, 7, new FilterCard("cards from player's library to exile")); - if (controller.searchLibrary(target, source, game, player.getId())) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = player.getLibrary().remove(targetId, game); - if (card != null) { - controller.moveCardToExileWithInfo(card, null, null, source, game, Zone.LIBRARY, true); - } - } - } - player.shuffleLibrary(source, game); - return true; + if (controller == null || player == null) { + return false; } - return false; + TargetCardInLibrary target = new TargetCardInLibrary(7, StaticFilters.FILTER_CARD); + controller.searchLibrary(target, source, game, player.getId()); + Cards cards = new CardsImpl(); + target.getTargets() + .stream() + .map(uuid -> player.getLibrary().getCard(uuid, game)) + .forEach(cards::add); + controller.moveCards(cards, Zone.EXILED, source, game); + player.shuffleLibrary(source, game); + return true; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWaeverTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWeaverTest.java similarity index 96% rename from Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWaeverTest.java rename to Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWeaverTest.java index 4ad535a830..5b810af0a2 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWaeverTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/ths/AshiokNightmareWeaverTest.java @@ -1,5 +1,3 @@ - - package org.mage.test.cards.single.ths; import mage.constants.PhaseStep; @@ -9,15 +7,14 @@ import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; /** - * * @author LevelX2 */ -public class AshiokNightmareWaeverTest extends CardTestPlayerBase { +public class AshiokNightmareWeaverTest extends CardTestPlayerBase { /** * Ashiok, Nightmare Weaver {1}{U}{B} - 3 - * + *

* +2: Exile the top three cards of target opponent's library. * -X: Put a creature card with converted mana cost X exiled with Ashiok, Nightmare Weaver onto the battlefield under your control. That creature is a Nightmare in addition to its other types. * -10: Exile all cards from all opponents' hands and graveyards.);Tests Heliod get a God with devotion to white >>= 5 @@ -55,9 +52,9 @@ public class AshiokNightmareWaeverTest extends CardTestPlayerBase { setChoice(playerA, "X=5"); addTarget(playerA, "Prophet of Kruphix"); - + castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - + setStopAt(4, PhaseStep.PRECOMBAT_MAIN); execute(); @@ -70,4 +67,4 @@ public class AshiokNightmareWaeverTest extends CardTestPlayerBase { assertTapped("Mountain", false); // Must be untapped because of Prophet of Kruphix } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java b/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java index f4f36701ff..98dd328ded 100644 --- a/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/GravestormAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.keyword; import mage.MageObjectReference; @@ -10,7 +9,6 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.watchers.common.GravestormWatcher; @@ -22,6 +20,7 @@ public class GravestormAbility extends TriggeredAbilityImpl { public GravestormAbility() { super(Zone.STACK, new GravestormEffect()); + this.addWatcher(new GravestormWatcher()); } private GravestormAbility(final GravestormAbility ability) {