From dcd3e7c0395b12dc11cd41bf58785fa06f640ad9 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 8 May 2018 23:46:34 +0200 Subject: [PATCH] * Some more fixed/reworked card movement handling. --- Mage.Client/serverlist.txt | 1 - .../mage/cards/a/ApproachOfTheSecondSun.java | 24 +-------- Mage.Sets/src/mage/cards/c/Chronostutter.java | 26 +++------ Mage.Sets/src/mage/cards/c/CommitMemory.java | 44 +++------------ .../src/mage/cards/c/CreamOfTheCrop.java | 22 ++++---- Mage.Sets/src/mage/cards/c/CruelFate.java | 45 +++++----------- Mage.Sets/src/mage/cards/d/DarkBargain.java | 9 +--- Mage.Sets/src/mage/cards/d/DarkConfidant.java | 6 +-- Mage.Sets/src/mage/cards/d/DarkTutelage.java | 25 ++++----- .../src/mage/cards/d/DemonlordBelzenlok.java | 12 ++--- .../src/mage/cards/d/DeployTheGatewatch.java | 19 ++----- .../src/mage/cards/d/DestroyTheEvidence.java | 19 +++---- Mage.Sets/src/mage/cards/d/DimirCharm.java | 42 +++++++-------- .../src/mage/cards/d/DimirMachinations.java | 53 ++++++------------- .../cards/d/DivergentTransformations.java | 27 ++++------ .../src/mage/cards/d/DuskmantleSeer.java | 10 ++-- .../src/mage/cards/e/ElementalAugury.java | 13 ++--- Mage.Sets/src/mage/cards/e/ElkinBottle.java | 23 +++----- Mage.Sets/src/mage/cards/e/EnigmaSphinx.java | 25 +++------ .../src/mage/cards/e/ErraticExplosion.java | 16 ++---- .../src/mage/cards/e/ErraticMutation.java | 12 ++--- .../src/mage/cards/e/ExplosiveRevelation.java | 32 ++++++----- Mage.Sets/src/mage/cards/e/EyeOfYawgmoth.java | 20 ++----- .../src/mage/cards/f/FlamesOfRemembrance.java | 52 ++++++------------ Mage.Sets/src/mage/cards/l/LongTermPlans.java | 2 +- .../src/mage/cards/o/OrochiSustainer.java | 5 +- .../mage/cards/t/TeferiHeroOfDominaria.java | 13 +---- .../java/org/mage/test/player/TestPlayer.java | 5 ++ .../java/org/mage/test/stub/PlayerStub.java | 5 ++ Mage/src/main/java/mage/players/Library.java | 31 ++++------- Mage/src/main/java/mage/players/Player.java | 11 ++++ .../main/java/mage/players/PlayerImpl.java | 22 ++++++++ Mage/src/main/java/mage/util/CardUtil.java | 10 ++++ Utils/gen-list-unimplemented-cards-for-set.pl | 8 +-- 34 files changed, 253 insertions(+), 436 deletions(-) diff --git a/Mage.Client/serverlist.txt b/Mage.Client/serverlist.txt index fdceb7823d..caecdb8ac0 100644 --- a/Mage.Client/serverlist.txt +++ b/Mage.Client/serverlist.txt @@ -1,6 +1,5 @@ XMage.de 1 (Europe/Germany) fast :xmage.de:17171 old xmage.de (Europe/Germany) :185.3.232.200:17171 -xmage.us (North America/USA) :xmage.us:17171 XMage Players MTG:xmageplayersmtg.ddns.net:17171 XMage.tahiti :xmage.tahiti.one:443 Seedds Server (Asia) :115.29.203.80:17171 diff --git a/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java index f87cfd3a35..b8d7e21fac 100644 --- a/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java +++ b/Mage.Sets/src/mage/cards/a/ApproachOfTheSecondSun.java @@ -79,29 +79,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect { } Card spellCard = game.getStack().getSpell(source.getSourceId()).getCard(); if (spellCard != null) { - List top6 = new ArrayList<>(); - // Cut the top 6 cards off into a temporary array - for (int i = 0; i < 6 && controller.getLibrary().hasCards(); ++i) { - top6.add(controller.getLibrary().removeFromTop(game)); - } - - // Is the library now empty, thus the rise is on the bottom (for the message to the players)? - boolean isOnBottom = controller.getLibrary().size() < 6; - // Put this card (if the ability came from an ApproachOfTheSecondSun spell card) on top - spellCard.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - - // put the top 6 we took earlier back on top (going in reverse order this time to get them back - // on top in the proper order) - for (int i = top6.size() - 1; i >= 0; --i) { - controller.getLibrary().putOnTop(top6.get(i), game); - } - - // Inform the players - if (isOnBottom) { - game.informPlayers(controller.getLogName() + " puts " + spell.getLogName() + " on the bottom of their library."); - } else { - game.informPlayers(controller.getLogName() + " puts " + spell.getLogName() + " into their library 7th from the top."); - } + controller.putCardOnTopXOfLibrary(spellCard, game, source, 7); } } return true; diff --git a/Mage.Sets/src/mage/cards/c/Chronostutter.java b/Mage.Sets/src/mage/cards/c/Chronostutter.java index 2bd233048b..7a3499c45f 100644 --- a/Mage.Sets/src/mage/cards/c/Chronostutter.java +++ b/Mage.Sets/src/mage/cards/c/Chronostutter.java @@ -30,12 +30,10 @@ package mage.cards.c; 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.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -48,8 +46,7 @@ import mage.target.common.TargetCreaturePermanent; public class Chronostutter extends CardImpl { public Chronostutter(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{U}"); // Put target creature into its owner's library second from the top. this.getSpellAbility().addEffect(new ChronostutterEffect()); @@ -85,22 +82,11 @@ class ChronostutterEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - Player owner = game.getPlayer(permanent.getOwnerId()); - Player controller = game.getPlayer(permanent.getControllerId()); - if (owner == null || controller == null) { - return false; - } - - Card card = null; - if (owner.getLibrary().hasCards()) { - card = owner.getLibrary().removeFromTop(game); - } - - permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - if (card != null) { - owner.getLibrary().putOnTop(card, game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + controller.putCardOnTopXOfLibrary(permanent, game, source, 2); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CommitMemory.java b/Mage.Sets/src/mage/cards/c/CommitMemory.java index 5ec8544777..88a3bfed1d 100644 --- a/Mage.Sets/src/mage/cards/c/CommitMemory.java +++ b/Mage.Sets/src/mage/cards/c/CommitMemory.java @@ -33,7 +33,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.keyword.AftermathAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.SplitCard; @@ -107,43 +106,16 @@ class CommitEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent != null) { - Player owner = game.getPlayer(permanent.getOwnerId()); - Player controller = game.getPlayer(permanent.getControllerId()); - if (owner == null || controller == null) { - return false; + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + return controller.putCardOnTopXOfLibrary(permanent, game, source, 2); } - - Card card = null; - if (owner.getLibrary().hasCards()) { - card = owner.getLibrary().removeFromTop(game); + Spell spell = game.getStack().getSpell(source.getFirstTarget()); + if (spell != null) { + return controller.putCardOnTopXOfLibrary(spell, game, source, 2); } - - permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - if (card != null) { - owner.getLibrary().putOnTop(card, game); - } - return true; - } - Spell spell = game.getStack().getSpell(source.getFirstTarget()); - if (spell != null) { - Player owner = game.getPlayer(spell.getOwnerId()); - Player controller = game.getPlayer(spell.getControllerId()); - if (owner == null || controller == null) { - return false; - } - - Card card = null; - if (owner.getLibrary().hasCards()) { - card = owner.getLibrary().removeFromTop(game); - } - - spell.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - if (card != null) { - owner.getLibrary().putOnTop(card, game); - } - return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java b/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java index 2815122878..3d94b9d83f 100644 --- a/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java +++ b/Mage.Sets/src/mage/cards/c/CreamOfTheCrop.java @@ -89,21 +89,19 @@ class CreamOfTheCropEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); + Player controller = game.getPlayer(source.getControllerId()); Permanent permanent = ((FixedTarget) getTargetPointer()).getTargetedPermanentOrLKIBattlefield(game); - if (player != null && permanent != null) { - int numLooked = Math.min(permanent.getPower().getValue(), player.getLibrary().size()); - if (numLooked > 0) { - Cards cards = new CardsImpl(); - for (int i = 0; i < numLooked; i++) { - cards.add(player.getLibrary().removeFromTop(game)); - } + if (controller != null && permanent != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, permanent.getPower().getValue())); + if (!cards.isEmpty()) { TargetCard target = new TargetCardInHand(new FilterCard("card to put on top of your library")); - player.choose(Outcome.Benefit, cards, target, game); + controller.choose(Outcome.Benefit, cards, target, game); Card card = cards.get(target.getFirstTarget(), game); - cards.remove(card); - player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); - player.putCardsOnBottomOfLibrary(cards, game, source, true); + if (card != null) { + cards.remove(card); + controller.putCardsOnTopOfLibrary(new CardsImpl(card), game, source, true); + } + controller.putCardsOnBottomOfLibrary(cards, game, source, true); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/CruelFate.java b/Mage.Sets/src/mage/cards/c/CruelFate.java index 8863d25bea..8fab4b1f99 100644 --- a/Mage.Sets/src/mage/cards/c/CruelFate.java +++ b/Mage.Sets/src/mage/cards/c/CruelFate.java @@ -89,51 +89,30 @@ class CruelFateEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Card sourceCard = game.getCard(source.getSourceId()); if (sourceCard != null) { - Player you = game.getPlayer(source.getControllerId()); - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null && you != null) { - Cards cards = new CardsImpl(); - int count = Math.min(player.getLibrary().size(), 5); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - - you.lookAtCards(sourceCard.getIdName(), cards, game); + Player controller = game.getPlayer(source.getControllerId()); + Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetOpponent != null && controller != null) { + Cards cards = new CardsImpl(targetOpponent.getLibrary().getTopCards(game, 5)); + controller.lookAtCards(source, null, cards, game); // card to put into opponent's graveyard TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into target opponent's graveyard")); - if (player.canRespond()) { + if (targetOpponent.isInGame()) { if (cards.size() > 1) { - you.choose(Outcome.Detriment, cards, target, game); + controller.choose(Outcome.Detriment, cards, target, game); Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); + controller.moveCards(card, Zone.GRAVEYARD, source, game); } - } - else if (cards.size() == 1) { + } else if (cards.size() == 1) { Card card = cards.get(cards.iterator().next(), game); + controller.moveCards(card, Zone.GRAVEYARD, source, game); card.moveToZone(Zone.GRAVEYARD, source.getSourceId(), game, true); + cards.clear(); } } - // cards to put on the top of opponent's library - TargetCard target2 = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on the top of target opponent's library")); - while (player.canRespond() && cards.size() > 1) { - you.choose(Outcome.Neutral, cards, target2, game); - Card card = cards.get(target2.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } - target2.clearChosen(); - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - } + controller.putCardsOnTopOfLibrary(cards, game, source, true); return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DarkBargain.java b/Mage.Sets/src/mage/cards/d/DarkBargain.java index c649310409..1dd99d314c 100644 --- a/Mage.Sets/src/mage/cards/d/DarkBargain.java +++ b/Mage.Sets/src/mage/cards/d/DarkBargain.java @@ -87,14 +87,7 @@ class DarkBargainEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); MageObject sourceOject = source.getSourceObject(game); if (player != null && sourceOject != null) { - Cards cards = new CardsImpl(); - int cardsCount = Math.min(3, player.getLibrary().size()); - for (int i = 0; i < cardsCount; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3)); if (!cards.isEmpty()) { Cards cardsToHand = new CardsImpl(); player.lookAtCards(sourceOject.getIdName(), cards, game); diff --git a/Mage.Sets/src/mage/cards/d/DarkConfidant.java b/Mage.Sets/src/mage/cards/d/DarkConfidant.java index bca6a50257..2dc4d58361 100644 --- a/Mage.Sets/src/mage/cards/d/DarkConfidant.java +++ b/Mage.Sets/src/mage/cards/d/DarkConfidant.java @@ -34,8 +34,8 @@ import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; @@ -49,7 +49,7 @@ import mage.players.Player; public class DarkConfidant extends CardImpl { public DarkConfidant(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -87,7 +87,7 @@ class DarkConfidantEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) { if (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + Card card = controller.getLibrary().getFromTop(game); if (card != null) { Cards cards = new CardsImpl(card); controller.revealCards(sourcePermanent.getIdName(), cards, game); diff --git a/Mage.Sets/src/mage/cards/d/DarkTutelage.java b/Mage.Sets/src/mage/cards/d/DarkTutelage.java index 150301fdc2..3895e610a7 100644 --- a/Mage.Sets/src/mage/cards/d/DarkTutelage.java +++ b/Mage.Sets/src/mage/cards/d/DarkTutelage.java @@ -1,16 +1,16 @@ /* * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR @@ -20,12 +20,11 @@ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those of the * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.d; import java.util.UUID; @@ -47,7 +46,7 @@ import mage.players.Player; public class DarkTutelage extends CardImpl { public DarkTutelage(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new DarkTutelageEffect(), false)); } @@ -75,15 +74,13 @@ class DarkTutelageEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null && player.getLibrary().hasCards()) { - Card card = player.getLibrary().removeFromTop(game); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { + controller.revealCards(source, new CardsImpl(card), game); card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - player.loseLife(card.getConvertedManaCost(), game, false); - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards("Dark Tutelage", cards, game); + controller.loseLife(card.getConvertedManaCost(), game, false); return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DemonlordBelzenlok.java b/Mage.Sets/src/mage/cards/d/DemonlordBelzenlok.java index cac0c1d439..0e5273b82d 100644 --- a/Mage.Sets/src/mage/cards/d/DemonlordBelzenlok.java +++ b/Mage.Sets/src/mage/cards/d/DemonlordBelzenlok.java @@ -32,8 +32,6 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.constants.SubType; -import mage.constants.SuperType; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.TrampleAbility; import mage.cards.Card; @@ -41,6 +39,8 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.SuperType; import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; @@ -103,15 +103,15 @@ class DemonlordBelzenlokEffect extends OneShotEffect { } boolean cont = true; int addedToHand = 0; - while (controller.getLibrary().hasCards() && controller.canRespond() && cont) { - Card card = controller.getLibrary().removeFromTop(game); + while (controller.getLibrary().hasCards() && cont) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { - controller.moveCardToExileWithInfo(card, null, null, source.getSourceId(), game, Zone.LIBRARY, true); + controller.moveCards(card, Zone.EXILED, source, game); if (!card.isLand()) { if (card.getConvertedManaCost() < 4) { cont = false; } - card.moveToZone(Zone.HAND, source.getSourceId(), game, true); + controller.moveCards(card, Zone.HAND, source, game); addedToHand++; } } diff --git a/Mage.Sets/src/mage/cards/d/DeployTheGatewatch.java b/Mage.Sets/src/mage/cards/d/DeployTheGatewatch.java index e056e3cf2e..00080266e2 100644 --- a/Mage.Sets/src/mage/cards/d/DeployTheGatewatch.java +++ b/Mage.Sets/src/mage/cards/d/DeployTheGatewatch.java @@ -89,27 +89,15 @@ class DeployTheGatewatchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); if (controller == null) { return false; } // Look at the top seven cards of your library. - Cards cards = new CardsImpl(); - boolean planeswalkerIncluded = false; - for (int i = 0; i < 7; i++) { - Card card = controller.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - if (filter.match(card, game)) { - planeswalkerIncluded = true; - } - } - } - controller.lookAtCards("Deploy the Gatewatch", cards, game); - + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 7)); + controller.lookAtCards(source, null, cards, game); // Put up to two planeswalker cards from among them onto the battlefield. - if (planeswalkerIncluded) { + if (cards.count(filter, game) > 0) { TargetCard target = new TargetCard(0, 2, Zone.LIBRARY, filter); if (controller.choose(Outcome.DrawCard, cards, target, game)) { Cards pickedCards = new CardsImpl(target.getTargets()); @@ -117,7 +105,6 @@ class DeployTheGatewatchEffect extends OneShotEffect { controller.moveCards(pickedCards.getCards(game), Zone.BATTLEFIELD, source, game); } } - // Put the rest on the bottom of your library in a random order controller.putCardsOnBottomOfLibrary(cards, game, source, false); return true; diff --git a/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java b/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java index 50e5e2998c..52f9cb912f 100644 --- a/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java +++ b/Mage.Sets/src/mage/cards/d/DestroyTheEvidence.java @@ -28,7 +28,6 @@ package mage.cards.d; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyTargetEffect; @@ -48,7 +47,7 @@ import mage.target.common.TargetLandPermanent; public class DestroyTheEvidence extends CardImpl { public DestroyTheEvidence(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{B}"); // Destroy target land. Its controller reveals cards from the top of his // or her library until he or she reveals a land card, then puts those cards into their graveyard. @@ -87,27 +86,21 @@ class DestroyTheEvidenceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Permanent landPermanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject != null && landPermanent != null) { + if (landPermanent != null) { Player player = game.getPlayer(landPermanent.getControllerId()); if (player == null) { return false; } - boolean landFound = false; - Cards cards = new CardsImpl(); - while (player.getLibrary().hasCards() && !landFound) { - if (!player.canRespond()) { - return false; - } - Card card = player.getLibrary().removeFromTop(game); + Cards cards = new CardsImpl(); + for (Card card : player.getLibrary().getCards(game)) { if (card != null) { cards.add(card); if (card.isLand()) { - landFound = true; + break; } } } - player.revealCards(sourceObject.getName(), cards, game, true); + player.revealCards(source, cards, game); player.moveCards(cards, Zone.GRAVEYARD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/d/DimirCharm.java b/Mage.Sets/src/mage/cards/d/DimirCharm.java index 9e7f3a91e0..5168958ec1 100644 --- a/Mage.Sets/src/mage/cards/d/DimirCharm.java +++ b/Mage.Sets/src/mage/cards/d/DimirCharm.java @@ -55,18 +55,17 @@ import mage.target.common.TargetCreaturePermanent; * @author Plopman */ public class DimirCharm extends CardImpl { - + private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("creature with power 2 or less"); private static final FilterSpell filterSorcery = new FilterSpell("sorcery spell"); - + static { filterCreature.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3)); filterSorcery.add(new CardTypePredicate(CardType.SORCERY)); } - public DimirCharm (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{U}{B}"); - + public DimirCharm(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U}{B}"); //Choose one - Counter target sorcery spell this.getSpellAbility().addEffect(new CounterTargetEffect()); @@ -90,47 +89,42 @@ public class DimirCharm extends CardImpl { } @Override - public DimirCharm copy() { + public DimirCharm copy() { return new DimirCharm(this); } } class DimirCharmEffect extends OneShotEffect { + public DimirCharmEffect() { - super(Outcome.Benefit); + super(Outcome.Benefit); } public DimirCharmEffect(final DimirCharmEffect effect) { super(effect); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if(controller != null && player != null){ - Cards cards = new CardsImpl(); - for(int i = 0; i < 3; i++){ - Card card = player.getLibrary().removeFromTop(game); - if(card != null){ - cards.add(card); - } - } - if(!cards.isEmpty()){ + if (controller != null && player != null) { + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3)); + if (!cards.isEmpty()) { TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("Card to put back on top of library")); - if(controller.chooseTarget(Outcome.Benefit, cards, target, source, game)){ + if (controller.chooseTarget(Outcome.Benefit, cards, target, source, game)) { Card card = cards.get(target.getFirstTarget(), game); - if(card != null){ - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + if (card != null) { cards.remove(card); } - controller.moveCards(cards, Zone.GRAVEYARD, source, game); } + controller.moveCards(cards, Zone.GRAVEYARD, source, game); } + return true; } return false; } - + @Override public DimirCharmEffect copy() { return new DimirCharmEffect(this); @@ -139,5 +133,5 @@ class DimirCharmEffect extends OneShotEffect { @Override public String getText(Mode mode) { return "look at the top three cards of target player's library, then put one back and the rest into that player's graveyard"; - } + } } diff --git a/Mage.Sets/src/mage/cards/d/DimirMachinations.java b/Mage.Sets/src/mage/cards/d/DimirMachinations.java index 7493efb190..54aa74a23f 100644 --- a/Mage.Sets/src/mage/cards/d/DimirMachinations.java +++ b/Mage.Sets/src/mage/cards/d/DimirMachinations.java @@ -31,9 +31,9 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TransmuteAbility; -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; @@ -51,15 +51,15 @@ import mage.target.TargetPlayer; public class DimirMachinations extends CardImpl { public DimirMachinations(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Look at the top three cards of target player's library. Exile any number of those cards, then put the rest back in any order. this.getSpellAbility().addEffect(new DimirMachinationsEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); - + // Transmute {1}{B}{B} this.addAbility(new TransmuteAbility("{1}{B}{B}")); - + } public DimirMachinations(final DimirMachinations card) { @@ -73,57 +73,36 @@ public class DimirMachinations extends CardImpl { } class DimirMachinationsEffect extends OneShotEffect { - + DimirMachinationsEffect() { super(Outcome.Neutral); this.staticText = "Look at the top three cards of target player's library. Exile any number of those cards, then put the rest back in any order"; } - + DimirMachinationsEffect(final DimirMachinationsEffect effect) { super(effect); } - + @Override public DimirMachinationsEffect copy() { return new DimirMachinationsEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); if (controller != null && targetPlayer != null) { - int numCardsToLookAt = Math.min(3, targetPlayer.getLibrary().size()); - if (numCardsToLookAt > 0) { - CardsImpl cards = new CardsImpl(); - for (int i = 0; i < numCardsToLookAt; i++) { - cards.add(targetPlayer.getLibrary().removeFromTop(game)); - } - TargetCard targetExile = new TargetCard(0, numCardsToLookAt, Zone.LIBRARY, new FilterCard("card to exile")); + CardsImpl cards = new CardsImpl(targetPlayer.getLibrary().getTopCards(game, 3)); + if (!cards.isEmpty()) { + controller.lookAtCards(source, null, cards, game); + TargetCard targetExile = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, new FilterCard("cards to exile")); if (controller.choose(Outcome.Exile, cards, targetExile, game)) { - for (UUID cardId : targetExile.getTargets()) { - Card card = cards.get(cardId, game); - if (card != null) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); - cards.remove(card); - } - } - while (!cards.isEmpty()) { - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); - cards.remove(card); - } - else { - TargetCard targetTop = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on top of library")); - if (controller.choose(Outcome.Neutral, cards, targetTop, game)) { - Card card = cards.get(targetTop.getFirstTarget(), game); - controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); - cards.remove(card); - } - } - } + Cards toExile = new CardsImpl(targetExile.getTargets()); + controller.moveCards(toExile, Zone.EXILED, source, game); + cards.removeAll(toExile); } + controller.putCardsOnTopOfLibrary(cards, game, source, true); } return true; } diff --git a/Mage.Sets/src/mage/cards/d/DivergentTransformations.java b/Mage.Sets/src/mage/cards/d/DivergentTransformations.java index 7815acb1ee..6c8f3a1207 100644 --- a/Mage.Sets/src/mage/cards/d/DivergentTransformations.java +++ b/Mage.Sets/src/mage/cards/d/DivergentTransformations.java @@ -105,23 +105,18 @@ class DivergentTransformationsEffect extends OneShotEffect { Player player = game.getPlayer(playerId); if (player != null) { if (player.getLibrary().hasCards()) { - Cards cards = new CardsImpl(); - Card card = player.getLibrary().removeFromTop(game); - cards.add(card); - while (!card.isCreature() && player.getLibrary().hasCards()) { - card = player.getLibrary().removeFromTop(game); - cards.add(card); + Cards toReveal = new CardsImpl(); + for (Card card : player.getLibrary().getCards(game)) { + toReveal.add(card); + if (card.isCreature()) { + player.revealCards(source, toReveal, game); + player.moveCards(card, Zone.BATTLEFIELD, source, game); + toReveal.remove(card); + break; + } } - - if (card.isCreature()) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); - } - - if (!cards.isEmpty()) { - player.revealCards(sourceObject.getIdName(), cards, game); - Set cardsToShuffle = cards.getCards(game); - cardsToShuffle.remove(card); - player.getLibrary().addAll(cardsToShuffle, game); + if (!toReveal.isEmpty()) { + player.shuffleLibrary(source, game); } } } diff --git a/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java b/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java index 7a3e93f5d2..7fbfd9c5e5 100644 --- a/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java +++ b/Mage.Sets/src/mage/cards/d/DuskmantleSeer.java @@ -35,8 +35,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.TargetController; import mage.constants.Zone; import mage.game.Game; @@ -98,13 +98,11 @@ class DuskmantleSeerEffect extends OneShotEffect { } for (Player player : game.getPlayers().values()) { if (player.getLibrary().hasCards()) { - Card card = player.getLibrary().removeFromTop(game); + Card card = player.getLibrary().getFromTop(game); if (card != null) { - Cards cards = new CardsImpl(); - cards.add(card); - player.revealCards(sourceCard.getName() + ": Revealed by " + player.getName(), cards, game); + player.revealCards(source, ": Revealed by " + player.getName(), new CardsImpl(card), game); player.loseLife(card.getConvertedManaCost(), game, false); - card.moveToZone(Zone.HAND, source.getSourceId(), game, true); + player.moveCards(card, Zone.HAND, source, game); } } } diff --git a/Mage.Sets/src/mage/cards/e/ElementalAugury.java b/Mage.Sets/src/mage/cards/e/ElementalAugury.java index 0562975ea0..278dd06c11 100644 --- a/Mage.Sets/src/mage/cards/e/ElementalAugury.java +++ b/Mage.Sets/src/mage/cards/e/ElementalAugury.java @@ -47,7 +47,7 @@ import mage.target.TargetPlayer; public class ElementalAugury extends CardImpl { public ElementalAugury(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{U}{B}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{B}{R}"); // {3}: Look at the top three cards of target player's library, then put them back in any order. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElementalAuguryEffect(), new ManaCostsImpl("3")); @@ -89,15 +89,8 @@ class ElementalAuguryEffect extends OneShotEffect { || controller == null) { return false; } - Cards cards = new CardsImpl(); - int count = Math.min(targetPlayer.getLibrary().size(), 3); - for (int i = 0; i < count; i++) { - Card card = targetPlayer.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - controller.lookAtCards("Elemental Augury", cards, game); + Cards cards = new CardsImpl(targetPlayer.getLibrary().getTopCards(game, 3)); + controller.lookAtCards(source, null, cards, game); controller.putCardsOnTopOfLibrary(cards, game, source, true); return true; } diff --git a/Mage.Sets/src/mage/cards/e/ElkinBottle.java b/Mage.Sets/src/mage/cards/e/ElkinBottle.java index 7fa8d73a16..ee8b719cf9 100644 --- a/Mage.Sets/src/mage/cards/e/ElkinBottle.java +++ b/Mage.Sets/src/mage/cards/e/ElkinBottle.java @@ -40,13 +40,9 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.game.turn.Step; -import mage.players.Library; import mage.players.Player; import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; /** * @@ -55,7 +51,7 @@ import mage.target.targetpointer.FixedTarget; public class ElkinBottle extends CardImpl { public ElkinBottle(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); // {3}, {tap}, Exile the top card of your library. Until the beginning of your next upkeep, you may play that card. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElkinBottleExileEffect(), new GenericManaCost(3)); @@ -92,13 +88,10 @@ class ElkinBottleExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (sourcePermanent != null && controller != null && controller.getLibrary().hasCards()) { - Library library = controller.getLibrary(); - Card card = library.removeFromTop(game); + if (controller != null) { + Card card = controller.getLibrary().getFromTop(game); if (card != null) { - String exileName = new StringBuilder(sourcePermanent.getIdName()).append(" ").toString(); - controller.moveCardToExileWithInfo(card, source.getSourceId(), exileName, source.getSourceId(), game, Zone.LIBRARY, true); + controller.moveCardsToExile(card, source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, null)); ContinuousEffect effect = new ElkinBottleCastFromExileEffect(); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); @@ -110,14 +103,14 @@ class ElkinBottleExileEffect extends OneShotEffect { } class ElkinBottleCastFromExileEffect extends AsThoughEffectImpl { - + private boolean sameStep = true; public ElkinBottleCastFromExileEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit); this.staticText = "Until the beginning of your next upkeep, you may play that card."; } - + public ElkinBottleCastFromExileEffect(final ElkinBottleCastFromExileEffect effect) { super(effect); } @@ -149,5 +142,5 @@ class ElkinBottleCastFromExileEffect extends AsThoughEffectImpl { return source.getControllerId().equals(affectedControllerId) && sourceId.equals(getTargetPointer().getFirst(game, source)); } - + } diff --git a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java index 76c1ed4567..d693e7b5a6 100644 --- a/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java +++ b/Mage.Sets/src/mage/cards/e/EnigmaSphinx.java @@ -47,7 +47,6 @@ import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; -import mage.players.Library; import mage.players.Player; /** @@ -147,22 +146,14 @@ class EnigmaSphinxEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(source.getSourceId()); - if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { - Player owner = game.getPlayer(card.getOwnerId()); - if (owner != null && card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true)) { - // Move Sphinx to third position - game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top"); - Library lib = owner.getLibrary(); - if (lib != null) { - Card card1 = lib.removeFromTop(game); - if (card1 != null && card1.getId().equals(source.getSourceId())) { - lib.putCardThirdFromTheTop(card1, game); - return true; - } - } - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; } - return false; + Card card = (Card) source.getSourceObjectIfItStillExists(game); + if (card != null) { + controller.putCardOnTopXOfLibrary(card, game, source, 3); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/e/ErraticExplosion.java b/Mage.Sets/src/mage/cards/e/ErraticExplosion.java index 97189b3d0f..f2a2f8afd9 100644 --- a/Mage.Sets/src/mage/cards/e/ErraticExplosion.java +++ b/Mage.Sets/src/mage/cards/e/ErraticExplosion.java @@ -28,7 +28,6 @@ package mage.cards.e; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -51,7 +50,7 @@ public class ErraticExplosion extends CardImpl { public ErraticExplosion(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); - // Choose any target. Reveal cards from the top of your library until you reveal a nonland card. Erratic Explosion deals damage equal to that card's converted mana cost to that creature or player. Put the revealed cards on the bottom of your library in any order. + // Choose any target. Reveal cards from the top of your library until you reveal a nonland card. Erratic Explosion deals damage equal to that card's converted mana cost to that permanent or player. Put the revealed cards on the bottom of your library in any order. this.getSpellAbility().addTarget(new TargetAnyTarget()); this.getSpellAbility().addEffect(new ErraticExplosionEffect()); } @@ -85,22 +84,17 @@ class ErraticExplosionEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null && sourceObject != null) { + if (controller != null) { CardsImpl toReveal = new CardsImpl(); Card nonLandCard = null; - - while (nonLandCard == null && controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { toReveal.add(card); if (!card.isLand()) { nonLandCard = card; + break; } } - // reveal cards - if (!toReveal.isEmpty()) { - controller.revealCards(sourceObject.getIdName(), toReveal, game); - } + controller.revealCards(source, toReveal, game); // the nonland card if (nonLandCard != null) { Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(game, source)); diff --git a/Mage.Sets/src/mage/cards/e/ErraticMutation.java b/Mage.Sets/src/mage/cards/e/ErraticMutation.java index a0d51b3599..f1fa29ca29 100644 --- a/Mage.Sets/src/mage/cards/e/ErraticMutation.java +++ b/Mage.Sets/src/mage/cards/e/ErraticMutation.java @@ -52,7 +52,7 @@ import mage.target.targetpointer.FixedTarget; public class ErraticMutation extends CardImpl { public ErraticMutation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}"); // Choose target creature. Reveal cards from the top of your library until you reveal a nonland card. That creature gets +X/-X until end of turn, where X is that card's converted mana cost. Put all cards revealed this way on the bottom of your library in any order. this.getSpellAbility().addTarget(new TargetCreaturePermanent()); @@ -93,18 +93,16 @@ class ErraticMutationEffect extends OneShotEffect { if (controller != null && sourceObject != null) { CardsImpl toReveal = new CardsImpl(); Card nonLandCard = null; - - while (nonLandCard == null && controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { toReveal.add(card); if (!card.isLand()) { nonLandCard = card; + break; } } // reveal cards - if (!toReveal.isEmpty()) { - controller.revealCards(sourceObject.getIdName(), toReveal, game); - } + controller.revealCards(sourceObject.getIdName(), toReveal, game); + // the nonland card if (nonLandCard != null) { int boostValue = nonLandCard.getConvertedManaCost(); diff --git a/Mage.Sets/src/mage/cards/e/ExplosiveRevelation.java b/Mage.Sets/src/mage/cards/e/ExplosiveRevelation.java index 4d9796da4a..2ac1ec42f3 100644 --- a/Mage.Sets/src/mage/cards/e/ExplosiveRevelation.java +++ b/Mage.Sets/src/mage/cards/e/ExplosiveRevelation.java @@ -90,22 +90,19 @@ class ExplosiveRevelationEffect extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null) { if (controller.getLibrary().hasCards()) { - - CardsImpl cards = new CardsImpl(); + CardsImpl toReveal = new CardsImpl(); Library library = controller.getLibrary(); - Card card = null; - do { - card = library.removeFromTop(game); - if (card != null) { - cards.add(card); + Card nonLandCard = null; + for (Card card : library.getCards(game)) { + toReveal.add(card); + if (!card.isLand()) { + nonLandCard = card; } - } while (library.hasCards() && card != null && card.isLand()); - // reveal cards - if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getIdName(), cards, game); } + // reveal cards + controller.revealCards(sourceObject.getIdName(), toReveal, game); // the nonland card - int damage = card.getConvertedManaCost(); + int damage = nonLandCard == null ? 0 : nonLandCard.getConvertedManaCost(); // assign damage to target for (UUID targetId : targetPointer.getTargets(game, source)) { Permanent targetedCreature = game.getPermanent(targetId); @@ -118,12 +115,13 @@ class ExplosiveRevelationEffect extends OneShotEffect { } } } - // move nonland card to hand - card.moveToZone(Zone.HAND, source.getSourceId(), game, true); - // remove nonland card from revealed card list - cards.remove(card); + if (nonLandCard != null) { + // move nonland card to hand + controller.moveCards(nonLandCard, Zone.HAND, source, game); + toReveal.remove(nonLandCard); + } // put the rest of the cards on the bottom of the library in any order - return controller.putCardsOnBottomOfLibrary(cards, game, source, true); + return controller.putCardsOnBottomOfLibrary(toReveal, game, source, true); } return true; } diff --git a/Mage.Sets/src/mage/cards/e/EyeOfYawgmoth.java b/Mage.Sets/src/mage/cards/e/EyeOfYawgmoth.java index 54d281fddb..86bf7f0328 100644 --- a/Mage.Sets/src/mage/cards/e/EyeOfYawgmoth.java +++ b/Mage.Sets/src/mage/cards/e/EyeOfYawgmoth.java @@ -106,29 +106,17 @@ class EyeOfYawgmothEffect extends OneShotEffect { } } if (power > 0) { - Cards cards = new CardsImpl(); - int count = Math.min(controller.getLibrary().size(), power); - for (int i = 0; i < count; i++) { - Card card = controller.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - controller.revealCards(source.getSourceObject(game).getIdName(), cards, game); - + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, power)); + controller.revealCards(source, cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand")); if (controller.choose(Outcome.DrawCard, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { + controller.moveCards(card, Zone.HAND, source, game); cards.remove(card); - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - game.informPlayers(source.getSourceObject(game).getIdName() + ": " + controller.getLogName() + " puts " + card.getIdName() + " into their hand"); } } - for (UUID cardId : cards) { - Card card = game.getCard(cardId); - card.moveToExile(null, "", source.getSourceId(), game); - } + controller.moveCards(cards, Zone.EXILED, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java b/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java index 74191b0a86..53db4fdc90 100644 --- a/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java +++ b/Mage.Sets/src/mage/cards/f/FlamesOfRemembrance.java @@ -27,8 +27,6 @@ */ package mage.cards.f; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -37,18 +35,21 @@ import mage.abilities.costs.common.ExileFromGraveCost; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.dynamicvalue.common.CountersSourceCount; import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.*; import mage.counters.CounterType; import mage.game.Game; -import mage.players.Library; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetpointer.FixedTargets; +import mage.util.CardUtil; /** * @@ -57,7 +58,7 @@ import mage.target.common.TargetCardInYourGraveyard; public class FlamesOfRemembrance extends CardImpl { public FlamesOfRemembrance(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}"); // At the beggining of your upkeep, you may exile a card from your graveyard. If you do, put a lore counter on Flames of Remembrance. this.addAbility(new BeginningOfUpkeepTriggeredAbility(new DoIfCostPaid(new AddCountersSourceEffect(CounterType.LORE.createInstance()), new ExileFromGraveCost(new TargetCardInYourGraveyard()), null, true), TargetController.YOU, false)); @@ -83,7 +84,7 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect { public FlamesOfRemembranceExileEffect(CountersSourceCount amount) { super(Outcome.Benefit); this.amount = amount; - this.staticText = "Exile top X cards of your library, where X is the number of lore counters on Flames of Remembrance. Until end of turn you play cards exile this way"; + this.staticText = "Exile top X cards of your library, where X is the number of lore counters on {this}. Until end of turn you play cards exile this way"; } public FlamesOfRemembranceExileEffect(final FlamesOfRemembranceExileEffect effect) { @@ -100,23 +101,12 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - - Library library = controller.getLibrary(); - List cards = new ArrayList<>(); - int count = Math.min(amount.calculate(game, source, this), library.size()); - for (int i = 0; i < count; i++) { - Card card = library.removeFromTop(game); - if (card != null) { - cards.add(card); - } - } + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, amount.calculate(game, source, this))); if (!cards.isEmpty()) { - List cardsId = new ArrayList<>(); - for (Card card : cards) { - card.moveToExile(source.getSourceId(), "Flames of Remembrance", source.getSourceId(), game); - cardsId.add(card.getId()); - } - game.addEffect(new FlamesOfRemembranceMayPlayExiledEffect(cardsId), source); + controller.moveCardsToExile(cards.getCards(game), source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, "")); + ContinuousEffect effect = new FlamesOfRemembranceMayPlayExiledEffect(); + effect.setTargetPointer(new FixedTargets(cards, game)); + game.addEffect(effect, source); } return true; } @@ -127,16 +117,12 @@ class FlamesOfRemembranceExileEffect extends OneShotEffect { class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl { - public List cards = new ArrayList<>(); - - public FlamesOfRemembranceMayPlayExiledEffect(List cards) { + public FlamesOfRemembranceMayPlayExiledEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - this.cards.addAll(cards); } public FlamesOfRemembranceMayPlayExiledEffect(final FlamesOfRemembranceMayPlayExiledEffect effect) { super(effect); - this.cards.addAll(effect.cards); } @Override @@ -150,15 +136,7 @@ class FlamesOfRemembranceMayPlayExiledEffect extends AsThoughEffectImpl { } @Override - public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { - Card card = game.getCard(sourceId); - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null && card != null && game.getState().getZone(sourceId) == Zone.EXILED) { - if (cards.contains(sourceId)) { - return true; - } - } - return false; + public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { + return source.getControllerId().equals(affectedControllerId) && this.getTargetPointer().getTargets(game, source).contains(objectId); } - } diff --git a/Mage.Sets/src/mage/cards/l/LongTermPlans.java b/Mage.Sets/src/mage/cards/l/LongTermPlans.java index fab9bae3c1..d99d9c781a 100644 --- a/Mage.Sets/src/mage/cards/l/LongTermPlans.java +++ b/Mage.Sets/src/mage/cards/l/LongTermPlans.java @@ -87,7 +87,7 @@ class LongTermPlansEffect extends OneShotEffect { Card card = player.getLibrary().remove(target.getFirstTarget(), game); if (card != null) { player.shuffleLibrary(source, game); - player.getLibrary().putCardThirdFromTheTop(card, game); + player.putCardOnTopXOfLibrary(card, game, source, 3); } } return true; diff --git a/Mage.Sets/src/mage/cards/o/OrochiSustainer.java b/Mage.Sets/src/mage/cards/o/OrochiSustainer.java index 5cddb8998f..0358c117fa 100644 --- a/Mage.Sets/src/mage/cards/o/OrochiSustainer.java +++ b/Mage.Sets/src/mage/cards/o/OrochiSustainer.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.cards.o; import java.util.UUID; @@ -42,12 +41,14 @@ import mage.constants.SubType; public class OrochiSustainer extends CardImpl { public OrochiSustainer(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); this.subtype.add(SubType.SNAKE); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(1); this.toughness = new MageInt(2); + + // {T}: Add {G}. this.addAbility(new GreenManaAbility()); } diff --git a/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java b/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java index beb697571c..fa839a925d 100644 --- a/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java +++ b/Mage.Sets/src/mage/cards/t/TeferiHeroOfDominaria.java @@ -38,14 +38,12 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.UntapLandsEffect; -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.SuperType; -import mage.constants.Zone; import mage.game.Game; import mage.game.command.emblems.TeferiHeroOfDominariaEmblem; import mage.game.permanent.Permanent; @@ -114,16 +112,7 @@ class TeferiHeroOfDominariaSecondEffect extends OneShotEffect { if (controller != null) { Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); if (permanent != null) { - Player owner = game.getPlayer(permanent.getOwnerId()); - if (owner == null) { - return false; - } - permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); - Card card = owner.getLibrary().remove(permanent.getId(), game); - if (card != null) { - owner.getLibrary().putCardThirdFromTheTop(card, game); - game.informPlayers(card.getLogName() + " is put into " + owner.getLogName() + "'s library third from the top"); - } + controller.putCardOnTopXOfLibrary(permanent, game, source, 3); } return true; } diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index b81671cfc6..1f25916096 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -1403,6 +1403,11 @@ public class TestPlayer implements Player { return computerPlayer.putCardsOnBottomOfLibrary(cards, game, source, anyOrder); } + @Override + public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) { + return computerPlayer.putCardOnTopXOfLibrary(card, game, source, xFromTheTop); + } + @Override public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) { return computerPlayer.putCardsOnTopOfLibrary(cards, game, source, anyOrder); diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index ca01958cb6..e6cdc6f7bc 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -908,6 +908,11 @@ public class PlayerStub implements Player { return false; } + @Override + public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) { + return true; + } + @Override public int announceXMana(int min, int max, String message, Game game, Ability ability) { return 0; diff --git a/Mage/src/main/java/mage/players/Library.java b/Mage/src/main/java/mage/players/Library.java index 77b816948f..f928eea29a 100644 --- a/Mage/src/main/java/mage/players/Library.java +++ b/Mage/src/main/java/mage/players/Library.java @@ -135,26 +135,17 @@ public class Library implements Serializable { } } - public void putCardThirdFromTheTop(Card card, Game game) { - if (card != null) { - if (card.getOwnerId().equals(playerId)) { - Card cardTop = null; - Card cardSecond = null; - if (hasCards()) { - cardTop = removeFromTop(game); - } - if (hasCards()) { - cardSecond = removeFromTop(game); - } - putOnTop(card, game); - if (cardSecond != null) { - putOnTop(cardSecond, game); - } - if (cardTop != null) { - putOnTop(cardTop, game); - } - } else { - game.getPlayer(card.getOwnerId()).getLibrary().putCardThirdFromTheTop(card, game); + public void putCardToTopXPos(Card card, int pos, Game game) { + if (card != null && pos > -1) { + LinkedList save = new LinkedList<>(); + int idx = 1; + while (hasCards() && idx < pos) { + idx++; + save.add(removeFromTop(game)); + } + putOnTop(card, game); + while (!save.isEmpty()) { + putOnTop(save.removeLast(), game); } } } diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index b08e8e8c41..efb73fff23 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -562,6 +562,17 @@ public interface Player extends MageItem, Copyable { */ boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder); + /** + * Moves the card to the top x position of the library + * + * @param card + * @param game + * @param source + * @param xFromTheTop + * @return + */ + boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop); + /** * Moves the cards from cards to the top of players library. * diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 9fd608468c..6a0524ddc6 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -84,6 +84,7 @@ import mage.game.events.ZoneChangeEvent; import mage.game.match.MatchPlayer; import mage.game.permanent.Permanent; import mage.game.permanent.PermanentCard; +import mage.game.permanent.PermanentToken; import mage.game.permanent.token.SquirrelToken; import mage.game.stack.Spell; import mage.game.stack.StackAbility; @@ -894,6 +895,26 @@ public abstract class PlayerImpl implements Player, Serializable { return true; } + @Override + public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop) { + if (card.getOwnerId().equals(getId())) { + if (library.size() + 1 < xFromTheTop) { + putCardsOnBottomOfLibrary(new CardsImpl(card), game, source, true); + } else { + if (card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true) && !(card instanceof PermanentToken) && !card.isCopy()) { + card = getLibrary().removeFromTop(game); + getLibrary().putCardToTopXPos(card, xFromTheTop, game); + game.informPlayers(card.getLogName() + " is put into " + getLogName() + "'s library " + CardUtil.numberToOrdinalText(xFromTheTop) + " from the top"); + } else { + return false; + } + } + } else { + return game.getPlayer(card.getOwnerId()).putCardOnTopXOfLibrary(card, game, source, xFromTheTop); + } + return true; + } + /** * Can be cards or permanents that go to library * @@ -1840,6 +1861,7 @@ public abstract class PlayerImpl implements Player, Serializable { return gainLife(amount, game, source.getSourceId()); } + @Override public int gainLife(int amount, Game game, UUID sourceId) { if (!canGainLife || amount == 0) { return 0; diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 7c636d2afe..beaeaafc54 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -51,6 +51,9 @@ public final class CardUtil { static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; + static final String[] ordinalStrings = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eightth", "ninth", + "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"}; + /** * Increase spell or ability cost to be paid. * @@ -363,6 +366,13 @@ public final class CardUtil { return number; } + public static String numberToOrdinalText(int number) { + if (number >= 1 && number < 21) { + return ordinalStrings[number - 1]; + } + return Integer.toString(number) + "th"; + } + public static String replaceSourceName(String message, String sourceName) { message = message.replace("{this}", sourceName); message = message.replace("{source}", sourceName); diff --git a/Utils/gen-list-unimplemented-cards-for-set.pl b/Utils/gen-list-unimplemented-cards-for-set.pl index 154f2ae8a6..98a8da096e 100755 --- a/Utils/gen-list-unimplemented-cards-for-set.pl +++ b/Utils/gen-list-unimplemented-cards-for-set.pl @@ -99,8 +99,10 @@ foreach my $card (sort cardSort @setCards) { $cardNames {@{$card}[0]} = 0; if ($toPrint) { $toPrint .= "\n"; - } - $toPrint .= "@{$card}[2]|@{$card}[0]"; + } + my $cardName = @{$card}[0]; + $cardName =~ s/ /+/g; + $toPrint .= "@{$card}[2]|[@{$card}[0]](https://magiccards.info/query?q=!$cardName)"; } } @@ -125,7 +127,7 @@ foreach $cn (sort keys (%cardNames)) } my $cn2 = $cn; $cn2 =~ s/ /+/g; - print ISSUE_TRACKER "- $x_or_not [$cn](https://www.google.com.au/search?q=$cn2+MTG&tbm=isch)\n"; + print ISSUE_TRACKER "- $x_or_not [$cn](https://magiccards.info/query?q=!$cn2)\n"; } close ISSUE_TRACKER; print ("Tracking Issue text for a new Github issue (similar to https://github.com/magefree/mage/issues/2215): " . lc($sets{$setName}) ."_issue_tracker.txt\n");