- If two (or more) required before actions happen, FP player has a choice which one to play first. If that action prevents the effect, other required actions that depend on that effect will no longer be playable.

This commit is contained in:
marcins78
2012-10-24 14:50:44 +00:00
parent f57d334264
commit 5d21fa793d
3 changed files with 119 additions and 3 deletions

View File

@@ -104,9 +104,7 @@ public class TurnProcedure {
public Effect nextEffect(LotroGame game) {
if (!_initialized) {
_initialized = true;
List<Action> requiredIsAboutToResponses = _game.getActionsEnvironment().getRequiredBeforeTriggers(_effect);
if (requiredIsAboutToResponses.size() > 0)
appendEffect(new PlayoutAllActionsIfEffectNotCancelledEffect(this, requiredIsAboutToResponses));
appendEffect(new PlayoutRequiredBeforeResponsesEffect(this, new HashSet<PhysicalCard>(), _effect));
appendEffect(new PlayoutOptionalBeforeResponsesEffect(this, new HashSet<PhysicalCard>(), _game.getGameState().getPlayerOrder().getCounterClockwisePlayOrder(_game.getGameState().getCurrentPlayerId(), true), 0, _effect));
appendEffect(new PlayEffect(_effect));
}
@@ -180,6 +178,47 @@ public class TurnProcedure {
}
}
private class PlayoutRequiredBeforeResponsesEffect extends UnrespondableEffect {
private SystemQueueAction _action;
private Set<PhysicalCard> _cardTriggersUsed;
private Effect _effect;
private PlayoutRequiredBeforeResponsesEffect(SystemQueueAction action, Set<PhysicalCard> cardTriggersUsed, Effect effect) {
_action = action;
_cardTriggersUsed = cardTriggersUsed;
_effect = effect;
}
@Override
protected void doPlayEffect(LotroGame game) {
final List<Action> requiredBeforeTriggers = game.getActionsEnvironment().getRequiredBeforeTriggers(_effect);
// Remove triggers already resolved
final Iterator<Action> triggersIterator = requiredBeforeTriggers.iterator();
while (triggersIterator.hasNext())
if (_cardTriggersUsed.contains(triggersIterator.next().getActionSource()))
triggersIterator.remove();
if (requiredBeforeTriggers.size() == 1) {
_game.getActionsEnvironment().addActionToStack(requiredBeforeTriggers.get(0));
} else if (requiredBeforeTriggers.size() > 1) {
_game.getUserFeedback().sendAwaitingDecision(_game.getGameState().getCurrentPlayerId(),
new ActionSelectionDecision(game, 1, _effect.getText(game) + " - Required \"is about to\" responses", requiredBeforeTriggers) {
@Override
public void decisionMade(String result) throws DecisionResultInvalidException {
Action action = getSelectedAction(result);
if (action != null) {
_game.getActionsEnvironment().addActionToStack(action);
if (requiredBeforeTriggers.contains(action))
_cardTriggersUsed.add(action.getActionSource());
_game.getActionsEnvironment().addActionToStack(action);
_action.insertEffect(new PlayoutRequiredBeforeResponsesEffect(_action, _cardTriggersUsed, _effect));
}
}
});
}
}
}
private class PlayoutOptionalBeforeResponsesEffect extends UnrespondableEffect {
private SystemQueueAction _action;
private Set<PhysicalCard> _cardTriggersUsed;
@@ -271,6 +310,7 @@ public class TurnProcedure {
_game.getActionsEnvironment().addActionToStack(action);
if (optionalAfterTriggers.containsKey(action))
optionalAfterTriggers.get(action).optionalTriggerUsed((OptionalTriggerAction) action);
_action.insertEffect(new PlayoutOptionalAfterResponsesEffect(_action, _playOrder, 0, _effectResults));
} else {
if ((_passCount + 1) < _playOrder.getPlayerCount()) {

View File

@@ -111,6 +111,14 @@ public abstract class AbstractAtTest {
return null;
}
protected String getCardActionIdContains(AwaitingDecision awaitingDecision, String actionTextContains) {
String[] actionTexts = (String[]) awaitingDecision.getDecisionParameters().get("actionText");
for (int i = 0; i < actionTexts.length; i++)
if (actionTexts[i].contains(actionTextContains))
return ((String[]) awaitingDecision.getDecisionParameters().get("actionId"))[i];
return null;
}
protected String getMultipleDecisionIndex(AwaitingDecision awaitingDecision, String result) {
String[] actionTexts = (String[]) awaitingDecision.getDecisionParameters().get("results");
for (int i = 0; i < actionTexts.length; i++)

View File

@@ -18,6 +18,7 @@ import com.gempukku.lotro.logic.modifiers.Modifier;
import com.gempukku.lotro.logic.modifiers.ModifierFlag;
import com.gempukku.lotro.logic.modifiers.SpecialFlagModifier;
import com.gempukku.lotro.logic.timing.EffectResult;
import com.gempukku.lotro.logic.vo.LotroDeck;
import org.junit.Test;
import java.util.*;
@@ -346,4 +347,71 @@ public class TimingAtTest extends AbstractAtTest {
assertEquals(Zone.REMOVED, prowlingOrcInDiscard.getZone());
assertEquals(Zone.SHADOW_CHARACTERS, prowlingOrc.getZone());
}
@Test
public void twoBeforeRequiredEffectsPreventing() throws DecisionResultInvalidException {
Map<String, LotroDeck> decks = new HashMap<String, LotroDeck>();
LotroDeck p1Deck = createSimplestDeck();
p1Deck.setRingBearer("9_4");
p1Deck.setRing("4_1");
decks.put(P1, p1Deck);
decks.put(P2, createSimplestDeck());
initializeGameWithDecks(decks);
skipMulligans();
PhysicalCardImpl gimlisHelm = new PhysicalCardImpl(100, "1_15", P1, _library.getLotroCardBlueprint("1_15"));
_game.getGameState().attachCard(_game, gimlisHelm, _game.getGameState().getRingBearer(P1));
PhysicalCardImpl urukHaiRaidingParty = new PhysicalCardImpl(103, "1_158", P2, _library.getLotroCardBlueprint("1_158"));
_game.getGameState().addCardToZone(_game, urukHaiRaidingParty, Zone.SHADOW_CHARACTERS);
// End fellowship phase
playerDecided(P1, "");
// End shadow phase
playerDecided(P2, "");
// End maneuver phase
playerDecided(P1, "");
playerDecided(P2, "");
// End archery phase
playerDecided(P1, "");
playerDecided(P2, "");
// End assignment phase
playerDecided(P1, "");
playerDecided(P2, "");
playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId()+" "+urukHaiRaidingParty.getCardId());
// Choose Gimli's skirmish
playerDecided(P1, ""+_game.getGameState().getRingBearer(P1).getCardId());
assertEquals(3, _game.getGameState().getBurdens());
_game.getGameState().removeBurdens(3);
AwaitingDecision skirmishDecision = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionId(skirmishDecision, "Use The One"));
assertEquals(1, _game.getGameState().getBurdens());
playerDecided(P2, "");
AwaitingDecision skirmishSecondDecision = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionId(skirmishSecondDecision, "Use Gimli's"));
assertEquals(Zone.DISCARD, gimlisHelm.getZone());
playerDecided(P2, "");
playerDecided(P1, "");
// Prevent both wounds with Helm
AwaitingDecision beforeRequiredChoice = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionIdContains(beforeRequiredChoice, "Gimli's Helm"));
AwaitingDecision beforeRequiredSecondChoice = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionIdContains(beforeRequiredSecondChoice, "Gimli's Helm"));
assertEquals(1, _game.getGameState().getBurdens());
}
}