From 86cddd0cbaa586004af4f44459189cb1d064ae93 Mon Sep 17 00:00:00 2001 From: marcins78 Date: Tue, 23 Oct 2012 15:22:50 +0000 Subject: [PATCH] - Changed how Muster works now. At the start of the regroup phase, one of your muster cards will light up (unfortunately all optional effects have to be used via cards). If you want to use Muster, just click the card (right-click to be sure what effect you're using). Then you choose which cards you want to discard, up to the number of Muster cards you have. All cards are discarded and then you draw an equal number of cards. --- .../ChooseAndDiscardCardsFromHandEffect.java | 27 ++++++++--- .../lotro/logic/timing/rules/MusterRule.java | 46 ++++++++++++------- .../lotro/at/IndividualCardAtTest.java | 15 +++++- .../src/main/webapp/includes/changeLog.html | 4 ++ 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ChooseAndDiscardCardsFromHandEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ChooseAndDiscardCardsFromHandEffect.java index 2f3040d2a..58afd02e2 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ChooseAndDiscardCardsFromHandEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ChooseAndDiscardCardsFromHandEffect.java @@ -7,6 +7,8 @@ import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.SubAction; import com.gempukku.lotro.logic.decisions.CardsSelectionDecision; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator; +import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator; import com.gempukku.lotro.logic.timing.AbstractSubActionEffect; import com.gempukku.lotro.logic.timing.Action; import com.gempukku.lotro.logic.timing.Effect; @@ -18,11 +20,12 @@ public class ChooseAndDiscardCardsFromHandEffect extends AbstractSubActionEffect private Action _action; private String _playerId; private boolean _forced; - private int _minimum; - private int _maximum; + private Evaluator _minimum; + private Evaluator _maximum; private Filterable[] _filter; + private String _text = "Choose cards to discard"; - public ChooseAndDiscardCardsFromHandEffect(Action action, String playerId, boolean forced, int minimum, int maximum, Filterable... filters) { + public ChooseAndDiscardCardsFromHandEffect(Action action, String playerId, boolean forced, Evaluator minimum, Evaluator maximum, Filterable... filters) { _action = action; _playerId = playerId; _forced = forced; @@ -31,6 +34,10 @@ public class ChooseAndDiscardCardsFromHandEffect extends AbstractSubActionEffect _filter = filters; } + public ChooseAndDiscardCardsFromHandEffect(Action action, String playerId, boolean forced, int minimum, int maximum, Filterable... filters) { + this(action, playerId, forced, new ConstantEvaluator(minimum), new ConstantEvaluator(maximum), filters); + } + public ChooseAndDiscardCardsFromHandEffect(Action action, String playerId, boolean forced, int count, Filterable... filters) { this(action, playerId, forced, count, count, filters); } @@ -43,6 +50,10 @@ public class ChooseAndDiscardCardsFromHandEffect extends AbstractSubActionEffect this(action, playerId, forced, 1); } + public void setText(String text) { + _text = text; + } + @Override public Effect.Type getType() { return null; @@ -55,7 +66,8 @@ public class ChooseAndDiscardCardsFromHandEffect extends AbstractSubActionEffect @Override public boolean isPlayableInFull(LotroGame game) { - return Filters.filter(game.getGameState().getHand(_playerId), game.getGameState(), game.getModifiersQuerying(), _filter).size() >= _minimum; + return Filters.filter(game.getGameState().getHand(_playerId), game.getGameState(), game.getModifiersQuerying(), _filter).size() + >= _minimum.evaluateExpression(game.getGameState(), game.getModifiersQuerying(), null); } @Override @@ -64,16 +76,17 @@ public class ChooseAndDiscardCardsFromHandEffect extends AbstractSubActionEffect return; Collection hand = Filters.filter(game.getGameState().getHand(_playerId), game.getGameState(), game.getModifiersQuerying(), _filter); - int maximum = Math.min(_maximum, hand.size()); + int maximum = Math.min(_maximum.evaluateExpression(game.getGameState(), game.getModifiersQuerying(), null), hand.size()); - if (hand.size() <= _minimum) { + int minimum = _minimum.evaluateExpression(game.getGameState(), game.getModifiersQuerying(), null); + if (hand.size() <= minimum) { SubAction subAction = new SubAction(_action); subAction.appendEffect(new DiscardCardsFromHandEffect(_action.getActionSource(), _playerId, hand, _forced)); processSubAction(game, subAction); cardsBeingDiscardedCallback(hand); } else { game.getUserFeedback().sendAwaitingDecision(_playerId, - new CardsSelectionDecision(1, "Choose cards to discard", hand, _minimum, maximum) { + new CardsSelectionDecision(1, _text, hand, minimum, maximum) { @Override public void decisionMade(String result) throws DecisionResultInvalidException { Set cards = getSelectedCardsByResponse(result); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/MusterRule.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/MusterRule.java index 2b89f92dc..27ad08954 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/MusterRule.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/rules/MusterRule.java @@ -5,15 +5,19 @@ import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.game.AbstractActionProxy; import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.GameState; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.game.state.actions.DefaultActionsEnvironment; -import com.gempukku.lotro.logic.GameUtils; import com.gempukku.lotro.logic.actions.OptionalTriggerAction; import com.gempukku.lotro.logic.effects.ChooseAndDiscardCardsFromHandEffect; import com.gempukku.lotro.logic.effects.DrawCardsEffect; +import com.gempukku.lotro.logic.modifiers.ModifiersQuerying; +import com.gempukku.lotro.logic.modifiers.evaluator.ConstantEvaluator; +import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator; import com.gempukku.lotro.logic.timing.EffectResult; -import java.util.LinkedList; +import java.util.Collection; +import java.util.Collections; import java.util.List; public class MusterRule { @@ -27,25 +31,33 @@ public class MusterRule { _actionsEnvironment.addAlwaysOnActionProxy( new AbstractActionProxy() { @Override - public List getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult) { + public List getOptionalAfterTriggers(final String playerId, final LotroGame game, EffectResult effectResult) { if (effectResult.getType() == EffectResult.Type.START_OF_PHASE && game.getGameState().getCurrentPhase() == Phase.REGROUP && game.getGameState().getHand(playerId).size() > 0) { - List actions = new LinkedList(); - for (PhysicalCard musterCard : Filters.filterActive(game.getGameState(), game.getModifiersQuerying(), Keyword.MUSTER)) { - if (playerId.equals(musterCard.getOwner())) { - OptionalTriggerAction action = new OptionalTriggerAction("muster" + musterCard.getCardId(), musterCard); - action.setMessage(playerId + " uses Muster from " + GameUtils.getCardLink(musterCard)); - action.setText("Use Muster"); - action.appendCost( - new ChooseAndDiscardCardsFromHandEffect(action, playerId, false, 1)); - action.appendEffect( - new DrawCardsEffect(action, playerId, 1)); - actions.add(action); - } - } + PhysicalCard firstMuster = Filters.findFirstActive(game.getGameState(), game.getModifiersQuerying(), Filters.owner(playerId), Keyword.MUSTER); + if (firstMuster != null) { + final OptionalTriggerAction action = new OptionalTriggerAction("muster", firstMuster); + action.setText("Use Muster"); + ChooseAndDiscardCardsFromHandEffect effect = new ChooseAndDiscardCardsFromHandEffect(action, playerId, false, + new ConstantEvaluator(0), new Evaluator() { + @Override + public int evaluateExpression(GameState gameState, ModifiersQuerying modifiersQuerying, PhysicalCard cardAffected) { + return Filters.filterActive(gameState, modifiersQuerying, Filters.owner(playerId), Keyword.MUSTER).size(); + } + }) { + @Override + protected void cardsBeingDiscardedCallback(Collection cardsBeingDiscarded) { + if (cardsBeingDiscarded.size() > 0) + action.appendEffect( + new DrawCardsEffect(action, playerId, cardsBeingDiscarded.size())); + } + }; + effect.setText("Choose cards to discard to Muster"); + action.appendEffect(effect); - return actions; + return Collections.singletonList(action); + } } return null; } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java index 6fd82bb6e..6303333c9 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/IndividualCardAtTest.java @@ -227,8 +227,10 @@ public class IndividualCardAtTest extends AbstractAtTest { skipMulligans(); PhysicalCardImpl mumakChieftain = new PhysicalCardImpl(100, "10_45", P1, _library.getLotroCardBlueprint("10_45")); + PhysicalCardImpl mumakChieftain2 = new PhysicalCardImpl(101, "10_45", P1, _library.getLotroCardBlueprint("10_45")); _game.getGameState().addCardToZone(_game, mumakChieftain, Zone.HAND); + _game.getGameState().addCardToZone(_game, mumakChieftain2, Zone.DECK); // End fellowship phase playerDecided(P1, ""); @@ -241,9 +243,20 @@ public class IndividualCardAtTest extends AbstractAtTest { assertEquals(1, _game.getGameState().getWounds(_game.getGameState().getRingBearer(P1))); assertEquals(1, _game.getGameState().getHand(P1).size()); + final AwaitingDecision musterUseDecision = _userFeedback.getAwaitingDecision(P1); + assertEquals(AwaitingDecisionType.CARD_ACTION_CHOICE, musterUseDecision.getDecisionType()); + validateContents(new String[]{"" + _game.getGameState().getRingBearer(P1).getCardId()}, ((String[]) musterUseDecision.getDecisionParameters().get("cardId"))); playerDecided(P1, "0"); - assertEquals(0, _game.getGameState().getHand(P1).size()); + final AwaitingDecision musterDiscardDecision = _userFeedback.getAwaitingDecision(P1); + assertEquals(AwaitingDecisionType.CARD_SELECTION, musterDiscardDecision.getDecisionType()); + validateContents(new String[]{"" + mumakChieftain.getCardId()}, ((String[]) musterDiscardDecision.getDecisionParameters().get("cardId"))); + playerDecided(P1, ((String[]) musterDiscardDecision.getDecisionParameters().get("cardId"))[0]); + + assertEquals(1, _game.getGameState().getHand(P1).size()); + + assertEquals(Zone.HAND, mumakChieftain2.getZone()); + assertEquals(Phase.REGROUP, _game.getGameState().getCurrentPhase()); } @Test diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/includes/changeLog.html b/gemp-lotr/gemp-lotr-web/src/main/webapp/includes/changeLog.html index 25dc93695..e714297b4 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/includes/changeLog.html +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/includes/changeLog.html @@ -1,6 +1,10 @@
 23 Oct. 2012
 - "Harrowdale" might be working fine this time around.
+- Changed how Muster works now. At the start of the regroup phase, one of your muster cards will light up (unfortunately
+all optional effects have to be used via cards). If you want to use Muster, just click the card (right-click to be sure
+what effect you're using). Then you choose which cards you want to discard, up to the number of Muster cards you have.
+All cards are discarded and then you draw an equal number of cards.
 
 16 Oct. 2012
 - "Down to the Last Child" now triggers on companion/ally losing skirmish, not Uruk-hai winning, so if companion loses