From df987049c06d8e12eabb9cc2706c87a06cd78df8 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Tue, 8 May 2018 18:01:15 +0200 Subject: [PATCH] * Fixed some card movement (fixes #4910). --- .../src/mage/cards/a/AbbotOfKeralKeep.java | 4 +- Mage.Sets/src/mage/cards/a/Abundance.java | 3 +- Mage.Sets/src/mage/cards/a/ActOnImpulse.java | 70 ++++++++----------- Mage.Sets/src/mage/cards/a/AdNauseam.java | 2 +- Mage.Sets/src/mage/cards/a/AerialCaravan.java | 4 +- .../src/mage/cards/a/AethermagesTouch.java | 52 ++++++-------- Mage.Sets/src/mage/cards/a/AladdinsLamp.java | 62 ++++++---------- .../src/mage/cards/a/AncestralKnowledge.java | 56 +++++---------- .../src/mage/cards/a/AncestralMemories.java | 38 +++------- .../src/mage/cards/a/ArchitectsOfWill.java | 16 ++--- Mage.Sets/src/mage/cards/a/AshnodsCylix.java | 36 +++------- Mage.Sets/src/mage/cards/a/AuguryAdept.java | 13 ++-- Mage.Sets/src/mage/cards/b/BalustradeSpy.java | 23 +++--- .../src/mage/cards/b/BitterRevelation.java | 42 ++++------- .../mage/cards/b/BlessedReincarnation.java | 62 +++++++--------- .../src/mage/cards/b/BreathstealersCrypt.java | 33 ++++----- Mage.Sets/src/mage/cards/b/Browse.java | 29 +++----- .../src/mage/cards/c/ChandraPyromaster.java | 2 +- .../src/mage/cards/c/ChaosHarlequin.java | 6 +- Mage.Sets/src/mage/cards/c/CloneShell.java | 53 +++++--------- .../src/mage/cards/c/ColfenorsPlans.java | 24 ++++--- .../src/mage/cards/c/CommuneWithTheGods.java | 46 ++++-------- .../src/mage/cards/c/ConsumingAberration.java | 23 +++--- .../src/mage/cards/c/ConundrumSphinx.java | 4 +- .../src/mage/cards/c/CountrysideCrusher.java | 7 +- .../src/mage/cards/d/DemonicConsultation.java | 3 +- Mage.Sets/src/mage/cards/d/DiviningWitch.java | 3 +- Mage.Sets/src/mage/cards/f/FathomTrawl.java | 5 +- .../src/mage/cards/g/GoblinCharbelcher.java | 21 +++--- Mage.Sets/src/mage/cards/h/HeirloomBlade.java | 7 +- Mage.Sets/src/mage/cards/o/OathOfDruids.java | 34 +++++---- Mage.Sets/src/mage/cards/p/ProteusStaff.java | 3 +- .../src/mage/cards/r/RiptideShapeshifter.java | 3 +- .../src/mage/cards/s/ShiftingShadow.java | 9 ++- .../src/mage/cards/s/SpoilsOfTheVault.java | 5 +- .../java/org/mage/test/player/TestPlayer.java | 20 ++++++ .../java/org/mage/test/stub/PlayerStub.java | 20 ++++++ Mage/src/main/java/mage/cards/CardsImpl.java | 6 ++ Mage/src/main/java/mage/players/Library.java | 42 ++++++----- Mage/src/main/java/mage/players/Player.java | 27 +++++++ .../main/java/mage/players/PlayerImpl.java | 41 ++++++++--- .../target/targetpointer/FixedTargets.java | 10 +++ Mage/src/main/java/mage/util/CardUtil.java | 60 ++++++++++------ 43 files changed, 481 insertions(+), 548 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java index 688697154bf..6f031ca861d 100644 --- a/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java +++ b/Mage.Sets/src/mage/cards/a/AbbotOfKeralKeep.java @@ -52,7 +52,7 @@ import mage.target.targetpointer.FixedTarget; public class AbbotOfKeralKeep extends CardImpl { public AbbotOfKeralKeep(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.MONK); this.power = new MageInt(2); @@ -97,7 +97,7 @@ class AbbotOfKeralKeepExileEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (sourcePermanent != null && controller != null && controller.getLibrary().hasCards()) { Library library = controller.getLibrary(); - Card card = library.removeFromTop(game); + Card card = library.getFromTop(game); if (card != null) { String exileName = sourcePermanent.getIdName() + " "; controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); diff --git a/Mage.Sets/src/mage/cards/a/Abundance.java b/Mage.Sets/src/mage/cards/a/Abundance.java index e234a73be4a..b29a7f461ce 100644 --- a/Mage.Sets/src/mage/cards/a/Abundance.java +++ b/Mage.Sets/src/mage/cards/a/Abundance.java @@ -104,8 +104,7 @@ class AbundanceReplacementEffect extends ReplacementEffectImpl { } Cards toReveal = new CardsImpl(); Card selectedCard = null; - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { toReveal.add(card); if (filter.match(card, source.getSourceId(), source.getControllerId(), game)) { selectedCard = card; diff --git a/Mage.Sets/src/mage/cards/a/ActOnImpulse.java b/Mage.Sets/src/mage/cards/a/ActOnImpulse.java index 8f45324b184..d03aa7e837b 100644 --- a/Mage.Sets/src/mage/cards/a/ActOnImpulse.java +++ b/Mage.Sets/src/mage/cards/a/ActOnImpulse.java @@ -27,19 +27,21 @@ */ package mage.cards.a; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; -import mage.players.Library; import mage.players.Player; +import mage.target.targetpointer.FixedTargets; /** * @@ -48,8 +50,7 @@ import mage.players.Player; public class ActOnImpulse extends CardImpl { public ActOnImpulse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}"); // Exile the top three cards of your library. Until end of turn, you may play cards exiled this way. this.getSpellAbility().addEffect(new ActOnImpulseExileEffect()); @@ -66,12 +67,12 @@ public class ActOnImpulse extends CardImpl { } class ActOnImpulseExileEffect extends OneShotEffect { - + public ActOnImpulseExileEffect() { super(Outcome.Benefit); this.staticText = "Exile the top three cards of your library. Until end of turn, you may play cards exiled this way."; } - + public ActOnImpulseExileEffect(final ActOnImpulseExileEffect effect) { super(effect); } @@ -80,69 +81,58 @@ class ActOnImpulseExileEffect extends OneShotEffect { public ActOnImpulseExileEffect copy() { return new ActOnImpulseExileEffect(this); } - + @Override 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(3, library.size()); - for (int i = 0; i < count; i++) { - Card card = library.removeFromTop(game); - if (card != null) { - cards.add(card); - } - } + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + Set cards = new HashSet<>(controller.getLibrary().getTopCards(game, 3)); if (!cards.isEmpty()) { - List cardsId = new ArrayList<>(); + controller.moveCardsToExile(cards, source, game, true, source.getSourceId(), sourceObject.getIdName()); + // remove cards that could not be moved to exile for (Card card : cards) { - card.moveToExile(source.getSourceId(), "Act on Impulse", source.getSourceId(), game); - cardsId.add(card.getId()); + if (!Zone.EXILED.equals(game.getState().getZone(card.getId()))) { + cards.remove(card); + } + } + if (!cards.isEmpty()) { + ContinuousEffect effect = new ActOnImpulseMayPlayExiledEffect(); + effect.setTargetPointer(new FixedTargets(cards, game)); + game.addEffect(effect, source); } - game.addEffect(new ActOnImpulseMayPlayExiledEffect(cardsId), source); } return true; } return false; } - + } class ActOnImpulseMayPlayExiledEffect extends AsThoughEffectImpl { - public List cards = new ArrayList<>(); - - public ActOnImpulseMayPlayExiledEffect(List cards) { + public ActOnImpulseMayPlayExiledEffect() { super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); - this.cards.addAll(cards); } - + public ActOnImpulseMayPlayExiledEffect(final ActOnImpulseMayPlayExiledEffect effect) { super(effect); - this.cards.addAll(effect.cards); } @Override public ActOnImpulseMayPlayExiledEffect copy() { return new ActOnImpulseMayPlayExiledEffect(this); } - + @Override public boolean apply(Game game, Ability source) { return true; } @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 affectedControllerId.equals(source.getControllerId()) + && getTargetPointer().getTargets(game, source).contains(objectId); } - + } diff --git a/Mage.Sets/src/mage/cards/a/AdNauseam.java b/Mage.Sets/src/mage/cards/a/AdNauseam.java index dbe8a9c7f4d..9677fdd14e9 100644 --- a/Mage.Sets/src/mage/cards/a/AdNauseam.java +++ b/Mage.Sets/src/mage/cards/a/AdNauseam.java @@ -87,7 +87,7 @@ class AdNauseamEffect extends OneShotEffect { return false; } while (controller.chooseUse(outcome, message, source, game) && controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + Card card = controller.getLibrary().getFromTop(game); if (card != null) { controller.moveCards(card, Zone.HAND, source, game); int cmc = card.getConvertedManaCost(); diff --git a/Mage.Sets/src/mage/cards/a/AerialCaravan.java b/Mage.Sets/src/mage/cards/a/AerialCaravan.java index c9961f8e3a6..c1482249cec 100644 --- a/Mage.Sets/src/mage/cards/a/AerialCaravan.java +++ b/Mage.Sets/src/mage/cards/a/AerialCaravan.java @@ -35,7 +35,6 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.constants.SubType; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -44,6 +43,7 @@ import mage.constants.AsThoughEffectType; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Library; @@ -103,7 +103,7 @@ class AerialCaravanExileEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (sourcePermanent != null && controller != null && controller.getLibrary().hasCards()) { Library library = controller.getLibrary(); - Card card = library.removeFromTop(game); + Card card = library.getFromTop(game); if (card != null) { String exileName = sourcePermanent.getIdName() + " "; controller.moveCardsToExile(card, source, game, true, source.getSourceId(), exileName); diff --git a/Mage.Sets/src/mage/cards/a/AethermagesTouch.java b/Mage.Sets/src/mage/cards/a/AethermagesTouch.java index a2d62f2dede..3dbef178a16 100644 --- a/Mage.Sets/src/mage/cards/a/AethermagesTouch.java +++ b/Mage.Sets/src/mage/cards/a/AethermagesTouch.java @@ -28,6 +28,7 @@ package mage.cards.a; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.effects.ContinuousEffect; @@ -38,6 +39,7 @@ import mage.cards.*; import mage.constants.*; import mage.filter.common.FilterCreatureCard; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; import mage.target.targetpointer.FixedTarget; @@ -49,8 +51,7 @@ import mage.target.targetpointer.FixedTarget; public class AethermagesTouch extends CardImpl { public AethermagesTouch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{W}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{U}"); // Reveal the top four cards of your library. You may put a creature card from among them onto the battlefield. It gains "At the beginning of your end step, return this creature to its owner's hand." Then put the rest of the cards revealed this way on the bottom of your library in any order. this.getSpellAbility().addEffect(new AethermagesTouchEffect()); @@ -65,12 +66,11 @@ public class AethermagesTouch extends CardImpl { return new AethermagesTouch(this); } } + class AethermagesTouchEffect extends OneShotEffect { - private static final FilterCreatureCard filterPutOntoBattlefield = new FilterCreatureCard("a creature card to put onto the battlefield"); - public AethermagesTouchEffect() { - super(Outcome.DrawCard); + super(Outcome.PutCardInPlay); this.staticText = "Reveal the top four cards of your library. You may put a creature card from among them onto the battlefield. It gains \"At the beginning of your end step, return this creature to its owner's hand.\" Then put the rest of the cards revealed this way on the bottom of your library in any order"; } @@ -85,40 +85,32 @@ class AethermagesTouchEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Cards cards = new CardsImpl(); - - boolean properCardFound = false; - int count = Math.min(player.getLibrary().size(), 4); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - if (filterPutOntoBattlefield.match(card, source.getSourceId(), source.getControllerId(), game)) { - properCardFound = true; - } - } - } - + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4)); if (!cards.isEmpty()) { - player.revealCards("Aethermage's Touch", cards, game); - TargetCard target = new TargetCard(Zone.LIBRARY, filterPutOntoBattlefield); - if (properCardFound && player.choose(Outcome.PutCreatureInPlay, cards, target, game)) { + FilterCreatureCard filter = new FilterCreatureCard("a creature card to put onto the battlefield"); + controller.revealCards(sourceObject.getIdName(), cards, game); + TargetCard target = new TargetCard(Zone.LIBRARY, filter); + if (cards.count(filter, game) > 0 && controller.choose(outcome, cards, target, game)) { Card card = game.getCard(target.getFirstTarget()); if (card != null) { cards.remove(card); - if (card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId())) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { // It gains \"At the beginning of your end step, return this creature to its owner's hand.\" - Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), TargetController.YOU, null, false); - ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.Custom); - effect.setTargetPointer(new FixedTarget(card.getId())); - game.addEffect(effect, source); + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), TargetController.YOU, null, false); + ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.Custom); + effect.setTargetPointer(new FixedTarget(permanent, game)); + game.addEffect(effect, source); + } } } } - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); } return true; diff --git a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java index cc5864cf6d7..bf70fa15571 100644 --- a/Mage.Sets/src/mage/cards/a/AladdinsLamp.java +++ b/Mage.Sets/src/mage/cards/a/AladdinsLamp.java @@ -51,15 +51,14 @@ import mage.target.TargetCard; public class AladdinsLamp extends CardImpl { public AladdinsLamp(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{10}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{10}"); - // {X}, {tap}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AladdinsLampEffect(), new ManaCostsImpl("{X}")); + // {X}, {T}: The next time you would draw a card this turn, instead look at the top X cards of your library, put all but one of them on the bottom of your library in a random order, then draw a card. X can't be 0. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AladdinsLampEffect(), new ManaCostsImpl("{X}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - + } - public AladdinsLamp(final AladdinsLamp card) { super(card); @@ -88,53 +87,32 @@ class AladdinsLampEffect extends ReplacementEffectImpl { } @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - Cards cards = new CardsImpl(); - int count = source.getManaCostsToPay().getX(); - count = Math.min(player.getLibrary().size(), count); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game);// I'd like to use .getTopCards(game, count), but it returns a set which I dunno how to work with and would break the copied code adding to effort/time; - if (card != null) { - cards.add(card); - } + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, source.getManaCostsToPay().getX())); + controller.lookAtCards(source, null, cards, game); + TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to stay at the top of library")); + if (controller.choose(outcome, cards, target, game)) { + cards.remove(target.getFirstTarget()); } - player.lookAtCards("Aladdin's Lamp", cards, game); - - TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard()); - - if (player.choose(outcome, cards, target, game)) { - Card card = cards.get(target.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - } - } - - - // Put the rest on the bottom of your library in a random order - while (!cards.isEmpty()) { - Card card = cards.getRandom(game); - if (card != null) { - cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); - } - } - //player.drawCards(1, game); // Technically I should move it to the top and then draw but, I cant confirm that flag above refers to bottom of library + controller.putCardsOnBottomOfLibrary(cards, game, source, false); + game.applyEffects(); + controller.drawCards(1, game, event.getAppliedEffects()); + discard(); return true; } - + @Override public boolean checksEventType(GameEvent event, Game game) { return event.getType() == GameEvent.EventType.DRAW_CARD; - } - + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { return source.getControllerId().equals(event.getPlayerId()); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/a/AncestralKnowledge.java b/Mage.Sets/src/mage/cards/a/AncestralKnowledge.java index b83b8a15e74..3ce6ce1345f 100644 --- a/Mage.Sets/src/mage/cards/a/AncestralKnowledge.java +++ b/Mage.Sets/src/mage/cards/a/AncestralKnowledge.java @@ -51,15 +51,14 @@ import mage.target.TargetCard; public class AncestralKnowledge extends CardImpl { public AncestralKnowledge(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); // Cumulative upkeep {1} this.addAbility(new CumulativeUpkeepAbility(new ManaCostsImpl<>("{1}"))); - + // When Ancestral Knowledge enters the battlefield, look at the top ten cards of your library, then exile any number of them and put the rest back on top of your library in any order. this.addAbility(new EntersBattlefieldTriggeredAbility(new AncestralKnowledgeEffect())); - + // When Ancestral Knowledge leaves the battlefield, shuffle your library. this.addAbility(new LeavesBattlefieldTriggeredAbility(new ShuffleLibrarySourceEffect(), false)); } @@ -75,53 +74,34 @@ public class AncestralKnowledge extends CardImpl { } class AncestralKnowledgeEffect extends OneShotEffect { - + AncestralKnowledgeEffect() { super(Outcome.Benefit); this.staticText = "look at the top ten cards of your library, then exile any number of them and put the rest back on top of your library in any order"; } - + AncestralKnowledgeEffect(final AncestralKnowledgeEffect effect) { super(effect); } - + @Override public AncestralKnowledgeEffect copy() { return new AncestralKnowledgeEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - int numCards = Math.min(10, player.getLibrary().size()); - if (numCards > 0) { - Cards cards = new CardsImpl(); - for (int i = 0; i < numCards; i++) { - cards.add(player.getLibrary().removeFromTop(game)); - } - TargetCard target = new TargetCard(0, numCards, Zone.LIBRARY, new FilterCard("cards to exile")); - player.choose(Outcome.Exile, cards, target, game); - for (UUID cardId : target.getTargets()) { - Card card = cards.get(cardId, game); - if (card != null) { - player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); - cards.remove(card); - } - } - while (cards.size() > 1) { - target = new TargetCard(1, Zone.LIBRARY, new FilterCard("card to put on top of library (last put is first drawn)")); - player.choose(Outcome.Benefit, cards, target, game); - Card card = cards.get(target.getFirstTarget(), game); - player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); - cards.remove(card); - } - if (cards.size() == 1) { - Card card = cards.get(cards.iterator().next(), game); - if (card != null) { - player.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.LIBRARY, true, false); - } - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 10)); + if (cards.size() > 0) { + controller.lookAtCards(source, null, cards, game); + TargetCard target = new TargetCard(0, Integer.MAX_VALUE, Zone.LIBRARY, new FilterCard("cards to exile")); + controller.choose(Outcome.Exile, cards, target, game); + Cards toExile = new CardsImpl(target.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/a/AncestralMemories.java b/Mage.Sets/src/mage/cards/a/AncestralMemories.java index 9dec2fdb8cc..f3511c3542f 100644 --- a/Mage.Sets/src/mage/cards/a/AncestralMemories.java +++ b/Mage.Sets/src/mage/cards/a/AncestralMemories.java @@ -27,6 +27,7 @@ */ package mage.cards.a; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.*; @@ -38,8 +39,6 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; -import java.util.UUID; - /** * * @author Quercitron @@ -47,8 +46,7 @@ import java.util.UUID; public class AncestralMemories extends CardImpl { public AncestralMemories(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}{U}"); // Look at the top seven cards of your library. Put two of them into your hand and the rest into your graveyard. this.getSpellAbility().addEffect(new AncestralMemoriesEffect()); @@ -82,32 +80,18 @@ class AncestralMemoriesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - - if (player != null) { - Cards cards = new CardsImpl(); - int cardsCount = Math.min(7, player.getLibrary().size()); - for (int i = 0; i < cardsCount; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 7)); if (!cards.isEmpty()) { - player.lookAtCards("Ancestral Memories", cards, game); - + controller.lookAtCards(source, null, cards, game); TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.LIBRARY, new FilterCard("two cards to put in your hand")); - if (player.choose(Outcome.Benefit, cards, target, game)) { - for (UUID targetId : target.getTargets()) { - Card card = cards.get(targetId, game); - if (card != null) { - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); - cards.remove(card); - } - } + if (controller.choose(Outcome.DrawCard, cards, target, game)) { + Cards toHand = new CardsImpl(target.getTargets()); + controller.moveCards(cards, Zone.HAND, source, game); + cards.removeAll(toHand); } - player.moveCards(cards, Zone.GRAVEYARD, source, game); + controller.moveCards(cards, Zone.GRAVEYARD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/a/ArchitectsOfWill.java b/Mage.Sets/src/mage/cards/a/ArchitectsOfWill.java index e8fab3707b0..443d7a7f876 100644 --- a/Mage.Sets/src/mage/cards/a/ArchitectsOfWill.java +++ b/Mage.Sets/src/mage/cards/a/ArchitectsOfWill.java @@ -49,7 +49,7 @@ import mage.target.TargetPlayer; public class ArchitectsOfWill extends CardImpl { public ArchitectsOfWill(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{2}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}{B}"); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.WIZARD); @@ -95,19 +95,11 @@ class ArchitectsOfWillEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(source.getFirstTarget()); - if (targetPlayer == null - || controller == null) { + if (targetPlayer == null || 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("Architects of Will", 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/a/AshnodsCylix.java b/Mage.Sets/src/mage/cards/a/AshnodsCylix.java index 0615ee96b47..f57ce54bff6 100644 --- a/Mage.Sets/src/mage/cards/a/AshnodsCylix.java +++ b/Mage.Sets/src/mage/cards/a/AshnodsCylix.java @@ -30,7 +30,6 @@ package mage.cards.a; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.Cost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; @@ -44,9 +43,7 @@ import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; -import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.Target; import mage.target.TargetCard; import mage.target.TargetPlayer; @@ -57,7 +54,7 @@ import mage.target.TargetPlayer; public class AshnodsCylix extends CardImpl { public AshnodsCylix(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); // {3}, {T}: Target player looks at the top three cards of their library, puts one of them back on top of their library, then exiles the rest. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AshnodsCylixEffect(), new GenericManaCost(3)); @@ -77,49 +74,38 @@ public class AshnodsCylix extends CardImpl { } class AshnodsCylixEffect extends OneShotEffect { - + AshnodsCylixEffect() { super(Outcome.Benefit); this.staticText = "Target player looks at the top three cards of their library, puts one of them back on top of their library, then exiles the rest"; } - + AshnodsCylixEffect(final AshnodsCylixEffect effect) { super(effect); } - + @Override public AshnodsCylixEffect copy() { return new AshnodsCylixEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player == null) { return false; } - Cards cards = new CardsImpl(); - int count = Math.min(player.getLibrary().size(), 3); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - //~ player.revealCards(source.getSourceObject(game).getIdName(), cards, game); + Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 3)); + player.lookAtCards(source, null, cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on top of your library")); - if (player.choose(Outcome.DrawCard, cards, target, game)) { + if (player.choose(Outcome.Benefit, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { cards.remove(card); - player.getLibrary().putOnTop(card, game); - game.informPlayers(source.getSourceObject(game).getIdName() + ": " + player.getLogName() + " puts a card on top of their library"); + game.informPlayers(source.getSourceObject(game).getIdName() + ": " + player.getLogName() + " puts a card back on top of their library"); } } - for (UUID cardId : cards) { - Card card = game.getCard(cardId); - card.moveToExile(null, "", source.getSourceId(), game); - } + player.moveCards(cards, Zone.EXILED, source, game); return true; } } diff --git a/Mage.Sets/src/mage/cards/a/AuguryAdept.java b/Mage.Sets/src/mage/cards/a/AuguryAdept.java index ac83ca62458..2a93b5a236d 100644 --- a/Mage.Sets/src/mage/cards/a/AuguryAdept.java +++ b/Mage.Sets/src/mage/cards/a/AuguryAdept.java @@ -29,7 +29,6 @@ package mage.cards.a; import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -48,7 +47,7 @@ import mage.players.Player; public class AuguryAdept extends CardImpl { public AuguryAdept(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W/U}{W/U}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/U}{W/U}"); this.subtype.add(SubType.KITHKIN); this.subtype.add(SubType.WIZARD); @@ -87,22 +86,18 @@ class AuguryAdeptEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject sourceObject = game.getObject(source.getSourceId()); Player controller = game.getPlayer(source.getControllerId()); - if (controller == null || sourceObject == null) { + if (controller == null) { return false; } - Cards cards = new CardsImpl(); - Card card = controller.getLibrary().removeFromTop(game); + Card card = controller.getLibrary().getFromTop(game); if (card != null) { card.moveToZone(Zone.HAND, source.getSourceId(), game, true); - int cmc = card.getConvertedManaCost(); if (cmc > 0) { controller.gainLife(cmc, game, source); } - cards.add(card); - controller.revealCards(sourceObject.getName(), cards, game); + controller.revealCards(source, new CardsImpl(card), game); } return true; } diff --git a/Mage.Sets/src/mage/cards/b/BalustradeSpy.java b/Mage.Sets/src/mage/cards/b/BalustradeSpy.java index 3b9f2725573..c764d93e4af 100644 --- a/Mage.Sets/src/mage/cards/b/BalustradeSpy.java +++ b/Mage.Sets/src/mage/cards/b/BalustradeSpy.java @@ -29,7 +29,6 @@ package mage.cards.b; import java.util.UUID; import mage.MageInt; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -53,7 +52,7 @@ import mage.target.TargetPlayer; public class BalustradeSpy extends CardImpl { public BalustradeSpy(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}"); this.subtype.add(SubType.VAMPIRE, SubType.ROGUE); this.power = new MageInt(2); @@ -97,26 +96,20 @@ class BalustradeSpyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(getTargetPointer().getFirst(game, source)); - MageObject sourceObject = source.getSourceObject(game); - if (controller == null || sourceObject == null) { + if (controller == null) { return false; } - CardsImpl cards = new CardsImpl(); - boolean landFound = false; - while (controller.getLibrary().hasCards() && !landFound) { - Card card = controller.getLibrary().removeFromTop(game); + CardsImpl toGraveyard = new CardsImpl(); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { - cards.add(card); + toGraveyard.add(card); if (card.isLand()) { - landFound = true; + break; } } } - if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getName(), cards, game); - controller.moveCards(cards, Zone.GRAVEYARD, source, game); - return true; - } + controller.revealCards(source, toGraveyard, game); + controller.moveCards(toGraveyard, Zone.GRAVEYARD, source, game); return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BitterRevelation.java b/Mage.Sets/src/mage/cards/b/BitterRevelation.java index e93f564f622..230b15fb400 100644 --- a/Mage.Sets/src/mage/cards/b/BitterRevelation.java +++ b/Mage.Sets/src/mage/cards/b/BitterRevelation.java @@ -47,8 +47,7 @@ import mage.target.TargetCard; public class BitterRevelation extends CardImpl { public BitterRevelation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}"); // Look at the top four cards of your library. Put two of them into your hand and the rest into your graveyard. You lose 2 life. this.getSpellAbility().addEffect(new BitterRevelationEffect()); @@ -66,48 +65,35 @@ public class BitterRevelation extends CardImpl { } class BitterRevelationEffect extends OneShotEffect { - + BitterRevelationEffect() { super(Outcome.Benefit); this.staticText = "Look at the top four cards of your library. Put two of them into your hand and the rest into your graveyard"; } - + BitterRevelationEffect(final BitterRevelationEffect effect) { super(effect); } - + @Override public BitterRevelationEffect copy() { return new BitterRevelationEffect(this); } - + @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Cards cards = new CardsImpl(); - int cardsCount = Math.min(4, player.getLibrary().size()); - for (int i = 0; i < cardsCount; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4)); if (!cards.isEmpty()) { - Cards cardsToHand = new CardsImpl(); - player.lookAtCards("Bitter Revelation", cards, game); + controller.lookAtCards(source, null, cards, game); TargetCard target = new TargetCard(Math.min(2, cards.size()), Zone.LIBRARY, new FilterCard("two cards to put in your hand")); - if (player.choose(Outcome.DrawCard, cards, target, game)) { - for (UUID targetId : target.getTargets()) { - Card card = cards.get(targetId, game); - if (card != null) { - cardsToHand.add(card); - cards.remove(card); - } - } + if (controller.choose(Outcome.DrawCard, cards, target, game)) { + Cards toHand = new CardsImpl(target.getTargets()); + controller.moveCards(toHand, Zone.HAND, source, game); + cards.removeAll(toHand); } - player.moveCards(cardsToHand, Zone.HAND, source, game); - player.moveCards(cards, Zone.GRAVEYARD, source, game); + controller.moveCards(cards, Zone.GRAVEYARD, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/b/BlessedReincarnation.java b/Mage.Sets/src/mage/cards/b/BlessedReincarnation.java index b7bea59d2ad..012bf6fdd58 100644 --- a/Mage.Sets/src/mage/cards/b/BlessedReincarnation.java +++ b/Mage.Sets/src/mage/cards/b/BlessedReincarnation.java @@ -27,11 +27,9 @@ */ package mage.cards.b; -import java.util.Set; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetEffect; import mage.abilities.keyword.ReboundAbility; import mage.cards.*; import mage.constants.CardType; @@ -51,24 +49,22 @@ import mage.target.common.TargetCreaturePermanent; * @author fireshoes */ public class BlessedReincarnation extends CardImpl { - + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); - + static { filter.add(new ControllerPredicate(TargetController.OPPONENT)); } public BlessedReincarnation(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}"); - // Exile target creature an opponent controls. - this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); - this.getSpellAbility().addEffect(new ExileTargetEffect()); - + // Exile target creature an opponent controls. // That player reveals cards from the top of their library until a creature card is revealed. // The player puts that card onto the battlefield, then shuffles the rest into their library. this.getSpellAbility().addEffect(new BlessedReincarnationEffect()); - + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + // Rebound this.addAbility(new ReboundAbility()); } @@ -87,7 +83,7 @@ class BlessedReincarnationEffect extends OneShotEffect { public BlessedReincarnationEffect() { super(Outcome.PutCreatureInPlay); - this.staticText = "That player reveals cards from the top of their library until a creature card is revealed. The player puts that card onto the battlefield, then shuffles the rest into their library"; + this.staticText = "Exile target creature an opponent controls. That player reveals cards from the top of their library until a creature card is revealed. The player puts that card onto the battlefield, then shuffles the rest into their library"; } public BlessedReincarnationEffect(final BlessedReincarnationEffect effect) { @@ -101,37 +97,31 @@ class BlessedReincarnationEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getFirstTarget()); - if (permanent == null) { - permanent = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); - } + Player controller = game.getPlayer(source.getControllerId()); + Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (permanent != null && controller != null) { + controller.moveCards(permanent, Zone.EXILED, source, game); + game.applyEffects(); - if (permanent != null) { - Player player = game.getPlayer(permanent.getControllerId()); - if (player != null) { - Library library = player.getLibrary(); + Player permanentController = game.getPlayer(permanent.getControllerId()); + if (permanentController != null) { + Library library = permanentController.getLibrary(); if (library.hasCards()) { - Cards cards = new CardsImpl(); - Card card = library.removeFromTop(game); - cards.add(card); - while (!card.isCreature() && library.hasCards()) { - card = library.removeFromTop(game); - cards.add(card); + Cards toReveal = new CardsImpl(); + for (Card card : library.getCards(game)) { + toReveal.add(card); + if (card.isCreature()) { + permanentController.moveCards(card, Zone.BATTLEFIELD, source, game); + break; + } } - - if (card.isCreature()) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), player.getId()); - } - - if (!cards.isEmpty()) { - player.revealCards("BlessedReincarnation", cards, game); - Set cardsToShuffle = cards.getCards(game); - cardsToShuffle.remove(card); - library.addAll(cardsToShuffle, game); + permanentController.revealCards(source, toReveal, game); + if (toReveal.size() > 1) { + library.shuffle(); } } - return true; } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java index c93450f6e33..94718a650a1 100644 --- a/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java +++ b/Mage.Sets/src/mage/cards/b/BreathstealersCrypt.java @@ -36,7 +36,6 @@ 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.Duration; import mage.constants.Outcome; @@ -93,25 +92,27 @@ class BreathstealersCryptEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(event.getPlayerId()); - PayLifeCost cost = new PayLifeCost(3); if (player != null) { - Card cardDrawn = player.getLibrary().removeFromTop(game); - if (cardDrawn != null) { - player.moveCardToHandWithInfo(cardDrawn, source.getSourceId(), game); - Cards cards = new CardsImpl(); - cards.add(cardDrawn); - player.revealCards("The card drawn from " + player.getName() + "'s library", cards, game); - if (cardDrawn.isCreature()) { - game.informPlayers("The card drawn by " + player.getName() + " is a creature card. He/she must pay 3 life or that card gets discarded."); - if (cost.canPay(source, source.getSourceId(), player.getId(), game) - && player.chooseUse(outcome, "Do you wish to pay 3 life to keep the drawn creature card? If not, you discard it.", source, game)) { - return cost.pay(source, game, source.getSourceId(), player.getId(), true, cost); - } else { - game.informPlayers("The cost of 3 life was not paid by " + player.getName() + ", so the creature card will be discarded."); - return player.discard(cardDrawn, source, game); + Cards oldHand = player.getHand().copy(); + if (player.drawCards(1, game, event.getAppliedEffects()) > 0) { + Cards drawnCards = player.getHand().copy(); + drawnCards.removeAll(oldHand); + player.revealCards(source, "The card drawn from " + player.getName() + "'s library.", drawnCards, game); + for (Card cardDrawn : drawnCards.getCards(game)) { + if (cardDrawn.isCreature()) { + game.informPlayers("The card drawn by " + player.getName() + " is a creature card. He/she must pay 3 life or that card gets discarded."); + PayLifeCost cost = new PayLifeCost(3); + if (cost.canPay(source, source.getSourceId(), player.getId(), game) + && player.chooseUse(outcome, "Do you wish to pay 3 life to keep the card " + cardDrawn.getIdName() + "? If not, you discard it.", source, game)) { + cost.pay(source, game, source.getSourceId(), player.getId(), true, cost); + } else { + game.informPlayers("The cost of 3 life was not paid by " + player.getName() + ", so " + cardDrawn.getIdName() + " will be discarded."); + player.discard(cardDrawn, source, game); + } } } } + return true; } return false; } diff --git a/Mage.Sets/src/mage/cards/b/Browse.java b/Mage.Sets/src/mage/cards/b/Browse.java index 0a1e222e078..dd7ca439a9d 100644 --- a/Mage.Sets/src/mage/cards/b/Browse.java +++ b/Mage.Sets/src/mage/cards/b/Browse.java @@ -48,7 +48,7 @@ import mage.target.TargetCard; public class Browse extends CardImpl { public Browse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}"); // {2}{U}{U}: Look at the top five cards of your library, put one of them into your hand, and exile the rest. SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BrowseEffect(), new ManaCostsImpl("{2}{U}{U}")); @@ -83,33 +83,20 @@ class BrowseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - - if (player != null) { - Cards cards = new CardsImpl(); - int cardsCount = Math.min(5, player.getLibrary().size()); - for (int i = 0; i < cardsCount; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - } - } - + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5)); if (!cards.isEmpty()) { - player.lookAtCards("Browse", cards, game); - + controller.lookAtCards(source, null, cards, game); TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put in your hand")); - if (player.choose(Outcome.Benefit, cards, target, game)) { + if (controller.choose(Outcome.Benefit, cards, target, game)) { Card card = cards.get(target.getFirstTarget(), game); if (card != null) { - card.moveToZone(Zone.HAND, source.getSourceId(), game, false); + controller.moveCards(card, Zone.HAND, source, game); cards.remove(card); } } - - for (Card card : cards.getCards(game)) { - card.moveToExile(null, null, source.getSourceId(), game); - } + controller.moveCards(cards, Zone.EXILED, source, game); } return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java index 7ada58cf61a..75c5b5f59f8 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java +++ b/Mage.Sets/src/mage/cards/c/ChandraPyromaster.java @@ -205,7 +205,7 @@ class ChandraPyromasterEffect2 extends OneShotEffect { MageObject sourceObject = source.getSourceObject(game); if (controller != null && sourceObject != null && controller.getLibrary().hasCards()) { Library library = controller.getLibrary(); - Card card = library.removeFromTop(game); + Card card = library.getFromTop(game); if (card != null) { controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName() + " ", source.getSourceId(), game, Zone.LIBRARY, true); game.addEffect(new ChandraPyromasterPlayEffect(new MageObjectReference(card, game)), source); diff --git a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java index 8da3349e7eb..f9d39b82eea 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java +++ b/Mage.Sets/src/mage/cards/c/ChaosHarlequin.java @@ -38,9 +38,9 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -52,7 +52,7 @@ import mage.players.Player; public class ChaosHarlequin extends CardImpl { public ChaosHarlequin(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); this.subtype.add(SubType.HUMAN); this.power = new MageInt(2); this.toughness = new MageInt(4); @@ -91,7 +91,7 @@ class ChaosHarlequinEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); if (player != null) { - Card card = player.getLibrary().removeFromTop(game); + Card card = player.getLibrary().getFromTop(game); if (card != null) { player.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY, true); if (card.isLand()) { diff --git a/Mage.Sets/src/mage/cards/c/CloneShell.java b/Mage.Sets/src/mage/cards/c/CloneShell.java index 8d6ae28ee91..cf0c4c95531 100644 --- a/Mage.Sets/src/mage/cards/c/CloneShell.java +++ b/Mage.Sets/src/mage/cards/c/CloneShell.java @@ -36,14 +36,15 @@ import mage.abilities.common.EntersBattlefieldTriggeredAbility; 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.Zone; import mage.filter.FilterCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetCard; +import mage.util.CardUtil; /** * @author nantuko @@ -51,7 +52,7 @@ import mage.target.TargetCard; public class CloneShell extends CardImpl { public CloneShell(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}"); this.subtype.add(SubType.SHAPESHIFTER); this.power = new MageInt(2); @@ -90,48 +91,28 @@ class CloneShellEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Cards cards = new CardsImpl(); - int count = Math.min(player.getLibrary().size(), 4); - for (int i = 0; i < count; i++) { - Card card = player.getLibrary().removeFromTop(game); - cards.add(card); - } - - if (cards.isEmpty()) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { return false; - } - TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1); - if (player.choose(Outcome.Detriment, cards, target1, game)) { - Card card = cards.get(target1.getFirstTarget(), game); - if (card != null) { - cards.remove(card); - card.moveToExile(getId(), "Clone Shell (Imprint)", source.getSourceId(), game); - card.setFaceDown(true, game); - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null) { - permanent.imprint(card.getId(), game); - } - } - target1.clearChosen(); - } - + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 4)); if (!cards.isEmpty()) { - TargetCard target2 = new TargetCard(Zone.LIBRARY, filter2); - while (player.canRespond() && cards.size() > 1) { - player.choose(Outcome.Benefit, cards, target2, game); - Card card = cards.get(target2.getFirstTarget(), game); + TargetCard target1 = new TargetCard(Zone.LIBRARY, filter1); + if (controller.choose(Outcome.Detriment, cards, target1, game)) { + Card card = cards.get(target1.getFirstTarget(), game); if (card != null) { cards.remove(card); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false); + controller.moveCardsToExile(card, source, game, false, CardUtil.getCardExileZoneId(game, source), CardUtil.createObjectRealtedWindowTitle(source, game, "(Imprint)")); + card.setFaceDown(true, game); + Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + if (permanent != null) { + permanent.imprint(card.getId(), game); + } } - target2.clearChosen(); + target1.clearChosen(); } - Card card = cards.get(cards.iterator().next(), game); - card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); } - return true; } diff --git a/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java index 6b1aba598f5..89d26739faa 100644 --- a/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java +++ b/Mage.Sets/src/mage/cards/c/ColfenorsPlans.java @@ -39,6 +39,8 @@ import mage.abilities.effects.common.continuous.CantCastMoreThanOneSpellEffect; 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.game.ExileZone; import mage.game.Game; @@ -92,13 +94,16 @@ class ColfenorsPlansExileEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null && sourceObject != null) { - for (int i = 0; i < 7; i++) { - Card card = player.getLibrary().removeFromTop(game); - if (card != null) { - if (player.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true)) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards toExile = new CardsImpl(controller.getLibrary().getTopCards(game, 7)); + UUID exileId = CardUtil.getCardExileZoneId(game, source); + controller.moveCardsToExile(toExile.getCards(game), source, game, false, + exileId, CardUtil.createObjectRealtedWindowTitle(source, game, null)); + ExileZone exileZone = game.getExile().getExileZone(exileId); + if (exileZone != null) { + for (Card card : exileZone.getCards(game)) { + if (card != null) { card.setFaceDown(true, game); } } @@ -137,10 +142,9 @@ class ColfenorsPlansPlayCardEffect extends AsThoughEffectImpl { @Override public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) { - Card card = game.getCard(objectId); - if (affectedControllerId.equals(source.getControllerId()) && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { + if (affectedControllerId.equals(source.getControllerId()) && game.getState().getZone(objectId) == Zone.EXILED) { ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); - return zone != null && zone.contains(card.getId()); + return zone != null && zone.contains(objectId); } return false; } diff --git a/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java b/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java index 7bdb9385a78..c2bdbb97df8 100644 --- a/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java +++ b/Mage.Sets/src/mage/cards/c/CommuneWithTheGods.java @@ -28,7 +28,6 @@ package mage.cards.c; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.*; @@ -49,7 +48,7 @@ import mage.target.TargetCard; public class CommuneWithTheGods extends CardImpl { public CommuneWithTheGods(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{G}"); // Reveal the top five cards of your library. You may put a creature or enchantment card from among them into your hand. Put the rest into your graveyard. this.getSpellAbility().addEffect(new CommuneWithTheGodsEffect()); @@ -68,11 +67,6 @@ public class CommuneWithTheGods extends CardImpl { class CommuneWithTheGodsEffect extends OneShotEffect { - private static final FilterCard filterPutInHand = new FilterCard("creature or enchantment card to put in hand"); - static { - filterPutInHand.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ENCHANTMENT))); - } - public CommuneWithTheGodsEffect() { super(Outcome.DrawCard); this.staticText = "Reveal the top five cards of your library. You may put a creature or enchantment card from among them into your hand. Put the rest into your graveyard"; @@ -90,32 +84,22 @@ class CommuneWithTheGodsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - MageObject sourceObject = game.getObject(source.getSourceId()); - if (sourceObject != null && controller != null) { - Cards cards = new CardsImpl(); - - boolean properCardFound = false; - int count = Math.min(controller.getLibrary().size(), 5); - for (int i = 0; i < count; i++) { - Card card = controller.getLibrary().removeFromTop(game); - if (card != null) { - cards.add(card); - if (filterPutInHand.match(card, source.getSourceId(), source.getControllerId(), game)) { - properCardFound = true; - } - } - } - + if (controller != null) { + Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5)); if (!cards.isEmpty()) { - controller.revealCards(sourceObject.getName(), cards, game); - TargetCard target = new TargetCard(0, 1, Zone.LIBRARY, filterPutInHand); - if (properCardFound && controller.choose(Outcome.DrawCard, cards, target, game)) { - Card card = game.getCard(target.getFirstTarget()); - if (card != null) { - cards.remove(card); - controller.moveCards(card, Zone.HAND, source, game); - } + FilterCard filterPutInHand = new FilterCard("creature or enchantment card to put in hand"); + filterPutInHand.add(Predicates.or(new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.ENCHANTMENT))); + controller.revealCards(source, cards, game); + if (cards.count(filterPutInHand, source.getSourceId(), source.getControllerId(), game) > 0) { + TargetCard target = new TargetCard(0, 1, Zone.LIBRARY, filterPutInHand); + if (controller.choose(Outcome.DrawCard, cards, target, game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + cards.remove(card); + controller.moveCards(card, Zone.HAND, source, game); + } + } } controller.moveCards(cards, Zone.GRAVEYARD, source, game); } diff --git a/Mage.Sets/src/mage/cards/c/ConsumingAberration.java b/Mage.Sets/src/mage/cards/c/ConsumingAberration.java index 7ee94832c60..574fbf23ab1 100644 --- a/Mage.Sets/src/mage/cards/c/ConsumingAberration.java +++ b/Mage.Sets/src/mage/cards/c/ConsumingAberration.java @@ -38,9 +38,9 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect; import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.game.Game; import mage.players.Player; @@ -52,11 +52,10 @@ import mage.players.Player; public class ConsumingAberration extends CardImpl { public ConsumingAberration(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}"); + this.subtype.add(SubType.HORROR); - this.power = new MageInt(0); this.toughness = new MageInt(0); @@ -76,7 +75,6 @@ public class ConsumingAberration extends CardImpl { } } - class ConsumingAberrationEffect extends OneShotEffect { public ConsumingAberrationEffect() { @@ -100,33 +98,32 @@ class ConsumingAberrationEffect extends OneShotEffect { if (player == null) { continue; } - Cards cards = new CardsImpl(); - while(player.getLibrary().hasCards()){ - Card card = player.getLibrary().removeFromTop(game); + for (Card card : player.getLibrary().getCards(game)) { if (card != null) { cards.add(card); - if(card.isLand()){ + if (card.isLand()) { break; } } } - player.revealCards("Consuming Aberrtion", cards, game); + player.revealCards(source, cards, game); player.moveCards(cards, Zone.GRAVEYARD, source, game); } return true; } } - class CardsInOpponentsGraveyardsCount implements DynamicValue { - public CardsInOpponentsGraveyardsCount(){ + public CardsInOpponentsGraveyardsCount() { super(); } - public CardsInOpponentsGraveyardsCount(DynamicValue count){ + + public CardsInOpponentsGraveyardsCount(DynamicValue count) { super(); } + @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { int amount = 0; diff --git a/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java b/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java index 37279502a92..9cc733409bb 100644 --- a/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java +++ b/Mage.Sets/src/mage/cards/c/ConundrumSphinx.java @@ -107,10 +107,10 @@ class ConundrumSphinxEffect extends OneShotEffect { } String cardName = cardChoice.getChoice(); game.informPlayers(sourceObject.getLogName() + ", player: " + player.getLogName() + ", named: [" + cardName + ']'); - Card card = player.getLibrary().removeFromTop(game); + Card card = player.getLibrary().getFromTop(game); if (card != null) { Cards cards = new CardsImpl(card); - player.revealCards(sourceObject.getIdName(), cards, game); + player.revealCards(source, player.getName(), cards, game); if (card.getName().equals(cardName)) { player.moveCards(cards, Zone.HAND, source, game); } else { diff --git a/Mage.Sets/src/mage/cards/c/CountrysideCrusher.java b/Mage.Sets/src/mage/cards/c/CountrysideCrusher.java index 954851fb495..b526c7e1c75 100644 --- a/Mage.Sets/src/mage/cards/c/CountrysideCrusher.java +++ b/Mage.Sets/src/mage/cards/c/CountrysideCrusher.java @@ -36,8 +36,8 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; 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.counters.CounterType; @@ -53,7 +53,7 @@ import mage.players.Player; public class CountrysideCrusher extends CardImpl { public CountrysideCrusher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); this.subtype.add(SubType.GIANT); this.subtype.add(SubType.WARRIOR); @@ -102,8 +102,7 @@ class CountrysideCrusherEffect extends OneShotEffect { Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); if (controller != null && sourcePermanent != null) { Cards cards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().getFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { cards.add(card); if (card.isLand()) { controller.moveCards(card, Zone.GRAVEYARD, source, game); diff --git a/Mage.Sets/src/mage/cards/d/DemonicConsultation.java b/Mage.Sets/src/mage/cards/d/DemonicConsultation.java index 1be6c39d27b..948756c63c5 100644 --- a/Mage.Sets/src/mage/cards/d/DemonicConsultation.java +++ b/Mage.Sets/src/mage/cards/d/DemonicConsultation.java @@ -100,8 +100,7 @@ class DemonicConsultationEffect extends OneShotEffect { // then reveal cards from the top of your library until you reveal the named card. Cards cardsToReaveal = new CardsImpl(); Card cardToHand = null; - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { cardsToReaveal.add(card); // Put that card into your hand diff --git a/Mage.Sets/src/mage/cards/d/DiviningWitch.java b/Mage.Sets/src/mage/cards/d/DiviningWitch.java index bf003028bb5..10ca9ae2321 100644 --- a/Mage.Sets/src/mage/cards/d/DiviningWitch.java +++ b/Mage.Sets/src/mage/cards/d/DiviningWitch.java @@ -114,8 +114,7 @@ public class DiviningWitch extends CardImpl { // then reveal cards from the top of your library until you reveal the named card. Cards cardsToReaveal = new CardsImpl(); Card cardToHand = null; - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { cardsToReaveal.add(card); // Put that card into your hand diff --git a/Mage.Sets/src/mage/cards/f/FathomTrawl.java b/Mage.Sets/src/mage/cards/f/FathomTrawl.java index 769f34586b7..6287eff1d0a 100644 --- a/Mage.Sets/src/mage/cards/f/FathomTrawl.java +++ b/Mage.Sets/src/mage/cards/f/FathomTrawl.java @@ -45,7 +45,7 @@ import mage.players.Player; public class FathomTrawl extends CardImpl { public FathomTrawl(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}"); // Reveal cards from the top of your library until you reveal three nonland cards. Put the nonland cards revealed this way into your hand, then put the rest of the revealed cards on the bottom of your library in any order. this.getSpellAbility().addEffect(new FathomTrawlEffect()); @@ -86,8 +86,7 @@ public class FathomTrawl extends CardImpl { Cards cards = new CardsImpl(); Cards nonlandCards = new CardsImpl(); Cards landCards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { cards.add(card); if (!card.isLand()) { diff --git a/Mage.Sets/src/mage/cards/g/GoblinCharbelcher.java b/Mage.Sets/src/mage/cards/g/GoblinCharbelcher.java index 3150d6d44f4..09a39b50e0e 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinCharbelcher.java +++ b/Mage.Sets/src/mage/cards/g/GoblinCharbelcher.java @@ -27,6 +27,7 @@ */ package mage.cards.g; +import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -43,8 +44,6 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetAnyTarget; -import java.util.UUID; - /** * * @author Plopman @@ -52,7 +51,7 @@ import java.util.UUID; public class GoblinCharbelcher extends CardImpl { public GoblinCharbelcher(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); // {3}, {tap}: Reveal cards from the top of your library until you reveal a land card. Goblin Charbelcher deals damage equal to the number of nonland cards revealed this way to any target. If the revealed land card was a Mountain, Goblin Charbelcher deals double that damage instead. Put the revealed cards on the bottom of your library in any order. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinCharbelcherEffect(), new ManaCostsImpl("{3}")); @@ -97,13 +96,12 @@ class GoblinCharbelcherEffect extends OneShotEffect { } Cards cards = new CardsImpl(); boolean landFound = false; - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { cards.add(card); - if (card.isLand()){ + if (card.isLand()) { landFound = true; - if(card.hasSubtype(SubType.MOUNTAIN, game)){ + if (card.hasSubtype(SubType.MOUNTAIN, game)) { isMountain = true; } break; @@ -118,20 +116,19 @@ class GoblinCharbelcherEffect extends OneShotEffect { if (landFound) { damage--; } - if(isMountain){ + if (isMountain) { damage *= 2; } - + Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source)); if (permanent != null) { permanent.damage(damage, source.getSourceId(), game, false, true); - } - else{ + } else { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); if (targetPlayer != null) { targetPlayer.damage(damage, source.getSourceId(), game, false, true); } - } + } controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } diff --git a/Mage.Sets/src/mage/cards/h/HeirloomBlade.java b/Mage.Sets/src/mage/cards/h/HeirloomBlade.java index d268f73c285..35bb0d1db1f 100644 --- a/Mage.Sets/src/mage/cards/h/HeirloomBlade.java +++ b/Mage.Sets/src/mage/cards/h/HeirloomBlade.java @@ -60,8 +60,8 @@ public class HeirloomBlade extends CardImpl { // Equipped creature gets +3/+1. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(3, 1))); - - // Whenever equipped creature dies, you may reveal cards from the top of your library until you reveal a creature card that shares a creature type with it. + + // Whenever equipped creature dies, you may reveal cards from the top of your library until you reveal a creature card that shares a creature type with it. // Put that card into your hand and the rest on the bottom of your library in a random order. this.addAbility(new DiesAttachedTriggeredAbility(new HeirloomBladeEffect(), "equipped creature", true)); @@ -106,8 +106,7 @@ class HeirloomBladeEffect extends OneShotEffect { if (equipped != null) { Cards revealed = new CardsImpl(); Cards otherCards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { revealed.add(card); if (card != null && card.isCreature() && equipped.shareSubtypes(card, game)) { controller.moveCardToHandWithInfo(card, source.getSourceId(), game, true); diff --git a/Mage.Sets/src/mage/cards/o/OathOfDruids.java b/Mage.Sets/src/mage/cards/o/OathOfDruids.java index 8b4566fe658..804b8043e53 100644 --- a/Mage.Sets/src/mage/cards/o/OathOfDruids.java +++ b/Mage.Sets/src/mage/cards/o/OathOfDruids.java @@ -28,7 +28,6 @@ package mage.cards.o; import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -65,7 +64,9 @@ public class OathOfDruids extends CardImpl { public OathOfDruids(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); - // At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is their opponent. The first player may reveal cards from the top of their library until he or she reveals a creature card. If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into their graveyard. + // At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is their opponent. + // The first player may reveal cards from the top of their library until he or she reveals a creature card. + // If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into their graveyard. Ability ability = new BeginningOfUpkeepTriggeredAbility(new OathOfDruidsEffect(), TargetController.ANY, false); ability.addTarget(new TargetPlayer(1, 1, false, filter)); originalId = ability.getOriginalId(); @@ -78,8 +79,6 @@ public class OathOfDruids extends CardImpl { Player activePlayer = game.getPlayer(game.getActivePlayerId()); if (activePlayer != null) { ability.getTargets().clear(); -// FilterPlayer filter = new FilterPlayer(); -// filter.add(new OathOfDruidsPredicate()); TargetPlayer target = new TargetPlayer(1, 1, false, filter); target.setTargetController(activePlayer.getId()); ability.getTargets().add(target); @@ -140,36 +139,35 @@ class OathOfDruidsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject sourceObject = game.getObject(source.getSourceId()); - Player player = game.getPlayer(game.getActivePlayerId()); - if (player == null || sourceObject == null) { + Player controller = game.getPlayer(game.getActivePlayerId()); + if (controller == null) { return false; } Cards revealed = new CardsImpl(); - Card creatureCard = null; - Cards nonCreatureCards = new CardsImpl(); - if (!player.chooseUse(Outcome.Benefit, "Use this ability?", source, game)) { + Card selectedCard = null; + Cards notSelectedCards = new CardsImpl(); + if (!controller.chooseUse(Outcome.Benefit, "Use this ability?", source, game)) { return true; } //The first player may reveal cards from the top of their library - while (creatureCard == null && player.getLibrary().hasCards()) { - Card card = player.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { revealed.add(card); // until he or she reveals a creature card. if (card.isCreature()) { - creatureCard = card; + selectedCard = card; + break; } else { - nonCreatureCards.add(card); + notSelectedCards.add(card); } } - player.revealCards(sourceObject.getIdName(), revealed, game); + controller.revealCards(source, revealed, game); //If he or she does, that player puts that card onto the battlefield - if (creatureCard != null) { - player.moveCards(creatureCard, Zone.BATTLEFIELD, source, game); + if (selectedCard != null) { + controller.moveCards(selectedCard, Zone.BATTLEFIELD, source, game); } // and all other cards revealed this way into their graveyard - player.moveCards(nonCreatureCards, Zone.GRAVEYARD, source, game); + controller.moveCards(notSelectedCards, Zone.GRAVEYARD, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/p/ProteusStaff.java b/Mage.Sets/src/mage/cards/p/ProteusStaff.java index eedabc15e84..93c38536a18 100644 --- a/Mage.Sets/src/mage/cards/p/ProteusStaff.java +++ b/Mage.Sets/src/mage/cards/p/ProteusStaff.java @@ -102,8 +102,7 @@ class ProteusStaffEffect extends OneShotEffect { // That creature's controller reveals cards from the top of their library until he or she reveals a creature card. Cards cards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { if (card.isCreature()) { // The player puts that card onto the battlefield diff --git a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java index ff278dab8c2..b4b485d6317 100644 --- a/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java +++ b/Mage.Sets/src/mage/cards/r/RiptideShapeshifter.java @@ -100,8 +100,7 @@ class RiptideShapeshifterEffect extends OneShotEffect { return false; } Cards revealedCards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card.isCreature() && card.hasSubtype(SubType.byDescription(choice.getChoice()), game)) { controller.moveCards(card, Zone.BATTLEFIELD, source, game); break; diff --git a/Mage.Sets/src/mage/cards/s/ShiftingShadow.java b/Mage.Sets/src/mage/cards/s/ShiftingShadow.java index 8a0e0bfc9ad..abd6d679b0f 100644 --- a/Mage.Sets/src/mage/cards/s/ShiftingShadow.java +++ b/Mage.Sets/src/mage/cards/s/ShiftingShadow.java @@ -73,8 +73,8 @@ public class ShiftingShadow extends CardImpl { this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); this.addAbility(new EnchantAbility(auraTarget.getTargetName())); - - // Enchanted creature has haste and “At the beginning of your upkeep, destroy this creature. Reveal cards from the top of your library until you reveal a creature card. + + // Enchanted creature has haste and “At the beginning of your upkeep, destroy this creature. Reveal cards from the top of your library until you reveal a creature card. // Put that card onto the battlefield and attach Shifting Shadow to it, then put all other cards revealed this way on the bottom of your library in a random order.” Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(HasteAbility.getInstance(), AttachmentType.AURA)); Effect effect = new GainAbilityAttachedEffect(new BeginningOfUpkeepTriggeredAbility( @@ -135,11 +135,10 @@ class ShiftingShadowEffect extends OneShotEffect { enchanted.destroy(source.getSourceId(), game, false); Cards revealed = new CardsImpl(); Cards otherCards = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { revealed.add(card); if (card != null && card.isCreature()) { - card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), controller.getId()); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); Permanent newEnchanted = game.getPermanent(card.getId()); FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); filter.add(new PermanentIdPredicate(card.getId())); diff --git a/Mage.Sets/src/mage/cards/s/SpoilsOfTheVault.java b/Mage.Sets/src/mage/cards/s/SpoilsOfTheVault.java index c0aaa9537ac..624c5cea3ef 100644 --- a/Mage.Sets/src/mage/cards/s/SpoilsOfTheVault.java +++ b/Mage.Sets/src/mage/cards/s/SpoilsOfTheVault.java @@ -50,7 +50,7 @@ import mage.players.Player; public class SpoilsOfTheVault extends CardImpl { public SpoilsOfTheVault(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{B}"); + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}"); // Name a card. Reveal cards from the top of your library until you reveal the named card, then put that card into your hand. Exile all other cards revealed this way, and you lose 1 life for each of the exiled cards. this.getSpellAbility().addEffect(new NameACardEffect(NameACardEffect.TypeOfName.ALL)); @@ -94,8 +94,7 @@ class SpoilsOfTheVaultEffect extends OneShotEffect { Cards cardsToReveal = new CardsImpl(); Cards cardsToExile = new CardsImpl(); - while (controller.getLibrary().hasCards()) { - Card card = controller.getLibrary().removeFromTop(game); + for (Card card : controller.getLibrary().getCards(game)) { if (card != null) { cardsToReveal.add(card); if (card.getName().equals(cardName)) { 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 79cf55db7f8..b81671cfc68 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 @@ -1473,21 +1473,41 @@ public class TestPlayer implements Player { computerPlayer.shuffleLibrary(source, game); } + @Override + public void revealCards(Ability source, Cards cards, Game game) { + computerPlayer.revealCards(source, cards, game); + } + @Override public void revealCards(String name, Cards cards, Game game) { computerPlayer.revealCards(name, cards, game); } + @Override + public void revealCards(Ability source, String name, Cards cards, Game game) { + computerPlayer.revealCards(name, cards, game); + } + @Override public void revealCards(String name, Cards cards, Game game, boolean postToLog) { computerPlayer.revealCards(name, cards, game, postToLog); } + @Override + public void revealCards(Ability source, String name, Cards cards, Game game, boolean postToLog) { + computerPlayer.revealCards(name, cards, game, postToLog); + } + @Override public void lookAtCards(String name, Cards cards, Game game) { computerPlayer.lookAtCards(name, cards, game); } + @Override + public void lookAtCards(Ability source, String name, Cards cards, Game game) { + computerPlayer.lookAtCards(source, name, cards, game); + } + @Override public void lookAtCards(String name, Card card, Game game) { computerPlayer.lookAtCards(name, card, game); 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 7eebfc498a8..ca01958cb61 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 @@ -758,16 +758,31 @@ public class PlayerStub implements Player { } + @Override + public void revealCards(Ability source, Cards cards, Game game) { + + } + @Override public void revealCards(String name, Cards cards, Game game) { } + @Override + public void revealCards(Ability source, String name, Cards cards, Game game) { + + } + @Override public void revealCards(String name, Cards cards, Game game, boolean postToLog) { } + @Override + public void revealCards(Ability source, String name, Cards cards, Game game, boolean postToLog) { + + } + @Override public void lookAtCards(String name, Card card, Game game) { @@ -778,6 +793,11 @@ public class PlayerStub implements Player { } + @Override + public void lookAtCards(Ability source, String name, Cards cards, Game game) { + + } + @Override public Player copy() { return null; diff --git a/Mage/src/main/java/mage/cards/CardsImpl.java b/Mage/src/main/java/mage/cards/CardsImpl.java index 473021c2751..3174bfdc00f 100644 --- a/Mage/src/main/java/mage/cards/CardsImpl.java +++ b/Mage/src/main/java/mage/cards/CardsImpl.java @@ -54,6 +54,12 @@ public class CardsImpl extends LinkedHashSet implements Cards, Serializabl } } + public CardsImpl(Set cards) { + for (Card card : cards) { + this.add(card.getId()); + } + } + public CardsImpl(Collection cardIds) { if (cardIds != null) { this.addAll(cardIds); diff --git a/Mage/src/main/java/mage/players/Library.java b/Mage/src/main/java/mage/players/Library.java index 61c4734a68f..77b816948f9 100644 --- a/Mage/src/main/java/mage/players/Library.java +++ b/Mage/src/main/java/mage/players/Library.java @@ -136,24 +136,26 @@ public class Library implements Serializable { } public void putCardThirdFromTheTop(Card card, Game game) { - if (card != null && card.getOwnerId().equals(playerId)) { - Card cardTop = null; - Card cardSecond = null; - if (hasCards()) { - cardTop = removeFromTop(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); } - 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); } } @@ -190,6 +192,12 @@ public class Library implements Serializable { return new ArrayList<>(library); } + /** + * Returns the cards of the library in a list ordered from top to buttom + * + * @param game + * @return + */ public List getCards(Game game) { return library.stream().map(game::getCard).collect(Collectors.toList()); } diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index 83d698dafba..b08e8e8c410 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -474,14 +474,41 @@ public interface Player extends MageItem, Copyable { void resetStoredBookmark(Game game); + void revealCards(Ability source, Cards cards, Game game); + void revealCards(String name, Cards cards, Game game); + void revealCards(Ability source, String name, Cards cards, Game game); + void revealCards(String name, Cards cards, Game game, boolean postToLog); + /** + * Adds the cards to the reveal window and adds the source object's id name + * to the title bar of the revealed cards window + * + * @param source + * @param name + * @param cards + * @param game + * @param postToLog + */ + void revealCards(Ability source, String name, Cards cards, Game game, boolean postToLog); + void lookAtCards(String name, Card card, Game game); void lookAtCards(String name, Cards cards, Game game); + /** + * Adds the cards to the look window and adds the source object's id name to + * the title bar of the lookedAt window + * + * @param source + * @param name + * @param cards + * @param game + */ + void lookAtCards(Ability source, String name, Cards cards, Game game); + @Override Player copy(); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 307fc1d5272..9fd608468ca 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -1474,16 +1474,34 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public void revealCards(String name, Cards cards, Game game) { - revealCards(name, cards, game, true); + public void revealCards(Ability source, Cards cards, Game game) { + revealCards(source, null, cards, game, true); } @Override - public void revealCards(String name, Cards cards, Game game, boolean postToLog) { + public void revealCards(String titleSuffix, Cards cards, Game game) { + revealCards(titleSuffix, cards, game, true); + } + + @Override + public void revealCards(String titleSuffix, Cards cards, Game game, boolean postToLog) { + revealCards(null, titleSuffix, cards, game, postToLog); + } + + @Override + public void revealCards(Ability source, String titleSuffix, Cards cards, Game game) { + revealCards(source, titleSuffix, cards, game, true); + } + + @Override + public void revealCards(Ability source, String titleSuffix, Cards cards, Game game, boolean postToLog) { + if (cards == null || cards.isEmpty()) { + return; + } if (postToLog) { - game.getState().getRevealed().add(name, cards); + game.getState().getRevealed().add(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards); } else { - game.getState().getRevealed().update(name, cards); + game.getState().getRevealed().update(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards); } if (postToLog && !game.isSimulation()) { StringBuilder sb = new StringBuilder(getLogName()).append(" reveals "); @@ -1500,14 +1518,19 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public void lookAtCards(String name, Card card, Game game) { - game.getState().getLookedAt(this.playerId).add(name, card); + public void lookAtCards(String titleSuffix, Card card, Game game) { + game.getState().getLookedAt(this.playerId).add(titleSuffix, card); game.fireUpdatePlayersEvent(); } @Override - public void lookAtCards(String name, Cards cards, Game game) { - game.getState().getLookedAt(this.playerId).add(name, cards); + public void lookAtCards(String titleSuffix, Cards cards, Game game) { + this.lookAtCards(null, titleSuffix, cards, game); + } + + @Override + public void lookAtCards(Ability source, String titleSuffix, Cards cards, Game game) { + game.getState().getLookedAt(this.playerId).add(CardUtil.createObjectRealtedWindowTitle(source, game, titleSuffix), cards); game.fireUpdatePlayersEvent(); } diff --git a/Mage/src/main/java/mage/target/targetpointer/FixedTargets.java b/Mage/src/main/java/mage/target/targetpointer/FixedTargets.java index e220491074e..f4ca2f05c36 100644 --- a/Mage/src/main/java/mage/target/targetpointer/FixedTargets.java +++ b/Mage/src/main/java/mage/target/targetpointer/FixedTargets.java @@ -7,9 +7,11 @@ package mage.target.targetpointer; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.UUID; import mage.MageObjectReference; import mage.abilities.Ability; +import mage.cards.Card; import mage.cards.Cards; import mage.game.Game; import mage.game.permanent.Permanent; @@ -46,6 +48,14 @@ public class FixedTargets implements TargetPointer { this.initialized = true; } + public FixedTargets(Set cards, Game game) { + for (Card card : cards) { + MageObjectReference mor = new MageObjectReference(card.getId(), card.getZoneChangeCounter(game), game); + targets.add(mor); + } + this.initialized = true; + } + private FixedTargets(final FixedTargets fixedTargets) { this.targets.addAll(fixedTargets.targets); this.targetsNotInitialized.addAll(fixedTargets.targetsNotInitialized); diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java index 930c3d2315c..7c636d2afe4 100644 --- a/Mage/src/main/java/mage/util/CardUtil.java +++ b/Mage/src/main/java/mage/util/CardUtil.java @@ -27,6 +27,7 @@ */ package mage.util; +import java.util.UUID; import mage.MageObject; import mage.Mana; import mage.abilities.Ability; @@ -37,22 +38,18 @@ import mage.abilities.costs.mana.*; import mage.cards.Card; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.Token; import mage.util.functions.CopyTokenFunction; -import java.util.UUID; - /** * @author nantuko */ public final class CardUtil { - private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone"; 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"}; + "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"}; /** * Increase spell or ability cost to be paid. @@ -133,7 +130,6 @@ public final class CardUtil { return adjustedCost; } - public static void reduceCost(SpellAbility spellAbility, ManaCosts manaCostsToReduce) { adjustCost(spellAbility, manaCostsToReduce, true); } @@ -154,8 +150,8 @@ public final class CardUtil { * * @param spellAbility * @param manaCostsToReduce costs to reduce - * @param convertToGeneric colored mana does reduce generic mana if no - * appropriate colored mana is in the costs included + * @param convertToGeneric colored mana does reduce generic mana if no + * appropriate colored mana is in the costs included */ public static void adjustCost(SpellAbility spellAbility, ManaCosts manaCostsToReduce, boolean convertToGeneric) { ManaCosts previousCost = spellAbility.getManaCostsToPay(); @@ -340,7 +336,7 @@ public final class CardUtil { * * @param number number to convert to text * @param forOne if the number is 1, this string will be returnedinstead of - * "one". + * "one". * @return */ public static String numberToText(int number, String forOne) { @@ -383,21 +379,22 @@ public final class CardUtil { return true; } - /** - * Parse card number as int (support base [123] and alternative numbers [123b]). + * Parse card number as int (support base [123] and alternative numbers + * [123b]). * * @param cardNumber origin card number * @return int */ - public static int parseCardNumberAsInt(String cardNumber){ + public static int parseCardNumberAsInt(String cardNumber) { - if (cardNumber.isEmpty()){ throw new IllegalArgumentException("Card number is empty.");} + if (cardNumber.isEmpty()) { + throw new IllegalArgumentException("Card number is empty."); + } - if(Character.isDigit(cardNumber.charAt(cardNumber.length() - 1))) - { + if (Character.isDigit(cardNumber.charAt(cardNumber.length() - 1))) { return Integer.parseInt(cardNumber); - }else{ + } else { return Integer.parseInt(cardNumber.substring(0, cardNumber.length() - 1)); } } @@ -405,7 +402,7 @@ public final class CardUtil { /** * Creates and saves a (card + zoneChangeCounter) specific exileId. * - * @param game the current game + * @param game the current game * @param source source ability * @return the specific UUID */ @@ -440,9 +437,9 @@ public final class CardUtil { * be specific to a permanent instance. So they won't match, if a permanent * was e.g. exiled and came back immediately. * - * @param text short value to describe the value + * @param text short value to describe the value * @param cardId id of the card - * @param game the game + * @param game the game * @return */ public static String getCardZoneString(String text, UUID cardId, Game game) { @@ -513,9 +510,9 @@ public final class CardUtil { public static int addWithOverflowCheck(int base, int increment) { long result = ((long) base) + increment; if (result > Integer.MAX_VALUE) { - return Integer.MAX_VALUE; + return Integer.MAX_VALUE; } else if (result < Integer.MIN_VALUE) { - return Integer.MIN_VALUE; + return Integer.MIN_VALUE; } return base + increment; } @@ -523,11 +520,28 @@ public final class CardUtil { public static int subtractWithOverflowCheck(int base, int decrement) { long result = ((long) base) - decrement; if (result > Integer.MAX_VALUE) { - return Integer.MAX_VALUE; + return Integer.MAX_VALUE; } else if (result < Integer.MIN_VALUE) { - return Integer.MIN_VALUE; + return Integer.MIN_VALUE; } return base - decrement; } + public static String createObjectRealtedWindowTitle(Ability source, Game game, String textSuffix) { + String title; + if (source != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null) { + title = sourceObject.getIdName() + + " [" + source.getSourceObjectZoneChangeCounter() + "]" + + (textSuffix == null ? "" : " " + textSuffix); + } else { + title = textSuffix == null ? "" : textSuffix; + } + } else { + title = textSuffix == null ? "" : textSuffix;; + } + return title; + + } }