Cleaning up play actions procedure.

This commit is contained in:
marcins78@gmail.com
2011-09-01 21:48:47 +00:00
parent e460d97b97
commit c6f2aa7e41
9 changed files with 136 additions and 83 deletions

View File

@@ -23,7 +23,8 @@ public class AbstractAttachableFPPossession extends AbstractAttachable {
protected void appendTransferPossessionAction(List<Action> actions, LotroGame game, PhysicalCard self, Filter validTargetFilter) {
GameState gameState = game.getGameState();
if (gameState.getCurrentPhase() == Phase.FELLOWSHIP
if (Filters.canSpot(gameState, game.getModifiersQuerying(), validTargetFilter)
&& gameState.getCurrentPhase() == Phase.FELLOWSHIP
&& self.getZone() == Zone.ATTACHED) {
Filter vaildTransferFilter;

View File

@@ -42,7 +42,8 @@ public class Card1_034 extends AbstractAlly {
appendPlayAllyActions(actions, game, self);
appendHealAllyActions(actions, game, self);
if (PlayConditions.canUseFPCardDuringPhase(game.getGameState(), Phase.FELLOWSHIP, self)) {
if (PlayConditions.canUseFPCardDuringPhase(game.getGameState(), Phase.FELLOWSHIP, self)
&& PlayConditions.canExert(game.getGameState(), game.getModifiersQuerying(), self)) {
final CostToEffectAction action = new CostToEffectAction(self, Keyword.FELLOWSHIP, "Exert Celeborn to Heal an ELVEN ally");
action.addCost(new ExertCharacterEffect(self));
action.addEffect(new ChooseActiveCardEffect(playerId, "Choose an ELVEN ally", Filters.culture(Culture.ELVEN), Filters.type(CardType.ALLY)) {

View File

@@ -0,0 +1,60 @@
package com.gempukku.lotro.logic.decisions;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.logic.timing.Action;
import java.util.List;
public abstract class ActionSelectionDecision extends AbstractAwaitingDecision {
private List<? extends Action> _actions;
public ActionSelectionDecision(int decisionId, String text, List<? extends Action> actions) {
super(decisionId, text, AwaitingDecisionType.ACTION_CHOICE);
_actions = actions;
setParam("actionId", getActionIds(actions));
setParam("blueprintId", getCardIds(actions));
setParam("actionText", getActionTexts(actions));
}
private String[] getActionIds(List<? extends Action> actions) {
String[] result = new String[actions.size()];
for (int i = 0; i < result.length; i++)
result[i] = String.valueOf(i);
return result;
}
private String[] getCardIds(List<? extends Action> actions) {
String[] result = new String[actions.size()];
for (int i = 0; i < result.length; i++) {
PhysicalCard physicalCard = actions.get(i).getActionSource();
if (physicalCard != null)
result[i] = String.valueOf(physicalCard.getBlueprintId());
else
result[i] = "rules";
}
return result;
}
private String[] getActionTexts(List<? extends Action> actions) {
String[] result = new String[actions.size()];
for (int i = 0; i < result.length; i++)
result[i] = actions.get(i).getText();
return result;
}
protected Action getSelectedAction(String result) throws DecisionResultInvalidException {
if (result.equals(""))
throw new DecisionResultInvalidException();
try {
int actionIndex = Integer.parseInt(result);
if (actionIndex < 0 || actionIndex >= _actions.size())
throw new DecisionResultInvalidException();
return _actions.get(actionIndex);
} catch (NumberFormatException exp) {
throw new DecisionResultInvalidException();
}
}
}

View File

@@ -1,5 +1,5 @@
package com.gempukku.lotro.logic.decisions;
public enum AwaitingDecisionType {
INTEGER, MULTIPLE_CHOICE, ARBITRARY_CARDS, ACTION_CHOICE, CARD_SELECTION, ACTION_ORDER, ASSIGN_MINIONS
INTEGER, MULTIPLE_CHOICE, ARBITRARY_CARDS, CARD_ACTION_CHOICE, ACTION_CHOICE, CARD_SELECTION, ASSIGN_MINIONS
}

View File

@@ -4,12 +4,12 @@ import com.gempukku.lotro.logic.timing.Action;
import java.util.List;
public abstract class ActionsSelectionDecision extends AbstractAwaitingDecision {
public abstract class CardActionSelectionDecision extends AbstractAwaitingDecision {
private List<? extends Action> _actions;
private boolean _optional;
public ActionsSelectionDecision(int decisionId, String text, List<? extends Action> actions, boolean optional) {
super(decisionId, text, AwaitingDecisionType.ACTION_CHOICE);
public CardActionSelectionDecision(int decisionId, String text, List<? extends Action> actions, boolean optional) {
super(decisionId, text, AwaitingDecisionType.CARD_ACTION_CHOICE);
_actions = actions;
_optional = optional;

View File

@@ -4,16 +4,17 @@ import com.gempukku.lotro.communication.UserFeedback;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.PlayOrder;
import com.gempukku.lotro.logic.actions.CostToEffectAction;
import com.gempukku.lotro.logic.decisions.AbstractAwaitingDecision;
import com.gempukku.lotro.logic.decisions.ActionsSelectionDecision;
import com.gempukku.lotro.logic.decisions.AwaitingDecisionType;
import com.gempukku.lotro.logic.decisions.ActionSelectionDecision;
import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect;
import com.gempukku.lotro.logic.timing.actions.SystemAction;
import com.gempukku.lotro.logic.timing.processes.GameProcess;
import com.gempukku.lotro.logic.timing.processes.pregame.BiddingGameProcess;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
// Action generates multiple Effects, both costs and result of an action are Effects.
@@ -34,7 +35,7 @@ public class TurnProcedure {
}
public void carryOutPendingActionsUntilDecisionNeeded() {
while (!_userFeedback.hasPendingDecisions() && _game.getGameState().getWinnerPlayerId() == null) {
while (!_userFeedback.hasPendingDecisions() && (_game.getGameState() == null || _game.getGameState().getWinnerPlayerId() == null)) {
if (_actionStack.isEmpty()) {
if (_playedGameProcess) {
_gameProcess = _gameProcess.getNextProcess();
@@ -100,7 +101,10 @@ public class TurnProcedure {
if (!_checkedIsAboutToOptionalResponses) {
_checkedIsAboutToOptionalResponses = true;
EffectResult effectResult = _effect.getRespondableResult();
return new StackActionEffect(new PlayoutOptionalIsAboutToResponsesAction(_effect, effectResult));
Map<String, List<Action>> optionalBeforeTriggers = _game.getActionsEnvironment().getOptionalBeforeTriggers(_game.getGameState().getPlayerOrder().getAllPlayers(), _effect, effectResult);
CostToEffectAction action = new CostToEffectAction(null, null, null);
action.addEffect(new PlayoutOptionalBeforeResponsesEffect(action, optionalBeforeTriggers, _game.getGameState().getPlayerOrder().getCounterClockwisePlayOrder(_game.getGameState().getCurrentPlayerId(), true), 0, _effect, effectResult));
return new StackActionEffect(action);
}
if (!_effectPlayed) {
if (_effect.canPlayEffect(_game))
@@ -135,6 +139,56 @@ public class TurnProcedure {
}
}
private class PlayoutOptionalBeforeResponsesEffect extends UnrespondableEffect {
private CostToEffectAction _action;
private Map<String, List<Action>> _actionMap = new HashMap<String, List<Action>>();
private PlayOrder _playOrder;
private int _passCount;
private Effect _effect;
private EffectResult _effectResult;
private PlayoutOptionalBeforeResponsesEffect(CostToEffectAction action, Map<String, List<Action>> actionMap, PlayOrder playOrder, int passCount, Effect effect, EffectResult effectResult) {
_action = action;
_actionMap = actionMap;
_playOrder = playOrder;
_passCount = passCount;
_effect = effect;
_effectResult = effectResult;
}
@Override
public void playEffect(LotroGame game) {
if (!_effect.isCancelled()) {
final String activePlayer = _playOrder.getNextPlayer();
List<Action> possibleActions = _actionMap.get(activePlayer);
possibleActions.addAll(_game.getActionsEnvironment().getOptionalAfterActions(activePlayer, _effectResult));
if (possibleActions.size() > 0) {
_game.getUserFeedback().sendAwaitingDecision(activePlayer,
new CardActionSelectionDecision(1, "Choose action to play or DONE", possibleActions, true) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);
if (action != null) {
_game.getActionsEnvironment().addActionToStack(action);
_actionMap.get(activePlayer).remove(action);
_action.addEffect(new PlayoutOptionalAfterResponsesEffect(_action, _actionMap, _playOrder, 0, _effectResult));
} else {
if ((_passCount + 1) < _playOrder.getPlayerCount()) {
_action.addEffect(new PlayoutOptionalAfterResponsesEffect(_action, _actionMap, _playOrder, _passCount + 1, _effectResult));
}
}
}
});
} else {
if ((_passCount + 1) < _playOrder.getPlayerCount()) {
_action.addEffect(new PlayoutOptionalAfterResponsesEffect(_action, _actionMap, _playOrder, _passCount + 1, _effectResult));
}
}
}
}
}
private class PlayoutOptionalAfterResponsesEffect extends UnrespondableEffect {
private CostToEffectAction _action;
private Map<String, List<Action>> _actionMap = new HashMap<String, List<Action>>();
@@ -158,7 +212,7 @@ public class TurnProcedure {
if (possibleActions.size() > 0) {
_game.getUserFeedback().sendAwaitingDecision(activePlayer,
new ActionsSelectionDecision(1, "Choose action to play or DONE", possibleActions, true) {
new CardActionSelectionDecision(1, "Choose action to play or DONE", possibleActions, true) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);
@@ -199,7 +253,7 @@ public class TurnProcedure {
_game.getActionsEnvironment().addActionToStack(_actions.get(0));
} else {
_game.getUserFeedback().sendAwaitingDecision(_game.getGameState().getCurrentPlayerId(),
new ActionsSelectionDecision(1, "Choose action to play now", _actions, false) {
new ActionSelectionDecision(1, "Choose action to play now", _actions) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);
@@ -213,32 +267,6 @@ public class TurnProcedure {
}
}
private class ChooseActionsOrderDecision extends AbstractAwaitingDecision {
private List<Action> _actions;
private ChooseActionsOrderDecision(List<Action> actions) {
super(1, "Choose order of these actions", AwaitingDecisionType.ACTION_ORDER);
_actions = actions;
}
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
String[] split = result.split(" ");
if (split.length != _actions.size())
throw new DecisionResultInvalidException();
List<String> order = Arrays.asList(split);
for (int i = 0; i < _actions.size(); i++)
if (!order.contains(String.valueOf(i)))
throw new DecisionResultInvalidException();
Collections.reverse(order);
// We need to stack them in reverse order, so that we can play them out from top to bottom
for (String index : order)
_actionStack.stackAction(_actions.get(Integer.parseInt(index)));
}
}
private class StackActionEffect extends UnrespondableEffect {
private Action _action;
@@ -251,41 +279,4 @@ public class TurnProcedure {
_actionStack.stackAction(_action);
}
}
private class PlayoutOptionalIsAboutToResponsesAction extends SystemAction {
private Effect _effect;
private EffectResult _effectResult;
private PlayOrder _playOrder;
private int _consecutivePassesCount = 0;
private PlayoutOptionalIsAboutToResponsesAction(Effect effect, EffectResult effectResult) {
_effect = effect;
_effectResult = effectResult;
_playOrder = _game.getGameState().getPlayerOrder().getCounterClockwisePlayOrder(_game.getGameState().getCurrentPlayerId(), true);
}
@Override
public Effect nextEffect() {
if (_effect.isCancelled())
return null;
if (_consecutivePassesCount == _playOrder.getPlayerCount())
return null;
String player = _playOrder.getNextPlayer();
List<Action> actions = _game.getActionsEnvironment().getOptionalBeforeActions(player, _effect, _effectResult);
return new PlayoutDecisionEffect(_userFeedback, player, new ActionsSelectionDecision(1, "Choose action to play or DONE", actions, true) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);
if (action == null)
_consecutivePassesCount++;
else {
_consecutivePassesCount = 0;
_actionStack.stackAction(action);
}
}
});
}
}
}

View File

@@ -1,7 +1,7 @@
package com.gempukku.lotro.logic.timing.processes.turn.general;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.decisions.ActionsSelectionDecision;
import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.processes.GameProcess;
@@ -34,7 +34,7 @@ public class PlayerPlaysPhaseActionsUntilPassesGameProcess implements GameProces
playableActions.add(action);
_game.getUserFeedback().sendAwaitingDecision(_playerId,
new ActionsSelectionDecision(1, "Choose action to play or press DONE", playableActions, true) {
new CardActionSelectionDecision(1, "Choose action to play or press DONE", playableActions, true) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);

View File

@@ -2,7 +2,7 @@ package com.gempukku.lotro.logic.timing.processes.turn.general;
import com.gempukku.lotro.game.state.LotroGame;
import com.gempukku.lotro.logic.PlayOrder;
import com.gempukku.lotro.logic.decisions.ActionsSelectionDecision;
import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.timing.Action;
import com.gempukku.lotro.logic.timing.processes.GameProcess;
@@ -40,7 +40,7 @@ public class PlayersPlayPhaseActionsInOrderGameProcess implements GameProcess {
playableActions.add(action);
_game.getUserFeedback().sendAwaitingDecision(playerId,
new ActionsSelectionDecision(1, "Choose action to play or press DONE", playableActions, true) {
new CardActionSelectionDecision(1, "Choose action to play or press DONE", playableActions, true) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);

View File

@@ -299,7 +299,7 @@ var GempLotrUI = Class.extend({
this.multipleChoiceDecision(decision);
} else if (decisionType == "ARBITRARY_CARDS") {
this.arbitraryCardsDecision(decision);
} else if (decisionType == "ACTION_CHOICE") {
} else if (decisionType == "CARD_ACTION_CHOICE") {
this.actionChoiceDecision(decision);
} else if (decisionType == "CARD_SELECTION") {
this.cardSelectionDecision(decision);