magarena/src/magic/model/MagicGame.java

1324 lines
40 KiB
Java
Raw Normal View History

2013-04-12 19:32:25 -07:00
package magic.model;
import magic.data.GeneralConfig;
import magic.model.action.MagicAction;
import magic.model.action.MagicActionList;
import magic.model.action.MagicAddEventAction;
2013-07-11 22:43:22 -07:00
import magic.model.action.MagicAddFirstEventAction;
2013-04-12 19:32:25 -07:00
import magic.model.action.MagicExecuteFirstEventAction;
import magic.model.action.MagicLogMarkerAction;
import magic.model.action.MagicMarkerAction;
import magic.model.action.MagicPutItemOnStackAction;
import magic.model.action.MagicRemoveFromPlayAction;
import magic.model.choice.MagicCombatCreature;
import magic.model.choice.MagicDeclareAttackersResult;
import magic.model.choice.MagicDeclareBlockersResult;
import magic.model.choice.MagicTargetChoice;
import magic.model.event.MagicEvent;
import magic.model.event.MagicEventQueue;
import magic.model.event.MagicUniquenessEvent;
2013-04-12 19:32:25 -07:00
import magic.model.mstatic.MagicLayer;
import magic.model.mstatic.MagicPermanentStatic;
import magic.model.mstatic.MagicPermanentStaticMap;
import magic.model.mstatic.MagicStatic;
import magic.model.phase.MagicGameplay;
import magic.model.phase.MagicPhase;
import magic.model.phase.MagicPhaseType;
import magic.model.phase.MagicStep;
import magic.model.stack.MagicItemOnStack;
import magic.model.stack.MagicStack;
import magic.model.stack.MagicTriggerOnStack;
import magic.model.target.MagicLegendaryCopiesFilter;
import magic.model.target.MagicOtherPermanentTargetFilter;
import magic.model.target.MagicPlaneswalkerCopiesFilter;
import magic.model.target.MagicTarget;
import magic.model.target.MagicTargetFilter;
import magic.model.target.MagicTargetFilterFactory;
2013-04-12 19:32:25 -07:00
import magic.model.target.MagicTargetHint;
import magic.model.target.MagicTargetNone;
import magic.model.trigger.MagicPermanentTrigger;
import magic.model.trigger.MagicPermanentTriggerList;
import magic.model.trigger.MagicPermanentTriggerMap;
import magic.model.trigger.MagicTrigger;
import magic.model.trigger.MagicTriggerType;
import magic.model.trigger.MagicWhenOtherComesIntoPlayTrigger;
2013-04-12 19:32:25 -07:00
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
public class MagicGame {
public static final boolean LOSE_DRAW_EMPTY_LIBRARY=true;
private static final long ID_FACTOR=31;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
private static int COUNT;
private static MagicGame INSTANCE;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
private final MagicDuel duel;
private final MagicPlayer[] players;
private MagicPermanentTriggerMap triggers;
private final MagicPermanentTriggerMap additionalTriggers;
2013-04-12 19:32:25 -07:00
private final MagicPermanentTriggerList turnTriggers;
private final MagicPermanentStaticMap statics;
private final MagicCardList exiledUntilEndOfTurn;
private final MagicEventQueue events;
private final MagicStack stack;
private final MagicPlayer scorePlayer;
2013-07-08 23:40:18 -07:00
private final MagicGameplay gameplay;
private final MagicActionList actions;
private final MagicActionList delayedActions;
2013-04-12 19:32:25 -07:00
private final boolean sound;
private int score;
private int turn=1;
private int startTurn;
private int mainPhaseCount=100000000;
private int landsPlayed;
private int maxLands;
2013-07-08 23:40:18 -07:00
private int priorityPassedCount;
2013-04-12 19:32:25 -07:00
private boolean creatureDiedThisTurn;
private boolean priorityPassed;
private boolean skipTurn;
private boolean stateCheckRequired;
private boolean artificial;
private boolean fastChoices;
private boolean immediate;
private boolean disableLog;
private MagicPlayer visiblePlayer;
private MagicPlayer turnPlayer;
private MagicPlayer losingPlayer = MagicPlayer.NONE;
private MagicPhase phase;
private MagicStep step;
2013-06-23 18:33:35 -07:00
private MagicPayedCost payedCost;
2013-04-12 19:32:25 -07:00
private MagicActionList undoPoints;
private MagicLogBook logBook;
private MagicLogMessageBuilder logMessageBuilder;
2013-07-08 23:40:18 -07:00
private MagicSource activeSource = MagicEvent.NO_SOURCE;
2013-04-12 19:32:25 -07:00
private long[] keys;
private long stateId;
private long time = 1000000;
private boolean isConceded = false;
2013-04-12 19:32:25 -07:00
public static MagicGame getInstance() {
return INSTANCE;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
static int getCount() {
return COUNT;
}
static MagicGame create(
final MagicDuel duel,
final MagicGameplay gameplay,
final MagicPlayer[] players,
final MagicPlayer startPlayer,
final boolean sound) {
COUNT++;
INSTANCE = new MagicGame(duel, gameplay, players, startPlayer, sound);
return INSTANCE;
}
private MagicGame(
final MagicDuel aDuel,
final MagicGameplay aGameplay,
final MagicPlayer[] aPlayers,
final MagicPlayer startPlayer,
final boolean aSound) {
artificial=false;
duel = aDuel;
gameplay = aGameplay;
players = aPlayers;
for (final MagicPlayer player : players) {
player.setGame(this);
}
sound = aSound;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
triggers=new MagicPermanentTriggerMap();
additionalTriggers=new MagicPermanentTriggerMap();
2013-04-12 19:32:25 -07:00
turnTriggers=new MagicPermanentTriggerList();
statics = new MagicPermanentStaticMap();
exiledUntilEndOfTurn=new MagicCardList();
events=new MagicEventQueue();
stack=new MagicStack();
visiblePlayer=players[0];
scorePlayer=visiblePlayer;
turnPlayer=startPlayer;
actions=new MagicActionList();
delayedActions=new MagicActionList();
undoPoints=new MagicActionList();
logBook=new MagicLogBook();
logMessageBuilder=new MagicLogMessageBuilder(this);
payedCost=new MagicPayedCost();
changePhase(gameplay.getStartPhase(this));
}
public MagicGame(final MagicGame game,final MagicPlayer aScorePlayer) {
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
artificial=true;
sound=false;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//copy the reference, these are singletons
duel=game.duel;
gameplay=game.gameplay;
phase=game.phase;
step=game.step;
//copying primitives, array of primitive
time = game.time;
turn = game.turn;
startTurn = game.startTurn;
landsPlayed = game.landsPlayed;
maxLands = game.maxLands;
2013-04-12 19:32:25 -07:00
creatureDiedThisTurn = game.creatureDiedThisTurn;
priorityPassed = game.priorityPassed;
priorityPassedCount = game.priorityPassedCount;
stateCheckRequired = game.stateCheckRequired;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//copied and stored in copyMap
2013-06-23 18:33:35 -07:00
final MagicCopyMap copyMap=new MagicCopyMap();
players=copyMap.copyObjects(game.players,MagicPlayer.class);
2013-04-12 19:32:25 -07:00
for (final MagicPlayer player : players) {
player.setGame(this);
}
scorePlayer=copyMap.copy(aScorePlayer);
visiblePlayer=copyMap.copy(game.visiblePlayer);
turnPlayer=copyMap.copy(game.turnPlayer);
losingPlayer=copyMap.copy(game.losingPlayer);
payedCost=copyMap.copy(game.payedCost);
2013-07-08 23:40:18 -07:00
activeSource=copyMap.copy(game.activeSource);
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//construct a new object using copyMap to copy internals
events=new MagicEventQueue(copyMap, game.events);
stack=new MagicStack(copyMap, game.stack);
triggers=new MagicPermanentTriggerMap(copyMap, game.triggers);
additionalTriggers=new MagicPermanentTriggerMap(copyMap, game.additionalTriggers);
2013-04-12 19:32:25 -07:00
statics=new MagicPermanentStaticMap(copyMap, game.statics);
exiledUntilEndOfTurn=new MagicCardList(copyMap, game.exiledUntilEndOfTurn);
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//construct a new object
turnTriggers=new MagicPermanentTriggerList(triggers, game.turnTriggers);
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//the following are NOT copied when game state is cloned
//fastChoices
//immediate
//skipTurn
//mainPhaseCount
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//score is RESET to zero
score=0;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
//historical actions are not carried over
actions=new MagicActionList();
//there should be no pending actions
2013-06-23 18:33:35 -07:00
assert game.delayedActions.isEmpty() : "delayedActions: " + game.delayedActions;
2013-04-12 19:32:25 -07:00
delayedActions=new MagicActionList();
//no logging
disableLog = true;
undoPoints=null;
logBook=null;
logMessageBuilder=null;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setSkipTurn(final boolean skip) {
skipTurn = skip;
}
private boolean getSkipTurn() {
return skipTurn;
}
public void setScore(final int aScore) {
score = aScore;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void changeScore(final int amount) {
score+=amount;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getScore() {
return score;
}
public long getUniqueId() {
time++;
return time;
}
//follow factors in MagicMarkerAction
public long getStateId() {
2013-06-23 18:33:35 -07:00
keys = new long[] {
2013-04-12 19:32:25 -07:00
turn,
phase.hashCode(),
step.hashCode(),
turnPlayer.getIndex(),
landsPlayed,
maxLands,
2013-04-12 19:32:25 -07:00
priorityPassedCount,
(creatureDiedThisTurn ? 1L : -1L),
(priorityPassed ? 1L : -1L),
(stateCheckRequired ? 1L : -1L),
payedCost.getStateId(),
2013-04-12 19:32:25 -07:00
stack.getStateId(),
events.getStateId(),
players[0].getStateId(),
players[1].getStateId(),
2014-03-31 22:57:17 -07:00
activeSource.getStateId(),
triggers.getStateId(),
statics.getStateId(),
2013-04-12 19:32:25 -07:00
exiledUntilEndOfTurn.getUnorderedStateId(),
};
stateId = magic.MurmurHash3.hash(keys);
return stateId;
}
public String toString() {
2013-06-23 18:33:35 -07:00
return "GAME: " +
2013-04-12 19:32:25 -07:00
"id=" + stateId + " " +
2013-06-23 18:33:35 -07:00
"t=" + turn + " " +
"p=" + phase.getType() + " " +
"s=" + step + " " +
2013-04-12 19:32:25 -07:00
"tp=" + turnPlayer.getIndex() + " " +
"lp=" + landsPlayed + " " +
2013-04-12 19:32:25 -07:00
"ppc=" + priorityPassedCount + " " +
"pp=" + priorityPassed + " " +
"sc=" + stateCheckRequired + " " +
"x=" + getPayedCost().getX() + " " +
"e=" + events.size() + " " +
"s=" + stack.size();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public String getIdString() {
final StringBuilder sb = new StringBuilder(toString());
sb.append('\n');
sb.append(keys[0]);
for (int i = 1; i < keys.length; i++) {
sb.append(' ');
sb.append(keys[i]);
}
sb.append('\n');
sb.append(players[0].getIdString());
sb.append('\n');
sb.append(players[1].getIdString());
return sb.toString();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public long getGameId(final int pruneScore) {
2013-06-23 18:33:35 -07:00
long id=0;
2013-04-12 19:32:25 -07:00
id = id*ID_FACTOR + turn;
id = id*ID_FACTOR + phase.getType().ordinal();
id = id*ID_FACTOR + score + pruneScore;
id = players[0].getPlayerId(id);
id = players[1].getPlayerId(id);
return id;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public static boolean canSkipSingleChoice() {
return GeneralConfig.getInstance().getSkipSingle();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public static boolean canSkipSingleManaChoice() {
return GeneralConfig.getInstance().getSkipSingle();
}
//human is declaring blockers, skip if AI is not attacking
public boolean canSkipDeclareBlockersSingleChoice() {
return GeneralConfig.getInstance().getSkipSingle() && turnPlayer.getNrOfAttackers() == 0;
2013-06-23 18:33:35 -07:00
}
2013-04-12 19:32:25 -07:00
public boolean canAlwaysPass() {
if (GeneralConfig.getInstance().getAlwaysPass()) {
2013-06-23 18:33:35 -07:00
return phase.getType() == MagicPhaseType.Draw ||
2013-04-12 19:32:25 -07:00
phase.getType() == MagicPhaseType.BeginOfCombat;
}
return false;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
private int getArtificialLevel() {
return duel.getDifficulty();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getArtificialLevel(final int idx) {
return duel.getDifficulty(idx);
}
public boolean isArtificial() {
return artificial;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isReal() {
return !artificial;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setArtificial(final boolean art) {
artificial = art;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isSound() {
return sound;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setFastChoices(final boolean aFastChoices) {
fastChoices = aFastChoices;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean getFastChoices() {
return fastChoices;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setTurn(final int aTurn) {
turn = aTurn;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getTurn() {
return turn;
}
public void setMainPhases(final int count) {
startTurn=turn;
mainPhaseCount=count;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getRelativeTurn() {
return startTurn>0?turn-startTurn:0;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void decreaseMainPhaseCount() {
mainPhaseCount--;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setMainPhaseCount(final int count) {
mainPhaseCount=count;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getMainPhaseCount() {
return mainPhaseCount;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setPhase(final MagicPhase aPhase) {
phase = aPhase;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void nextPhase() {
changePhase(gameplay.getNextPhase(this));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
private void changePhase(final MagicPhase aPhase) {
phase = aPhase;
step=MagicStep.Begin;
priorityPassedCount=0;
players[0].getActivationPriority().clear();
players[1].getActivationPriority().clear();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPhase getPhase() {
return phase;
}
public void executePhase() {
phase.executePhase(this);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isPhase(final MagicPhaseType type) {
return phase.getType()==type;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isMainPhase() {
return phase.getType().isMain();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isCombatPhase() {
return phase.getType().isCombat();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setStep(final MagicStep aStep) {
step = aStep;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicStep getStep() {
return step;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void resolve() {
if (stack.isEmpty()) {
step=MagicStep.NextPhase;
} else {
step=MagicStep.Resolve;
2013-06-23 18:33:35 -07:00
}
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
public void resetPayedCost() {
payedCost = new MagicPayedCost();
}
2013-06-23 18:33:35 -07:00
public void setPayedCost(final MagicPayedCost aPayedCost) {
payedCost = aPayedCost;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPayedCost getPayedCost() {
return new MagicPayedCost(payedCost);
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
/** Determines if game score should be cached for this game state. */
public boolean cacheState() {
switch (phase.getType()) {
case FirstMain:
case EndOfCombat:
case Cleanup:
return step==MagicStep.NextPhase;
default:
return false;
}
}
/** Tells gameplay that it can skip certain parts during AI processing. */
public boolean canSkip() {
return stack.isEmpty() && artificial;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean isFinished() {
return losingPlayer.isValid() || mainPhaseCount <= 0;
}
public MagicLogBook getLogBook() {
return logBook;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void hideHiddenCards() {
getOpponent(scorePlayer).setHandToUnknown();
for (final MagicPlayer player : players) {
player.getLibrary().setAIKnown(false);
2013-06-23 18:33:35 -07:00
}
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void showRandomizedHiddenCards() {
getOpponent(scorePlayer).showRandomizedHandAndLibrary();
scorePlayer.getLibrary().shuffle(MagicRandom.nextRNGInt(999999));
scorePlayer.getLibrary().setAIKnown(true);
2013-04-12 19:32:25 -07:00
}
Collection<MagicAction> getActions() {
return actions;
}
public int getNumActions() {
return actions.size();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addDelayedAction(final MagicAction action) {
delayedActions.add(action);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void doAction(final MagicAction action) {
actions.add(action);
try {
action.doAction(this);
} catch (Throwable ex) {
MagicGameReport.buildReport(this, Thread.currentThread(), ex);
System.exit(1);
}
//performing actions update the score
score += action.getScore(scorePlayer);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void update() {
doDelayedActions();
MagicPermanent.update(this);
// add Soulbond trigger here
triggers = new MagicPermanentTriggerMap(additionalTriggers);
triggers.add(new MagicPermanentTrigger(0,MagicPermanent.NONE,MagicWhenOtherComesIntoPlayTrigger.Soulbond));
for (final MagicPlayer player : players) {
for (final MagicPermanent perm : player.getPermanents()) {
for (final MagicTrigger<?> trigger : perm.getTriggers()) {
triggers.add(new MagicPermanentTrigger(getUniqueId(), perm, trigger));
}}}
2013-04-12 19:32:25 -07:00
MagicPlayer.update(this);
MagicGame.update(this);
doDelayedActions();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void apply(final MagicLayer layer) {
switch (layer) {
case Game:
maxLands = 1;
2013-04-12 19:32:25 -07:00
break;
default:
throw new RuntimeException("No case for " + layer + " in MagicGame.apply");
}
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
private void apply(final MagicPermanent source, final MagicStatic mstatic) {
final MagicLayer layer = mstatic.getLayer();
switch (layer) {
case Game:
mstatic.modGame(source, this);
break;
default:
throw new RuntimeException("No case for " + layer + " in MagicGame.apply");
}
}
public static void update(final MagicGame game) {
game.apply(MagicLayer.Game);
for (final MagicPermanentStatic mpstatic : game.getStatics(MagicLayer.Game)) {
final MagicStatic mstatic = mpstatic.getStatic();
final MagicPermanent source = mpstatic.getPermanent();
if (mstatic.accept(game, source, source)) {
game.apply(source, mstatic);
}
}
}
private void doDelayedActions() {
while (!delayedActions.isEmpty()) {
final MagicAction action = delayedActions.removeFirst();
doAction(action);
}
}
public void snapshot() {
final MagicAction markerAction=new MagicMarkerAction();
doAction(markerAction);
if (artificial == false) {
doAction(new MagicLogMarkerAction());
undoPoints.addLast(markerAction);
}
}
2013-06-23 18:33:35 -07:00
public void restore() {
if (artificial == false) {
undoPoints.removeLast();
}
2013-04-12 19:32:25 -07:00
//undo each action up to and including the first MagicMarkerAction
MagicAction action;
do {
action = actions.removeLast();
try {
action.undoAction(this);
} catch (Throwable ex) {
MagicGameReport.buildReport(this, Thread.currentThread(), ex);
2013-04-12 19:32:25 -07:00
System.exit(1);
}
} while (!(action instanceof MagicMarkerAction));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void undoAllActions() {
2013-06-23 18:33:35 -07:00
assert actions.isEmpty() : "actions: " + actions;
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getNrOfUndoPoints() {
return undoPoints.size();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean hasUndoPoints() {
return !undoPoints.isEmpty();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void clearUndoPoints() {
undoPoints.clear();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void clearMessages() {
logMessageBuilder.clearMessages();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void logMessages() {
if (disableLog) {
return;
}
logMessageBuilder.logMessages();
}
private void logAppendEvent(final MagicEvent event,final Object[] choiceResults) {
if (disableLog) {
return;
}
final String message=event.getDescription(choiceResults);
if (message.length() == 0) {
return;
}
logMessageBuilder.appendMessage(event.getPlayer(),message);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void logAppendMessage(final MagicPlayer player,final String message) {
if (disableLog) {
return;
}
logMessageBuilder.appendMessage(player,message);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void logMessage(final MagicPlayer player,final String message) {
if (disableLog) {
return;
}
logBook.add(new MagicMessage(this,player,message));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void logAttackers(final MagicPlayer player,final MagicDeclareAttackersResult result) {
if (disableLog || result.isEmpty()) {
return;
}
final SortedSet<String> names=new TreeSet<String>();
for (final MagicPermanent attacker : result) {
names.add(attacker.getName());
}
final StringBuilder builder = new StringBuilder(player + " attacks with ");
MagicMessage.addNames(builder,names);
builder.append('.');
logBook.add(new MagicMessage(this,player,builder.toString()));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void logBlockers(final MagicPlayer player,final MagicDeclareBlockersResult result) {
if (disableLog) {
return;
}
final SortedSet<String> names=new TreeSet<String>();
for (final MagicCombatCreature[] creatures : result) {
for (int index=1;index<creatures.length;index++) {
names.add(creatures[index].getName());
}
}
if (names.isEmpty()) {
return;
}
final StringBuilder builder = new StringBuilder(player + " blocks with ");
MagicMessage.addNames(builder,names);
builder.append('.');
logBook.add(new MagicMessage(this,player,builder.toString()));
}
public void executeEvent(final MagicEvent event,final Object[] choiceResults) {
if (choiceResults == null) {
throw new RuntimeException("choiceResults is null");
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
logAppendEvent(event,choiceResults);
2013-06-23 18:33:35 -07:00
// Payed cost
if (event.getManaChoiceResultIndex() >= 0) {
payedCost.set(choiceResults[event.getManaChoiceResultIndex()]);
}
// Target in cost
if (event.getTargetChoiceResultIndex() >= 0) {
payedCost.set(choiceResults[event.getTargetChoiceResultIndex()]);
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-07-08 23:40:18 -07:00
activeSource = event.getSource();
2013-04-12 19:32:25 -07:00
event.executeEvent(this,choiceResults);
update();
}
public MagicEventQueue getEvents() {
return events;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean hasNextEvent() {
return !events.isEmpty();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicEvent getNextEvent() {
return events.getFirst();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addEvent(final MagicEvent event) {
doAction(new MagicAddEventAction(event));
}
2013-07-11 22:43:22 -07:00
public void addFirstEvent(final MagicEvent event) {
doAction(new MagicAddFirstEventAction(event));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void executeNextEvent(final Object[] choiceResults) {
doAction(new MagicExecuteFirstEventAction(choiceResults));
}
2013-06-23 18:33:35 -07:00
public void executeNextEvent() {
doAction(new MagicExecuteFirstEventAction(MagicEvent.NO_CHOICE_RESULTS));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicDuel getDuel() {
return duel;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void advanceDuel() {
duel.advance(losingPlayer!=players[0],this);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer[] getPlayers() {
return players;
}
2014-07-16 02:16:16 -07:00
/**
* Gets players ordered as Active Player then Non-Active Player.
* <p>
* @see <a href="http://www.slightlymagic.net/forum/viewtopic.php?f=115&p=155684">APNAP forum topic</a>
*/
public MagicPlayer[] getAPNAP() {
return new MagicPlayer[]{turnPlayer, turnPlayer.getOpponent()};
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getPlayer(final int index) {
return players[index];
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
MagicPlayer getOpponent(final MagicPlayer player) {
2013-06-23 18:33:35 -07:00
return players[1-player.getIndex()];
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setVisiblePlayer(final MagicPlayer aVisiblePlayer) {
visiblePlayer = aVisiblePlayer;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getVisiblePlayer() {
return visiblePlayer;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setTurnPlayer(final MagicPlayer aTurnPlayer) {
turnPlayer = aTurnPlayer;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getTurnPlayer() {
return turnPlayer;
}
2013-06-23 18:33:35 -07:00
2013-06-05 22:57:29 -07:00
public MagicPlayer getAttackingPlayer() {
return turnPlayer;
}
2013-06-23 18:33:35 -07:00
2013-06-05 22:57:29 -07:00
public MagicPlayer getDefendingPlayer() {
return turnPlayer.getOpponent();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getPriorityPlayer() {
return step == MagicStep.ActivePlayer ? turnPlayer : getOpponent(turnPlayer);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getScorePlayer() {
return scorePlayer;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setLosingPlayer(final MagicPlayer player) {
losingPlayer = player;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPlayer getLosingPlayer() {
return losingPlayer;
}
2013-07-08 23:40:18 -07:00
public MagicSource getActiveSource() {
return activeSource;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean hasTurn(final MagicPlayer player) {
return player == turnPlayer;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getNrOfPermanents(final MagicType type) {
return players[0].getNrOfPermanents(type) +
players[1].getNrOfPermanents(type);
2013-04-12 19:32:25 -07:00
}
public int getNrOfPermanents(final MagicSubType subType) {
return players[0].getNrOfPermanents(subType) +
players[1].getNrOfPermanents(subType);
}
2013-06-23 18:33:35 -07:00
public int getNrOfPermanents(final MagicTargetFilter<MagicPermanent> filter) {
return filterPermanents(filter).size();
}
2013-04-12 19:32:25 -07:00
public boolean canPlaySorcery(final MagicPlayer controller) {
2013-06-23 18:33:35 -07:00
return phase.getType().isMain() &&
stack.isEmpty() &&
2013-04-12 19:32:25 -07:00
turnPlayer == controller;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean canPlayLand(final MagicPlayer controller) {
return landsPlayed < maxLands && canPlaySorcery(controller);
2013-04-12 19:32:25 -07:00
}
public int getLandsPlayed() {
return landsPlayed;
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
public void incLandsPlayed() {
landsPlayed++;
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
public void resetLandsPlayed() {
landsPlayed = 0;
2013-04-12 19:32:25 -07:00
}
public void setLandsPlayed(final int lp) {
landsPlayed = lp;
2013-04-12 19:32:25 -07:00
}
public void incMaxLands() {
maxLands++;
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
public void resetMaxLands() {
maxLands = 1;
2013-04-12 19:32:25 -07:00
}
public int getSpellsCast() {
int spellCount = 0;
for (final MagicPlayer player : getPlayers()) {
spellCount += player.getSpellsCast();
}
return spellCount;
2013-04-12 19:32:25 -07:00
}
public int getSpellsCastLastTurn() {
int spellCount = 0;
for (final MagicPlayer player : getPlayers()) {
spellCount += player.getSpellsCastLastTurn();
}
return spellCount;
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
public void incSpellsCast(final MagicPlayer player) {
player.incSpellsCast();
2013-04-12 19:32:25 -07:00
}
2013-04-12 19:32:25 -07:00
public boolean getCreatureDiedThisTurn() {
return creatureDiedThisTurn;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setCreatureDiedThisTurn(final boolean died) {
creatureDiedThisTurn = died;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicStack getStack() {
return stack;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setPriorityPassed(final boolean passed) {
priorityPassed=passed;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean getPriorityPassed() {
return priorityPassed;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void incrementPriorityPassedCount() {
priorityPassedCount++;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setPriorityPassedCount(final int count) {
priorityPassedCount=count;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public int getPriorityPassedCount() {
return priorityPassedCount;
}
2014-03-27 23:09:11 -07:00
public MagicSource createDelayedSource(final MagicObject obj, final MagicPlayer controller) {
return new MagicCard(obj.getCardDefinition(), controller.map(this), getUniqueId());
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPermanent createPermanent(final MagicCard card,final MagicPlayer controller) {
return new MagicPermanent(getUniqueId(),card,controller);
}
public MagicPermanent createPermanent(final MagicCard card, final MagicCardDefinition cardDef, final MagicPlayer controller) {
return new MagicPermanent(getUniqueId(),card,cardDef,controller);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicCardList getExiledUntilEndOfTurn() {
return exiledUntilEndOfTurn;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setStateCheckRequired(final boolean required) {
stateCheckRequired = required;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void setStateCheckRequired() {
stateCheckRequired = true;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public boolean getStateCheckRequired() {
return stateCheckRequired;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void checkState() {
while (stateCheckRequired) {
stateCheckRequired = false;
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
// Check if a player has lost
for (final MagicPlayer player : players) {
player.generateStateBasedActions();
}
// Check permanents' state
for (final MagicPlayer player : players) {
for (final MagicPermanent permanent : player.getPermanents()) {
permanent.generateStateBasedActions();
}}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
update();
// some action may set stateCheckRequired to true, if so loop again
}
}
public void checkUniquenessRule(final MagicPermanent permanent) {
// 704.5k "legend rule"
if (permanent.hasType(MagicType.Legendary)) {
final MagicTargetFilter<MagicPermanent> targetFilter=new MagicLegendaryCopiesFilter(permanent.getName());
2013-04-12 19:32:25 -07:00
final Collection<MagicPermanent> targets=filterPermanents(permanent.getController(),targetFilter);
if (targets.size() > 1) {
addEvent(new MagicUniquenessEvent(permanent, targetFilter));
2013-04-12 19:32:25 -07:00
}
}
// 704.5j "planeswalker uniqueness rule."
if (permanent.hasType(MagicType.Planeswalker)) {
final MagicTargetFilter<MagicPermanent> targetFilter=new MagicPlaneswalkerCopiesFilter(permanent);
final Collection<MagicPermanent> targets=filterPermanents(permanent.getController(),targetFilter);
if (targets.size() > 1) {
addEvent(new MagicUniquenessEvent(permanent, targetFilter));
2013-04-12 19:32:25 -07:00
}
}
2013-07-22 23:44:23 -07:00
// 704.5m "world rule"
if (permanent.hasType(MagicType.World)) {
final Collection<MagicPermanent> targets=filterPermanents(
permanent.getController(),
new MagicOtherPermanentTargetFilter(
MagicTargetFilterFactory.WORLD,
2013-07-22 23:44:23 -07:00
permanent
)
);
for (final MagicPermanent world : targets) {
logAppendMessage(
world.getController(),
world.getName() + " is put into its owner's graveyard."
);
2013-07-22 23:44:23 -07:00
doAction(new MagicRemoveFromPlayAction(
world,
MagicLocationType.Graveyard
));
}
}
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public Object[] map(final Object[] data) {
final int length=data.length;
final Object[] mappedData=new Object[length];
for (int index=0;index<length;index++) {
final Object obj=data[index];
if (obj != null && obj instanceof MagicMappable) {
mappedData[index]=((MagicMappable)obj).map(this);
} else {
assert obj == null ||
obj instanceof Enum ||
obj instanceof Number ||
obj instanceof String :
obj.getClass().getName() + " not mapped";
2013-04-12 19:32:25 -07:00
mappedData[index]=obj;
}
2013-06-23 18:33:35 -07:00
}
2013-04-12 19:32:25 -07:00
return mappedData;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
// ***** TARGETTING *****
2014-04-13 19:26:51 -07:00
public List<MagicTarget> filterTargets(final MagicPlayer player,final MagicTargetFilter<MagicTarget> targetFilter) {
return targetFilter.filter(this, player, MagicTargetHint.None);
}
public List<MagicPlayer> filterPlayers(final MagicPlayer player,final MagicTargetFilter<MagicPlayer> targetFilter) {
return targetFilter.filter(this, player, MagicTargetHint.None);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public List<MagicPermanent> filterPermanents(final MagicPlayer player,final MagicTargetFilter<MagicPermanent> targetFilter) {
return targetFilter.filter(this, player, MagicTargetHint.None);
}
public List<MagicPermanent> filterPermanents(final MagicTargetFilter<MagicPermanent> targetFilter) {
return targetFilter.filter(this, turnPlayer, MagicTargetHint.None);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public List<MagicCard> filterCards(final MagicPlayer player,final MagicTargetFilter<MagicCard> targetFilter) {
return targetFilter.filter(this, player, MagicTargetHint.None);
}
public List<MagicCard> filterCards(final MagicTargetFilter<MagicCard> targetFilter) {
return targetFilter.filter(this, turnPlayer, MagicTargetHint.None);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public List<MagicItemOnStack> filterItemOnStack(final MagicPlayer player,final MagicTargetFilter<MagicItemOnStack> targetFilter) {
return targetFilter.filter(this, player, MagicTargetHint.None);
}
public List<MagicItemOnStack> filterItemOnStack(final MagicTargetFilter<MagicItemOnStack> targetFilter) {
return targetFilter.filter(this, turnPlayer, MagicTargetHint.None);
}
2013-04-12 19:32:25 -07:00
public boolean hasLegalTargets(
final MagicPlayer player,
final MagicSource source,
final MagicTargetChoice targetChoice,
final boolean hints) {
if (targetChoice == MagicTargetChoice.NONE) {
return true;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
final Collection<? extends MagicTarget> targets = targetChoice.getTargetFilter().filter(
this,
player,
targetChoice.getTargetHint(hints)
);
if (!targetChoice.isTargeted()) {
return !targets.isEmpty();
}
for (final MagicTarget target : targets) {
if (target.isValidTarget(source)) {
return true;
}
}
return false;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public List<MagicTarget> getLegalTargets(
final MagicPlayer player,
final MagicSource source,
final MagicTargetChoice targetChoice,
final MagicTargetHint targetHint) {
final Collection<? extends MagicTarget> targets = targetChoice.getTargetFilter().filter(
this,
player,
targetHint
);
final List<MagicTarget> options;
if (targetChoice.isTargeted()) {
options=new ArrayList<MagicTarget>();
for (final MagicTarget target : targets) {
if (target.isValidTarget(source)) {
options.add(target);
}
}
} else {
options=new ArrayList<MagicTarget>(targets);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
if (options.isEmpty()) {
// Try again without using hints
if (targetHint != MagicTargetHint.None) {
return getLegalTargets(player, source, targetChoice, MagicTargetHint.None);
// Add none when there are no legal targets. Only for triggers.
} else {
options.add(MagicTargetNone.getInstance());
}
}
return options;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public <T extends MagicTarget> boolean isLegalTarget(
final MagicPlayer player,
final MagicSource source,
final MagicTargetChoice targetChoice,
final T target) {
2013-06-23 18:33:35 -07:00
2014-03-19 23:13:46 -07:00
@SuppressWarnings("unchecked")
2013-04-12 19:32:25 -07:00
MagicTargetFilter<T> targetFilter = (MagicTargetFilter<T>)targetChoice.getTargetFilter();
2013-06-23 18:33:35 -07:00
if (target==null ||
target==MagicTargetNone.getInstance() ||
2013-04-12 19:32:25 -07:00
!targetFilter.accept(this,player,target)) {
return false;
2013-06-23 18:33:35 -07:00
}
2013-04-12 19:32:25 -07:00
if (target.isLegalTarget(player, targetFilter)) {
return !targetChoice.isTargeted() || target.isValidTarget(source);
}
return false;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
// ***** STATICS *****
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addStatics(final MagicPermanent permanent) {
for (final MagicStatic mstatic : permanent.getStatics()) {
addStatic(permanent, mstatic);
}
}
public void addStatics(final MagicPermanent permanent, final Collection<MagicStatic> mstatics) {
for (final MagicStatic mstatic : mstatics) {
addStatic(permanent, mstatic);
}
}
public Collection<MagicPermanentStatic> removeSelfStatics(final MagicPermanent permanent) {
return statics.remove(permanent, permanent.getStatics());
}
2013-06-23 18:33:35 -07:00
public Collection<MagicPermanentStatic> removeAllStatics(final MagicPermanent permanent) {
2013-04-12 19:32:25 -07:00
return statics.remove(permanent);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addStatic(final MagicPermanent permanent, final MagicStatic mstatic) {
addStatic(new MagicPermanentStatic(getUniqueId(),permanent,mstatic));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addStatic(final MagicPermanentStatic permanentStatic) {
statics.add(permanentStatic);
}
public void addStatics(final Collection<MagicPermanentStatic> aStatics) {
for (final MagicPermanentStatic mpstatic : aStatics) {
addStatic(mpstatic);
}
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public Collection<MagicPermanentStatic> getStatics(final MagicLayer layer) {
return statics.get(layer);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public Collection<MagicPermanentStatic> removeTurnStatics() {
return statics.removeTurn();
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void removeStatic(final MagicPermanent permanent,final MagicStatic mstatic) {
statics.remove(permanent, mstatic);
}
public void removeStatics(final MagicPermanent permanent,final Collection<MagicStatic> mstatics) {
statics.remove(permanent, mstatics);
}
2013-04-12 19:32:25 -07:00
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
// ***** TRIGGERS *****
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
/** Executes triggers immediately when they have no choices, otherwise ignore them. */
public void setImmediate(final boolean aImmediate) {
immediate = aImmediate;
}
2013-07-13 18:39:23 -07:00
public boolean isImmediate() {
return immediate;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPermanentTrigger addTrigger(final MagicPermanent permanent, final MagicTrigger<?> trigger) {
return addTrigger(new MagicPermanentTrigger(getUniqueId(),permanent,trigger));
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPermanentTrigger addTrigger(final MagicPermanentTrigger permanentTrigger) {
additionalTriggers.add(permanentTrigger);
2013-04-12 19:32:25 -07:00
return permanentTrigger;
}
public MagicPermanentTrigger addTurnTrigger(final MagicPermanent permanent,final MagicTrigger<?> trigger) {
final MagicPermanentTrigger permanentTrigger = addTrigger(permanent,trigger);
turnTriggers.add(permanentTrigger);
return permanentTrigger;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void addTurnTriggers(final List<MagicPermanentTrigger> triggersList) {
for (final MagicPermanentTrigger permanentTrigger : triggersList) {
addTrigger(permanentTrigger);
}
turnTriggers.addAll(triggersList);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void removeTurnTrigger(final MagicPermanentTrigger permanentTrigger) {
additionalTriggers.remove(permanentTrigger);
2013-04-12 19:32:25 -07:00
turnTriggers.remove(permanentTrigger);
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public void removeTrigger(final MagicPermanentTrigger permanentTrigger) {
additionalTriggers.remove(permanentTrigger);
2013-04-12 19:32:25 -07:00
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public MagicPermanentTrigger removeTrigger(final MagicPermanent permanent, MagicTrigger<?> trigger) {
return additionalTriggers.remove(permanent, trigger);
2013-04-12 19:32:25 -07:00
}
public List<MagicPermanentTrigger> removeTurnTriggers() {
if (turnTriggers.isEmpty()) {
return Collections.emptyList();
}
final MagicPermanentTriggerList removedTriggers = new MagicPermanentTriggerList(turnTriggers);
for (final MagicPermanentTrigger permanentTrigger : removedTriggers) {
removeTurnTrigger(permanentTrigger);
}
return removedTriggers;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public Collection<MagicPermanentTrigger> removeTriggers(final MagicPermanent permanent) {
return additionalTriggers.remove(permanent);
2013-04-12 19:32:25 -07:00
}
public <T> void executeTrigger(
final MagicTrigger<T> trigger,
final MagicPermanent permanent,
final MagicSource source,
final T data) {
2013-06-23 18:33:35 -07:00
if (trigger.accept(permanent, data) == false) {
2013-04-12 19:32:25 -07:00
return;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
final MagicEvent event=trigger.executeTrigger(this,permanent,data);
2013-06-23 18:33:35 -07:00
2013-07-07 22:17:04 -07:00
if (event.isValid() == false) {
2013-04-12 19:32:25 -07:00
return;
}
2013-06-23 18:33:35 -07:00
if (immediate) {
if (event.hasChoice()) {
// ignore
2013-05-05 02:10:07 -07:00
} else if (trigger.usesStack()) {
doAction(new MagicPutItemOnStackAction(new MagicTriggerOnStack(event)));
2013-05-05 02:10:07 -07:00
} else {
2013-06-23 18:33:35 -07:00
executeEvent(event, MagicEvent.NO_CHOICE_RESULTS);
}
2013-04-12 19:32:25 -07:00
} else if (trigger.usesStack()) {
doAction(new MagicPutItemOnStackAction(new MagicTriggerOnStack(event)));
} else {
2013-06-23 18:33:35 -07:00
addEvent(event);
2013-04-12 19:32:25 -07:00
}
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
public <T> void executeTrigger(final MagicTriggerType type,final T data) {
final Collection<MagicPermanentTrigger> typeTriggers=triggers.get(type);
2013-04-12 19:32:25 -07:00
if (typeTriggers.isEmpty()) {
return;
}
2013-06-23 18:33:35 -07:00
2013-04-12 19:32:25 -07:00
final Collection<MagicPermanentTrigger> copiedTriggers=new ArrayList<MagicPermanentTrigger>(typeTriggers);
for (final MagicPermanentTrigger permanentTrigger : copiedTriggers) {
final MagicPermanent permanent = permanentTrigger.getPermanent();
2014-03-19 23:13:46 -07:00
@SuppressWarnings("unchecked")
2013-04-12 19:32:25 -07:00
final MagicTrigger<T> trigger = (MagicTrigger<T>)permanentTrigger.getTrigger();
executeTrigger(trigger,permanent,permanent,data);
}
}
public void setConceded(final boolean b) {
isConceded = true;
}
public boolean isConceded() {
return isConceded;
}
2013-04-12 19:32:25 -07:00
}