added MagicGame.addDelayedActions to perform actions later

master
melvin 2012-06-14 13:15:45 +08:00
parent 35c8a728d7
commit 491a485351
2 changed files with 40 additions and 32 deletions

View File

@ -88,6 +88,7 @@ public class MagicGame {
private MagicStep step;
private final MagicPayedCost payedCost;
private final MagicActionList actions;
private final MagicActionList delayedActions;
private MagicActionList undoPoints;
private MagicLogBook logBook;
private MagicLogMessageBuilder logMessageBuilder;
@ -140,6 +141,7 @@ public class MagicGame {
scorePlayer=visiblePlayer;
turnPlayer=startPlayer;
actions=new MagicActionList();
delayedActions=new MagicActionList();
undoPoints=new MagicActionList();
logBook=new MagicLogBook();
logMessageBuilder=new MagicLogMessageBuilder(this);
@ -202,6 +204,7 @@ public class MagicGame {
//historical items are cleared
this.actions=new MagicActionList();
this.delayedActions=new MagicActionList();
this.disableLog = true;
/*
this.undoPoints=null;
@ -486,6 +489,10 @@ public class MagicGame {
public void startActions() {
doAction(new MagicMarkerAction());
}
public void addDelayedAction(final MagicAction action) {
delayedActions.add(action);
}
public void doAction(final MagicAction action) {
actions.add(action);
@ -503,6 +510,14 @@ public class MagicGame {
public void update() {
MagicPermanent.update(this);
doDelayedActions();
}
private void doDelayedActions() {
while (!delayedActions.isEmpty()) {
final MagicAction action = delayedActions.removeFirst();
doAction(action);
}
}
public void undoActions() {
@ -516,9 +531,12 @@ public class MagicGame {
}
public void undoAllActions() {
MagicAction action = null;
while (!actions.isEmpty()) {
actions.removeLast().undoAction(this);
action = actions.removeLast();
action.undoAction(this);
}
assert action instanceof MagicMarkerAction : "last action not MagicMarkerAction";
update();
}
@ -820,34 +838,28 @@ public class MagicGame {
public void checkState() {
while (stateCheckRequired) {
update();
stateCheckRequired = false;
update();
//accumulate the state-based actions
final List<MagicAction> stateBasedActions = new ArrayList<MagicAction>();
// Check if a player has lost
for (final MagicPlayer player : players) {
if (player.getLife() <= 0) {
stateBasedActions.add(new MagicLoseGameAction(player,MagicLoseGameAction.LIFE_REASON));
addDelayedAction(new MagicLoseGameAction(player,MagicLoseGameAction.LIFE_REASON));
}
if (player.getPoison() >= LOSING_POISON) {
stateBasedActions.add(new MagicLoseGameAction(player,MagicLoseGameAction.POISON_REASON));
addDelayedAction(new MagicLoseGameAction(player,MagicLoseGameAction.POISON_REASON));
}
}
// Check permanents' state
for (final MagicPlayer player : players) {
for (final MagicPermanent permanent : player.getPermanents()) {
permanent.checkState(this, stateBasedActions);
}
}
for (final MagicPermanent permanent : player.getPermanents()) {
permanent.checkState();
}}
//perform all the actions at once
for (final MagicAction action : stateBasedActions) {
doAction(action);
}
doDelayedActions();
//some action may set stateCheckRequired to true, if so loop again
}
}

View File

@ -261,19 +261,14 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
public static void updateScoreFixController(final MagicGame game) {
final List<MagicAction> actions = new ArrayList<MagicAction>();
for (final MagicPlayer player : game.getPlayers()) {
for (final MagicPermanent perm : player.getPermanents()) {
final MagicPlayer curr = perm.getController();
if (!curr.controlsPermanent(perm)) {
actions.add(new MagicChangeControlAction(curr, perm, perm.getScore()));
game.addDelayedAction(new MagicChangeControlAction(curr, perm, perm.getScore()));
}
perm.updateScore();
}}
for (final MagicAction action : actions) {
game.doAction(action);
}
}
public static void updateProperties(final MagicGame game) {
@ -329,7 +324,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
mstatic.getPowerToughness(game, this, cachedPowerToughness);
break;
default:
throw new RuntimeException(layer + " not handled in MagicPermanent.apply");
throw new RuntimeException("No case for " + layer + " in MagicPermanent.apply");
}
}
@ -570,17 +565,18 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
chosenTarget = target;
}
void checkState(final MagicGame game, final List<MagicAction> actions) {
void checkState() {
final MagicGame game = getGame();
if (isCreature()) {
final int toughness=getToughness();
if (toughness<=0) {
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
actions.add(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
} else if (hasState(MagicPermanentState.Destroyed)) {
actions.add(new MagicChangeStateAction(this,MagicPermanentState.Destroyed,false));
actions.add(new MagicDestroyAction(this));
game.addDelayedAction(new MagicChangeStateAction(this,MagicPermanentState.Destroyed,false));
game.addDelayedAction(new MagicDestroyAction(this));
} else if (toughness-damage<=0) {
actions.add(new MagicDestroyAction(this));
game.addDelayedAction(new MagicDestroyAction(this));
}
// Soulbond
@ -598,13 +594,13 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
!game.isLegalTarget(getController(),this,tchoice,enchantedCreature) ||
enchantedCreature.hasProtectionFrom(this)) {
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
actions.add(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
}
}
if (cardDefinition.isEquipment() && equippedCreature.isValid()) {
if (isCreature() || !equippedCreature.isCreature() || equippedCreature.hasProtectionFrom(this)) {
actions.add(new MagicAttachEquipmentAction(this,MagicPermanent.NONE));
game.addDelayedAction(new MagicAttachEquipmentAction(this,MagicPermanent.NONE));
}
}
@ -614,8 +610,8 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
final int minusCounters=getCounters(MagicCounterType.MinusOne);
if (minusCounters>0) {
final int amount=-Math.min(plusCounters,minusCounters);
actions.add(new MagicChangeCountersAction(this,MagicCounterType.PlusOne,amount,false));
actions.add(new MagicChangeCountersAction(this,MagicCounterType.MinusOne,amount,false));
game.addDelayedAction(new MagicChangeCountersAction(this,MagicCounterType.PlusOne,amount,false));
game.addDelayedAction(new MagicChangeCountersAction(this,MagicCounterType.MinusOne,amount,false));
}
}
}