mirror of
https://github.com/correl/mage.git
synced 2024-11-15 11:09:30 +00:00
Added support for player searching another players library
Fixed Haunting Echoes and Sadistic Sacrament to use this feature
This commit is contained in:
parent
b5b1d3468d
commit
fa0445b544
5 changed files with 75 additions and 65 deletions
|
@ -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<HauntingEchoesEffect> {
|
|||
|
||||
@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<UUID> 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
|
||||
|
|
|
@ -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<SadisticSacramentEffect> {
|
|||
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<UUID> targets = target.getTargets();
|
||||
for (UUID targetId : targets) {
|
||||
Card card = targetPlayer.getLibrary().remove(targetId, game);
|
||||
|
|
|
@ -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<Player> {
|
|||
|
||||
public boolean isHuman();
|
||||
public String getName();
|
||||
public RangeOfInfluence getRange();
|
||||
public Library getLibrary();
|
||||
public RangeOfInfluence getRange();
|
||||
public Library getLibrary();
|
||||
public Cards getGraveyard();
|
||||
public Abilities<Ability> 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<Player> {
|
|||
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<Player> {
|
|||
|
||||
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<Player> {
|
|||
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<Player> {
|
|||
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<? extends Card> pile1, List<? extends Card> pile2, Game game);
|
||||
public abstract boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game);
|
||||
public abstract boolean playMana(ManaCost unpaid, Game game);
|
||||
public abstract boolean playXMana(VariableManaCost cost, ManaCosts<ManaCost> costs, Game game);
|
||||
public abstract int chooseEffect(List<ReplacementEffect> rEffects, Game game);
|
||||
|
@ -249,7 +247,7 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
public List<Ability> getPlayableOptions(Ability ability, Game game);
|
||||
|
||||
public void addCounters(Counter counter, Game game);
|
||||
public List<UUID> getAttachments();
|
||||
public boolean addAttachment(UUID permanentId, Game game);
|
||||
public boolean removeAttachment(UUID permanentId, Game game);
|
||||
public List<UUID> getAttachments();
|
||||
public boolean addAttachment(UUID permanentId, Game game);
|
||||
public boolean removeAttachment(UUID permanentId, Game game);
|
||||
}
|
||||
|
|
|
@ -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<T extends PlayerImpl<T>> 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;
|
||||
}
|
||||
|
|
|
@ -66,11 +66,15 @@ public class TargetCardInLibrary extends TargetCard<TargetCardInLibrary> {
|
|||
}
|
||||
|
||||
@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<TargetCardInLibrary> {
|
|||
return new TargetCardInLibrary(this);
|
||||
}
|
||||
|
||||
public void setMinNumberOfTargets(int minNumberOfTargets) {
|
||||
this.minNumberOfTargets = minNumberOfTargets;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue