From 5d21fa793d052634022faf731cb4f6d07379351c Mon Sep 17 00:00:00 2001 From: marcins78 Date: Wed, 24 Oct 2012 14:50:44 +0000 Subject: [PATCH] - 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. --- .../lotro/logic/timing/TurnProcedure.java | 46 ++++++++++++- .../com/gempukku/lotro/at/AbstractAtTest.java | 8 +++ .../com/gempukku/lotro/at/TimingAtTest.java | 68 +++++++++++++++++++ 3 files changed, 119 insertions(+), 3 deletions(-) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/TurnProcedure.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/TurnProcedure.java index ff8cc1b40..e2615a7f7 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/TurnProcedure.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/TurnProcedure.java @@ -104,9 +104,7 @@ public class TurnProcedure { public Effect nextEffect(LotroGame game) { if (!_initialized) { _initialized = true; - List requiredIsAboutToResponses = _game.getActionsEnvironment().getRequiredBeforeTriggers(_effect); - if (requiredIsAboutToResponses.size() > 0) - appendEffect(new PlayoutAllActionsIfEffectNotCancelledEffect(this, requiredIsAboutToResponses)); + appendEffect(new PlayoutRequiredBeforeResponsesEffect(this, new HashSet(), _effect)); appendEffect(new PlayoutOptionalBeforeResponsesEffect(this, new HashSet(), _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 _cardTriggersUsed; + private Effect _effect; + + private PlayoutRequiredBeforeResponsesEffect(SystemQueueAction action, Set cardTriggersUsed, Effect effect) { + _action = action; + _cardTriggersUsed = cardTriggersUsed; + _effect = effect; + } + + @Override + protected void doPlayEffect(LotroGame game) { + final List requiredBeforeTriggers = game.getActionsEnvironment().getRequiredBeforeTriggers(_effect); + // Remove triggers already resolved + final Iterator 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 _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()) { diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java index 5a460938d..ac2cff023 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/AbstractAtTest.java @@ -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++) diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/TimingAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/TimingAtTest.java index 897e62675..c616dcaf9 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/TimingAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/TimingAtTest.java @@ -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 decks = new HashMap(); + 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()); + } }