From fa0445b5447f98de77a378ccf183f2c7a770910a Mon Sep 17 00:00:00 2001 From: North Date: Tue, 24 Apr 2012 22:57:28 +0300 Subject: [PATCH] Added support for player searching another players library Fixed Haunting Echoes and Sadistic Sacrament to use this feature --- .../mage/sets/magic2010/HauntingEchoes.java | 37 ++++++++------ .../mage/sets/zendikar/SadisticSacrament.java | 7 +-- Mage/src/mage/players/Player.java | 48 +++++++++---------- Mage/src/mage/players/PlayerImpl.java | 36 +++++++------- .../target/common/TargetCardInLibrary.java | 12 ++++- 5 files changed, 75 insertions(+), 65 deletions(-) diff --git a/Mage.Sets/src/mage/sets/magic2010/HauntingEchoes.java b/Mage.Sets/src/mage/sets/magic2010/HauntingEchoes.java index e9ebf4437f..2579549c5e 100644 --- a/Mage.Sets/src/mage/sets/magic2010/HauntingEchoes.java +++ b/Mage.Sets/src/mage/sets/magic2010/HauntingEchoes.java @@ -28,23 +28,21 @@ package mage.sets.magic2010; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; +import java.util.List; import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Outcome; import mage.Constants.Rarity; -import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.CardsImpl; +import mage.filter.FilterCard; import mage.filter.common.FilterBasicLandCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInLibrary; /** * @@ -85,22 +83,33 @@ class HauntingEchoesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - for (Card card: player.getGraveyard().getCards(game)) { + Player player = game.getPlayer(source.getControllerId()); + Player targetPlayer = game.getPlayer(source.getFirstTarget()); + if (targetPlayer != null) { + for (Card card: targetPlayer.getGraveyard().getCards(game)) { if (!filter.match(card)) { card.moveToExile(null, "", source.getId(), game); - for (Card lcard: player.getLibrary().getCards(game)) { - if (lcard.getName().equals(card.getName())) { - lcard.moveToExile(null, "", source.getId(), game); + + FilterCard filterCard = new FilterCard("cards named " + card.getName()); + filterCard.getName().add(card.getName()); + int count = targetPlayer.getLibrary().count(filterCard, game); + TargetCardInLibrary target = new TargetCardInLibrary(count, count, filterCard); + target.setRequired(true); + + player.searchLibrary(target, game, targetPlayer.getId()); + List targets = target.getTargets(); + for(UUID cardId : targets){ + Card libraryCard = game.getCard(cardId); + if (libraryCard != null) { + libraryCard.moveToExile(null, "", source.getId(), game); } } } } + targetPlayer.shuffleLibrary(game); + return true; } - game.getPlayer(source.getControllerId()).lookAtCards("Haunting Echoes", new CardsImpl(Zone.PICK, player.getLibrary().getCards(game)), game); - player.shuffleLibrary(game); - return true; + return false; } @Override diff --git a/Mage.Sets/src/mage/sets/zendikar/SadisticSacrament.java b/Mage.Sets/src/mage/sets/zendikar/SadisticSacrament.java index 49f1c7212b..92eaa21581 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SadisticSacrament.java +++ b/Mage.Sets/src/mage/sets/zendikar/SadisticSacrament.java @@ -39,8 +39,6 @@ import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; -import mage.cards.Cards; -import mage.cards.CardsImpl; import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; @@ -107,11 +105,8 @@ class SadisticSacramentEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player player = game.getPlayer(source.getControllerId()); if (player != null && targetPlayer != null) { - Cards targetPlayersLibrary = new CardsImpl(); - targetPlayersLibrary.addAll(targetPlayer.getLibrary().getCardList()); - TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterCard("cards to exile")); - if (player.choose(Outcome.Benefit, targetPlayersLibrary, target, game)) { + if (player.searchLibrary(target, game, targetPlayer.getId())) { List targets = target.getTargets(); for (UUID targetId : targets) { Card card = targetPlayer.getLibrary().remove(targetId, game); diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 8f6d9a883d..1555755a16 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -37,27 +37,17 @@ import mage.Constants.Outcome; import mage.Constants.RangeOfInfluence; import mage.MageItem; import mage.MageObject; -import mage.abilities.Abilities; -import mage.abilities.Ability; -import mage.abilities.ActivatedAbility; -import mage.abilities.Mode; -import mage.abilities.Modes; -import mage.abilities.SpellAbility; -import mage.abilities.TriggeredAbilities; -import mage.abilities.TriggeredAbility; +import mage.abilities.*; import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.effects.ReplacementEffect; -import mage.abilities.mana.ManaOptions; import mage.cards.Card; import mage.cards.Cards; import mage.cards.decks.Deck; import mage.choices.Choice; import mage.counters.Counter; import mage.counters.Counters; -import mage.filter.FilterAbility; -import mage.game.events.GameEvent; import mage.game.Game; import mage.game.draft.Draft; import mage.game.match.Match; @@ -78,20 +68,20 @@ public interface Player extends MageItem, Copyable { public boolean isHuman(); public String getName(); - public RangeOfInfluence getRange(); - public Library getLibrary(); + public RangeOfInfluence getRange(); + public Library getLibrary(); public Cards getGraveyard(); public Abilities getAbilities(); - public void addAbility(Ability ability); + public void addAbility(Ability ability); public Counters getCounters(); public int getLife(); public void setLife(int life, Game game); public int loseLife(int amount, Game game); - public boolean isCanLoseLife(); - public void setCanLoseLife(boolean canLoseLife); + public boolean isCanLoseLife(); + public void setCanLoseLife(boolean canLoseLife); public int gainLife(int amount, Game game); - public boolean isCanGainLife(); - public void setCanGainLife(boolean canGainLife); + public boolean isCanGainLife(); + public void setCanGainLife(boolean canGainLife); public boolean isLifeTotalCanChange(); public void setLifeTotalCanChange(boolean lifeTotalCanChange); public int damage(int damage, UUID sourceId, Game game, boolean combatDamage, boolean preventable); @@ -114,7 +104,7 @@ public interface Player extends MageItem, Copyable { public void setTopCardRevealed(boolean topCardRevealed); public UserData getUserData(); public void setUserData(UserData userData); - public boolean canLose(Game game); + public boolean canLose(Game game); /** * Returns a set of players which turns under you control. @@ -164,8 +154,8 @@ public interface Player extends MageItem, Copyable { public boolean isTestMode(); public void setTestMode(boolean value); - public void addAction(String action); - public void setAllowBadMoves(boolean allowBadMoves); + public void addAction(String action); + public void setAllowBadMoves(boolean allowBadMoves); public void init(Game game); public void init(Game game, boolean testMode); @@ -181,6 +171,14 @@ public interface Player extends MageItem, Copyable { public boolean removeFromGraveyard(Card card, Game game); public boolean removeFromLibrary(Card card, Game game); public boolean searchLibrary(TargetCardInLibrary target, Game game); + /** + * + * @param target + * @param game + * @param targetPlayerId player whose library will be searched + * @return true if search was successful + */ + public boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId); public boolean canPlayLand(); public boolean playLand(Card card, Game game); public boolean activateAbility(ActivatedAbility ability, Game game); @@ -219,7 +217,7 @@ public interface Player extends MageItem, Copyable { public abstract boolean chooseMulligan(Game game); public abstract boolean chooseUse(Outcome outcome, String message, Game game); public abstract boolean choose(Outcome outcome, Choice choice, Game game); - public abstract boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game); + public abstract boolean choosePile(Outcome outcome, String message, List pile1, List pile2, Game game); public abstract boolean playMana(ManaCost unpaid, Game game); public abstract boolean playXMana(VariableManaCost cost, ManaCosts costs, Game game); public abstract int chooseEffect(List rEffects, Game game); @@ -249,7 +247,7 @@ public interface Player extends MageItem, Copyable { public List getPlayableOptions(Ability ability, Game game); public void addCounters(Counter counter, Game game); - public List getAttachments(); - public boolean addAttachment(UUID permanentId, Game game); - public boolean removeAttachment(UUID permanentId, Game game); + public List getAttachments(); + public boolean addAttachment(UUID permanentId, Game game); + public boolean removeAttachment(UUID permanentId, Game game); } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index af7505ace0..f8ee9f791f 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -29,15 +29,7 @@ package mage.players; import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; +import java.util.*; import mage.Constants.AsThoughEffectType; import mage.Constants.Outcome; import mage.Constants.RangeOfInfluence; @@ -67,9 +59,9 @@ import mage.game.Game; import mage.game.combat.CombatGroup; import mage.game.events.DamagePlayerEvent; import mage.game.events.DamagedPlayerEvent; -import mage.game.permanent.Permanent; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; import mage.game.stack.StackAbility; import mage.players.net.UserData; import mage.target.Target; @@ -1092,16 +1084,24 @@ public abstract class PlayerImpl> implements Player, Ser @Override public boolean searchLibrary(TargetCardInLibrary target, Game game) { + return searchLibrary(target, game, playerId); + } + + @Override + public boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId) { //20091005 - 701.14c - if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, playerId, playerId))) { - TargetCardInLibrary newTarget; + if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.SEARCH_LIBRARY, targetPlayerId, playerId))) { + TargetCardInLibrary newTarget = target.copy(); int count = library.count(target.getFilter(), game); - if (count < target.getNumberOfTargets()) - newTarget = new TargetCardInLibrary(library.count(target.getFilter(), game), target.getMaxNumberOfTargets(), target.getFilter()); - else - newTarget = target; - if (newTarget.choose(Outcome.Neutral, playerId, null, game)) { - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, playerId, playerId)); + if (count < target.getNumberOfTargets()) { + newTarget.setMinNumberOfTargets(count); + } + if (newTarget.choose(Outcome.Neutral, playerId, targetPlayerId, game)) { + target.getTargets().clear(); + for(UUID targetId: newTarget.getTargets()){ + target.add(targetId, game); + } + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LIBRARY_SEARCHED, targetPlayerId, playerId)); } return true; } diff --git a/Mage/src/mage/target/common/TargetCardInLibrary.java b/Mage/src/mage/target/common/TargetCardInLibrary.java index b7833529db..c7e9922d20 100644 --- a/Mage/src/mage/target/common/TargetCardInLibrary.java +++ b/Mage/src/mage/target/common/TargetCardInLibrary.java @@ -66,11 +66,15 @@ public class TargetCardInLibrary extends TargetCard { } @Override - public boolean choose(Outcome outcome, UUID playerId, UUID sourceId, Game game) { + public boolean choose(Outcome outcome, UUID playerId, UUID targetPlayerId, Game game) { Player player = game.getPlayer(playerId); + Player targetPlayer = game.getPlayer(targetPlayerId); + if (targetPlayer == null) { + targetPlayer = player; + } while (!isChosen() && !doneChosing()) { chosen = targets.size() >= minNumberOfTargets; - if (!player.choose(outcome, new CardsImpl(Zone.LIBRARY, player.getLibrary().getCards(game)), this, game)) { + if (!player.choose(outcome, new CardsImpl(Zone.LIBRARY, targetPlayer.getLibrary().getCards(game)), this, game)) { return chosen; } chosen = targets.size() >= minNumberOfTargets; @@ -97,4 +101,8 @@ public class TargetCardInLibrary extends TargetCard { return new TargetCardInLibrary(this); } + public void setMinNumberOfTargets(int minNumberOfTargets) { + this.minNumberOfTargets = minNumberOfTargets; + } + }