diff --git a/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java b/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java index 6c0cd02e6ca..0e54ed691e5 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java +++ b/Mage.Sets/src/mage/sets/alarareborn/ThoughtHemorrhage.java @@ -38,9 +38,13 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; /** * @@ -102,23 +106,42 @@ class ThoughtHemorrhageEffect extends OneShotEffect { if (cardsFound > 0) { targetPlayer.damage(3 * cardsFound, source.getSourceId(), game, false, true); } - for (Card card : targetPlayer.getGraveyard().getCards(game)) { - if (card.getName().equals(cardName)) { - controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD); + // Exile all cards with the same name + // Building a card filter with the name + FilterCard filterNamedCards = new FilterCard(); + filterNamedCards.add(new NamePredicate(cardName)); + + // The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone. + // Finding those cards in the hand and library is optional, because those zones are hidden (even if the hand is temporarily revealed). + // search cards in graveyard + for (Card checkCard : targetPlayer.getGraveyard().getCards(game)) { + if (checkCard.getName().equals(cardName)) { + controller.moveCardToExileWithInfo(checkCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD); } } - for (Card card : targetPlayer.getHand().getCards(game)) { - if (card.getName().equals(cardName)) { + + // search cards in hand + TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game); + for(UUID cardId: targetCardsHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND); } } - for (Card card : targetPlayer.getLibrary().getCards(game)) { - if (card.getName().equals(cardName)) { + + // search cards in Library + // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. + TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); + controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); + for(UUID cardId: targetCardsLibrary.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); } } targetPlayer.shuffleLibrary(game); - return true; + return true; } } return false; diff --git a/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java b/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java index 7188e49d9ee..e2e38f88ebe 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/DescendantsPath.java @@ -102,7 +102,7 @@ class DescendantsPathEffect extends OneShotEffect { if (card.getCardType().contains(CardType.CREATURE)) { FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); - ArrayList> subtypes = new ArrayList>(); + ArrayList> subtypes = new ArrayList<>(); for (String subtype: card.getSubtype()) { subtypes.add(new SubtypePredicate(subtype)); } diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/ReapIntellect.java b/Mage.Sets/src/mage/sets/dragonsmaze/ReapIntellect.java index 38c09088c99..a290fd8f7e4 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/ReapIntellect.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/ReapIntellect.java @@ -27,25 +27,28 @@ */ package mage.sets.dragonsmaze; -import java.util.List; +import java.util.ArrayList; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.Cards; import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; import mage.players.Player; -import mage.target.TargetCard; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; /** @@ -79,10 +82,10 @@ public class ReapIntellect extends CardImpl { class ReapIntellectEffect extends OneShotEffect { - private static final FilterCard filter = new FilterCard("up to X nonland cards"); + private static final FilterCard filterNonLands = new FilterCard("up to X nonland cards"); static { - filter.add(Predicates.not(new CardTypePredicate(CardType.LAND))); + filterNonLands.add(Predicates.not(new CardTypePredicate(CardType.LAND))); } public ReapIntellectEffect() { @@ -96,67 +99,79 @@ class ReapIntellectEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Cards exiledCards = new CardsImpl(); Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player you = game.getPlayer(source.getControllerId()); - if (targetPlayer != null) { - targetPlayer.revealCards("Reap Intellect", targetPlayer.getHand(), game); - if (you != null) { - int xCost = Math.min(source.getManaCostsToPay().getX(), targetPlayer.getHand().size()); - TargetCard target = new TargetCard(0, xCost, Zone.PICK, filter); - target.setNotTarget(true); - if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { - for (UUID cardId : target.getTargets()) { - Card chosenCard = game.getCard(cardId); - if (chosenCard != null) { - if (chosenCard.moveToExile(source.getSourceId(), "Reap Intellect", source.getSourceId(), game)) { - exiledCards.add(chosenCard); - } - } - } - for (UUID cardId : exiledCards) { - if (cardId != null) { - Card card = game.getCard(cardId); - - // cards in Graveyard - Cards cardsInGraveyard = new CardsImpl(Zone.GRAVEYARD); - cardsInGraveyard.addAll(targetPlayer.getGraveyard()); - you.lookAtCards("Reap Intellect search of Graveyard", cardsInGraveyard, game); - - // cards in Hand - Cards cardsInHand = new CardsImpl(Zone.HAND); - cardsInHand.addAll(targetPlayer.getHand()); - you.lookAtCards("Reap Intellect search of Hand", cardsInHand, game); - - //cards in Library - Cards cardsInLibrary = new CardsImpl(Zone.LIBRARY); - cardsInLibrary.addAll(targetPlayer.getLibrary().getCards(game)); - you.lookAtCards("Reap Intellect search of Library", cardsInLibrary, game); - - // exile same named cards from zones - - for (Card checkCard : cardsInGraveyard.getCards(game)) { - if (checkCard.getName().equals(card.getName())) { - checkCard.moveToExile(source.getSourceId(), "Graveyard", source.getSourceId(), game); - } - } - for (Card checkCard : cardsInHand.getCards(game)) { - if (checkCard.getName().equals(card.getName())) { - checkCard.moveToExile(source.getSourceId(), "Hand", source.getSourceId(), game); - } - } - - for (Card checkCard : cardsInLibrary.getCards(game)) { - if (checkCard.getName().equals(card.getName())) { - checkCard.moveToExile(source.getSourceId(), "Library", source.getSourceId(), game); - } - } - } - } - targetPlayer.shuffleLibrary(game); - return true; - } + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (targetPlayer != null && sourceObject != null && controller != null) { + + // reveal hand of target player + targetPlayer.revealCards(sourceObject.getLogName(), targetPlayer.getHand(), game); + + // Chose cards to exile from hand + Cards exiledCards = new CardsImpl(); + int xCost = Math.min(source.getManaCostsToPay().getX(), targetPlayer.getHand().size()); + TargetCardInHand target = new TargetCardInHand(0, xCost, filterNonLands); + target.setNotTarget(true); + controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game); + for (UUID cardId : target.getTargets()) { + Card chosenCard = game.getCard(cardId); + if (chosenCard != null) { + controller.moveCardToExileWithInfo(chosenCard, null, "", source.getSourceId(), game, Zone.HAND); + exiledCards.add(chosenCard); + } } + // Exile other cards with the same name + // 4/15/2013 If you don't exile any cards from the player's hand, you don't search that player's library + if (!exiledCards.isEmpty()) { + + // Building a card filter with all names + ArrayList names = new ArrayList<>(); + FilterCard filterNamedCards = new FilterCard(); + for (Card card: exiledCards.getCards(game)) { + if (exiledCards.size() == 1) { + filterNamedCards.add(new NamePredicate(card.getName())); + } else { + names.add(new NamePredicate(card.getName())); + } + } + if (exiledCards.size() > 1) { + filterNamedCards.add(Predicates.or(names)); + } + + // search cards in graveyard + TargetCardInGraveyard targetCardsGraveyard = new TargetCardInGraveyard(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsGraveyard, source, game); + for(UUID cardId: targetCardsGraveyard.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.GRAVEYARD); + } + } + + // search cards in hand + TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game); + for(UUID cardId: targetCardsHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND); + } + } + + // search cards in Library + TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); + controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); + for(UUID cardId: targetCardsLibrary.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); + } + } + + } + + targetPlayer.shuffleLibrary(game); + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java b/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java index a5c4aa9640a..3ee7150fac2 100644 --- a/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java +++ b/Mage.Sets/src/mage/sets/magic2013/ShimianSpecter.java @@ -32,22 +32,24 @@ import java.util.UUID; import mage.constants.CardType; import mage.constants.Rarity; import mage.MageInt; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.NamePredicate; import mage.game.Game; import mage.players.Player; -import mage.target.TargetCard; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; /** * @@ -100,53 +102,67 @@ class ShimianSpecterEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - Player you = game.getPlayer(source.getControllerId()); - if (damagedPlayer != null && you != null) { - damagedPlayer.revealCards("Shimian Specter", damagedPlayer.getHand(), game); - - TargetCard target = new TargetCard(Zone.PICK, filter); + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (targetPlayer != null && sourceObject != null && controller != null) { + + // reveal hand of target player + targetPlayer.revealCards(sourceObject.getLogName(), targetPlayer.getHand(), game); + + // You choose a nonland card from it + TargetCardInHand target = new TargetCardInHand(new FilterNonlandCard()); target.setNotTarget(true); - if (you.choose(Outcome.Benefit, damagedPlayer.getHand(), target, game)) { - Card chosenCard = damagedPlayer.getHand().get(target.getFirstTarget(), game); - if (chosenCard != null && damagedPlayer != null) { - - //cards in Library - Cards cardsInLibrary = new CardsImpl(Zone.LIBRARY); - cardsInLibrary.addAll(damagedPlayer.getLibrary().getCards(game)); - you.lookAtCards(damagedPlayer.getName() + ": cards in library", cardsInLibrary, game); - - // cards in Graveyard - Cards cardsInGraveyard = new CardsImpl(Zone.GRAVEYARD); - cardsInGraveyard.addAll(damagedPlayer.getGraveyard()); - - // cards in Hand - Cards cardsInHand = new CardsImpl(Zone.HAND); - cardsInHand.addAll(damagedPlayer.getHand()); - you.lookAtCards(damagedPlayer.getName() + ": cards in hand", cardsInHand, game); - - // exile same named cards from zones - for (Card checkCard : cardsInLibrary.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Library", id, game); - } - } - for (Card checkCard : cardsInGraveyard.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Graveyard", id, game); - } - } - for (Card checkCard : cardsInHand.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Hand", id, game); - } - } - - damagedPlayer.shuffleLibrary(game); - - return true; - } + Card chosenCard = null; + if (controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { + chosenCard = game.getCard(target.getFirstTarget()); } + + + // Exile all cards with the same name + // Building a card filter with the name + FilterCard filterNamedCards = new FilterCard(); + if (chosenCard != null) { + filterNamedCards.add(new NamePredicate(chosenCard.getName())); + } else { + filterNamedCards.add(new NamePredicate("----")); // so no card matches + } + + // The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone. + // Finding those cards in the hand and library is optional, because those zones are hidden (even if the hand is temporarily revealed). + // search cards in graveyard + if (chosenCard != null) { + for (Card checkCard : targetPlayer.getGraveyard().getCards(game)) { + if (checkCard.getName().equals(chosenCard.getName())) { + controller.moveCardToExileWithInfo(checkCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD); + } + } + + // search cards in hand + TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game); + for(UUID cardId: targetCardsHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND); + } + } + } + + // search cards in Library + // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. + if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", game)) { + TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); + controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); + for(UUID cardId: targetCardsLibrary.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); + } + } + targetPlayer.shuffleLibrary(game); + } + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/planarchaos/Extirpate.java b/Mage.Sets/src/mage/sets/planarchaos/Extirpate.java index 2809e2d5e11..5dbdc3327d2 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/Extirpate.java +++ b/Mage.Sets/src/mage/sets/planarchaos/Extirpate.java @@ -29,6 +29,7 @@ package mage.sets.planarchaos; import java.util.List; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.SplitSecondAbility; @@ -41,6 +42,7 @@ import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; @@ -103,74 +105,52 @@ class ExtirpateEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Card card = game.getCard(source.getFirstTarget()); - Player player = game.getPlayer(source.getControllerId()); - - if (card != null && player != null) { - Player targetPlayer = game.getPlayer(card.getOwnerId()); - if (targetPlayer != null) { - FilterCard filter = new FilterCard("card named " + card.getName()); - filter.add(new NamePredicate(card.getName())); - - Cards cardsInLibrary = new CardsImpl(Zone.LIBRARY); - cardsInLibrary.addAll(targetPlayer.getLibrary().getCards(game)); - - // cards in Graveyard - int cardsCount = targetPlayer.getGraveyard().count(filter, game); - if (cardsCount > 0) { - filter.setMessage("card named " + card.getName() + " in the graveyard of " + targetPlayer.getName()); - TargetCardInGraveyard target = new TargetCardInGraveyard(0, cardsCount, filter); - if (player.choose(Outcome.Exile, targetPlayer.getGraveyard(), target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card targetCard = targetPlayer.getGraveyard().get(targetId, game); - if (targetCard != null) { - player.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.GRAVEYARD); - } - } - } - } - - // cards in Hand - cardsCount = targetPlayer.getHand().count(filter, game); - if (cardsCount > 0) { - filter.setMessage("card named " + card.getName() + " in the hand of " + targetPlayer.getName()); - TargetCardInHand target = new TargetCardInHand(0, cardsCount, filter); - if (player.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card targetCard = targetPlayer.getHand().get(targetId, game); - if (targetCard != null) { - player.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.HAND); - } - } - } - } else { - player.lookAtCards(targetPlayer.getName() + " hand", targetPlayer.getHand(), game); - } - - // cards in Library - cardsCount = cardsInLibrary.count(filter, game); - if (cardsCount > 0) { - filter.setMessage("card named " + card.getName() + " in the library of " + targetPlayer.getName()); - TargetCardInLibrary target = new TargetCardInLibrary(0, cardsCount, filter); - if (player.choose(Outcome.Exile, cardsInLibrary, target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card targetCard = targetPlayer.getLibrary().remove(targetId, game); - if (targetCard != null) { - player.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.LIBRARY); - } - } - } - } else { - player.lookAtCards(targetPlayer.getName() + " library", cardsInLibrary, game); - } - targetPlayer.shuffleLibrary(game); - return true; + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + Card chosenCard = game.getCard(getTargetPointer().getFirst(game, source)); + if (chosenCard != null && sourceObject != null && controller != null) { + Player owner = game.getPlayer(chosenCard.getOwnerId()); + if (owner == null) { + return false; } - } + + // Exile all cards with the same name + // Building a card filter with the name + FilterCard filterNamedCards = new FilterCard(); + filterNamedCards.add(new NamePredicate(chosenCard.getName())); + // The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone. + // Finding those cards in the hand and library is optional, because those zones are hidden (even if the hand is temporarily revealed). + // search cards in graveyard + for (Card checkCard : owner.getGraveyard().getCards(game)) { + if (checkCard.getName().equals(chosenCard.getName())) { + controller.moveCardToExileWithInfo(checkCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD); + } + } + + // search cards in hand + TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, owner.getGraveyard(), targetCardsHand, source, game); + for(UUID cardId: targetCardsHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND); + } + } + + // search cards in Library + TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); + controller.searchLibrary(targetCardsLibrary, game, owner.getId()); + for(UUID cardId: targetCardsLibrary.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); + } + } + owner.shuffleLibrary(game); + return true; + } return false; } + } diff --git a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java index ad9241b3fee..ceea9b8a490 100644 --- a/Mage.Sets/src/mage/sets/tempest/Lobotomy.java +++ b/Mage.Sets/src/mage/sets/tempest/Lobotomy.java @@ -28,6 +28,7 @@ package mage.sets.tempest; import java.util.UUID; +import mage.MageObject; import mage.constants.CardType; import mage.constants.Rarity; @@ -40,12 +41,16 @@ import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.NamePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInLibrary; /** * @@ -95,56 +100,66 @@ class LobotomyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Player you = game.getPlayer(source.getControllerId()); - if (targetPlayer != null) { - targetPlayer.revealCards("Lobotomy", targetPlayer.getHand(), game); - if (you != null) { - TargetCard target = new TargetCard(Zone.PICK, filter); - target.setNotTarget(true); - if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { - Card chosenCard = targetPlayer.getHand().get(target.getFirstTarget(), game); - if (chosenCard != null) { - if (targetPlayer != null) { - - //cards in Library - Cards cardsInLibrary = new CardsImpl(Zone.LIBRARY); - cardsInLibrary.addAll(targetPlayer.getLibrary().getCards(game)); - you.lookAtCards("Lobotomy search of Library", cardsInLibrary, game); - - // cards in Graveyard - Cards cardsInGraveyard = new CardsImpl(Zone.GRAVEYARD); - cardsInGraveyard.addAll(targetPlayer.getGraveyard()); - - // cards in Hand - Cards cardsInHand = new CardsImpl(Zone.HAND); - cardsInHand.addAll(targetPlayer.getHand()); - you.lookAtCards("Lobotomy search of Hand", cardsInHand, game); - - // exile same named cards from zones - for (Card checkCard : cardsInLibrary.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Library", id, game); - } - } - for (Card checkCard : cardsInGraveyard.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Graveyard", id, game); - } - } - for (Card checkCard : cardsInHand.getCards(game)) { - if (checkCard.getName().equals(chosenCard.getName())) { - checkCard.moveToExile(id, "Hand", id, game); - } - } - - targetPlayer.shuffleLibrary(game); - - return true; - } - } - } + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (targetPlayer != null && sourceObject != null && controller != null) { + + // reveal hand of target player + targetPlayer.revealCards(sourceObject.getLogName(), targetPlayer.getHand(), game); + + // You choose a nonland card from it + TargetCardInHand target = new TargetCardInHand(new FilterNonlandCard()); + target.setNotTarget(true); + Card chosenCard = null; + if (controller.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { + chosenCard = game.getCard(target.getFirstTarget()); + } + + + // Exile all cards with the same name + // Building a card filter with the name + FilterCard filterNamedCards = new FilterCard(); + if (chosenCard != null) { + filterNamedCards.add(new NamePredicate(chosenCard.getName())); + } else { + filterNamedCards.add(new NamePredicate("----")); // so no card matches } + // The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone. + // Finding those cards in the hand and library is optional, because those zones are hidden (even if the hand is temporarily revealed). + // search cards in graveyard + if (chosenCard != null) { + for (Card checkCard : targetPlayer.getGraveyard().getCards(game)) { + if (checkCard.getName().equals(chosenCard.getName())) { + controller.moveCardToExileWithInfo(checkCard, null, "", source.getSourceId(), game, Zone.GRAVEYARD); + } + } + + // search cards in hand + TargetCardInHand targetCardsHand = new TargetCardInHand(0, Integer.MAX_VALUE, filterNamedCards); + controller.chooseTarget(outcome, targetPlayer.getGraveyard(), targetCardsHand, source, game); + for(UUID cardId: targetCardsHand.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.HAND); + } + } + } + + // search cards in Library + // If the player has no nonland cards in his or her hand, you can still search that player's library and have him or her shuffle it. + if (chosenCard != null || controller.chooseUse(outcome, "Search library anyway?", game)) { + TargetCardInLibrary targetCardsLibrary = new TargetCardInLibrary(0, Integer.MAX_VALUE, filterNamedCards); + controller.searchLibrary(targetCardsLibrary, game, targetPlayer.getId()); + for(UUID cardId: targetCardsLibrary.getTargets()) { + Card card = game.getCard(cardId); + if (card != null) { + controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY); + } + } + targetPlayer.shuffleLibrary(game); + } + return true; } return false; }