diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/TriggerConditions.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/TriggerConditions.java index 0f4d95f58..ba8886816 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/TriggerConditions.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/TriggerConditions.java @@ -107,6 +107,30 @@ public class TriggerConditions { return false; } + public static boolean forEachCardDrawnOrPutIntoHandByOpponent(LotroGame game, EffectResult effectResult, String playerId) { + if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND) { + DrawCardOrPutIntoHandResult drawResult = (DrawCardOrPutIntoHandResult) effectResult; + return !drawResult.getPlayerId().equals(playerId); + } + return false; + } + + public static boolean forEachCardDrawnOrPutIntoHand(LotroGame game, EffectResult effectResult, String playerId) { + if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND) { + DrawCardOrPutIntoHandResult drawResult = (DrawCardOrPutIntoHandResult) effectResult; + return drawResult.getPlayerId().equals(playerId); + } + return false; + } + + public static boolean forEachCardDrawn(LotroGame game, EffectResult effectResult, String playerId) { + if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND) { + DrawCardOrPutIntoHandResult drawResult = (DrawCardOrPutIntoHandResult) effectResult; + return drawResult.isDraw() && drawResult.getPlayerId().equals(playerId); + } + return false; + } + public static boolean forEachDiscardedFromPlay(LotroGame game, EffectResult effectResult, Filterable... filters) { if (effectResult.getType() == EffectResult.Type.FOR_EACH_DISCARDED_FROM_PLAY) return Filters.and(filters).accepts(game.getGameState(), game.getModifiersQuerying(), ((DiscardCardsFromPlayResult) effectResult).getDiscardedCard()); diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/sauron/Card2_094.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/sauron/Card2_094.java index bc6385b69..46a802009 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/sauron/Card2_094.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/sauron/Card2_094.java @@ -2,6 +2,7 @@ package com.gempukku.lotro.cards.set2.sauron; import com.gempukku.lotro.cards.AbstractAttachable; import com.gempukku.lotro.cards.PlayConditions; +import com.gempukku.lotro.cards.TriggerConditions; import com.gempukku.lotro.cards.actions.AttachPermanentAction; import com.gempukku.lotro.cards.effects.AddBurdenEffect; import com.gempukku.lotro.cards.effects.choose.ChooseAndExertCharactersEffect; @@ -12,7 +13,6 @@ import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.RequiredTriggerAction; import com.gempukku.lotro.logic.timing.EffectResult; -import com.gempukku.lotro.logic.timing.results.DrawCardOrPutIntoHandResult; import java.util.Collections; import java.util.List; @@ -52,8 +52,7 @@ public class Card2_094 extends AbstractAttachable { @Override public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND - && ((DrawCardOrPutIntoHandResult) effectResult).getPlayerId().equals(game.getGameState().getCurrentPlayerId()) + if (TriggerConditions.forEachCardDrawnOrPutIntoHand(game, effectResult, game.getGameState().getCurrentPlayerId()) && game.getGameState().getCurrentPhase() == Phase.FELLOWSHIP) { RequiredTriggerAction action = new RequiredTriggerAction(self); action.appendEffect( diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set3/gandalf/Card3_029.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set3/gandalf/Card3_029.java index 2b461b56b..6083841b8 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set3/gandalf/Card3_029.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set3/gandalf/Card3_029.java @@ -2,6 +2,7 @@ package com.gempukku.lotro.cards.set3.gandalf; import com.gempukku.lotro.cards.AbstractPermanent; import com.gempukku.lotro.cards.PlayConditions; +import com.gempukku.lotro.cards.TriggerConditions; import com.gempukku.lotro.cards.effects.RemoveTwilightEffect; import com.gempukku.lotro.cards.effects.choose.ChooseAndExertCharactersEffect; import com.gempukku.lotro.common.*; @@ -34,7 +35,7 @@ public class Card3_029 extends AbstractPermanent { @Override public List getOptionalAfterTriggers(String playerId, LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND + if (TriggerConditions.forEachCardDrawnOrPutIntoHandByOpponent(game, effectResult, playerId) && game.getGameState().getCurrentPhase() == Phase.SHADOW) { DrawCardOrPutIntoHandResult drawResult = (DrawCardOrPutIntoHandResult) effectResult; if (!drawResult.getPlayerId().equals(playerId)) { diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set7/wraith/Card7_195.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set7/wraith/Card7_195.java index 7db1b3df9..32c11e5fe 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set7/wraith/Card7_195.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set7/wraith/Card7_195.java @@ -2,6 +2,7 @@ package com.gempukku.lotro.cards.set7.wraith; import com.gempukku.lotro.cards.AbstractPermanent; import com.gempukku.lotro.cards.PlayConditions; +import com.gempukku.lotro.cards.TriggerConditions; import com.gempukku.lotro.cards.effects.SelfDiscardEffect; import com.gempukku.lotro.cards.effects.choose.ChooseAndDiscardCardsFromPlayEffect; import com.gempukku.lotro.common.*; @@ -39,7 +40,7 @@ public class Card7_195 extends AbstractPermanent { @Override public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (effectResult.getType() == EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND + if (TriggerConditions.forEachCardDrawn(game, effectResult, game.getGameState().getCurrentPlayerId()) && game.getGameState().getCurrentPhase() != Phase.REGROUP) { DrawCardOrPutIntoHandResult drawResult = (DrawCardOrPutIntoHandResult) effectResult; if (drawResult.getPlayerId().equals(game.getGameState().getCurrentPlayerId())) { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/DrawOneCardEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/DrawOneCardEffect.java index 12cd501f6..0ca89a58a 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/DrawOneCardEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/DrawOneCardEffect.java @@ -45,11 +45,11 @@ public class DrawOneCardEffect extends AbstractEffect implements Preventable { drawn++; } - if (drawn > 0) { - game.getActionsEnvironment().emitEffectResult(new DrawCardOrPutIntoHandResult(_playerId)); + if (drawn == 1) { + game.getActionsEnvironment().emitEffectResult(new DrawCardOrPutIntoHandResult(_playerId, true)); return new FullEffectResult(true, true); } else - return new FullEffectResult(false, false); + return new FullEffectResult(_prevented, false); } @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/results/DrawCardOrPutIntoHandResult.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/results/DrawCardOrPutIntoHandResult.java index 23467fc6e..7a181d5cb 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/results/DrawCardOrPutIntoHandResult.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/results/DrawCardOrPutIntoHandResult.java @@ -4,13 +4,23 @@ import com.gempukku.lotro.logic.timing.EffectResult; public class DrawCardOrPutIntoHandResult extends EffectResult { private String _playerId; + private boolean _draw; public DrawCardOrPutIntoHandResult(String playerId) { + this(playerId, false); + } + + public DrawCardOrPutIntoHandResult(String playerId, boolean draw) { super(EffectResult.Type.DRAW_CARD_OR_PUT_INTO_HAND); _playerId = playerId; + _draw = draw; } public String getPlayerId() { return _playerId; } + + public boolean isDraw() { + return _draw; + } } 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 ff83c42ab..2ba1e4c4e 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 @@ -4,9 +4,12 @@ import com.gempukku.lotro.game.DefaultUserFeedback; import com.gempukku.lotro.game.LotroCardBlueprintLibrary; import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.game.formats.MovieFormat; +import com.gempukku.lotro.logic.actions.SystemQueueAction; import com.gempukku.lotro.logic.decisions.AwaitingDecision; +import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import com.gempukku.lotro.logic.timing.DefaultLotroGame; +import com.gempukku.lotro.logic.timing.Effect; import com.gempukku.lotro.logic.vo.LotroDeck; import org.junit.BeforeClass; @@ -136,6 +139,15 @@ public abstract class AbstractAtTest { _game.carryOutPendingActionsUntilDecisionNeeded(); } + protected void carryOutEffectInPhaseActionByPlayer(String playerId, Effect effect) throws DecisionResultInvalidException { + CardActionSelectionDecision awaitingDecision = (CardActionSelectionDecision) _userFeedback.getAwaitingDecision(playerId); + SystemQueueAction action = new SystemQueueAction(); + action.appendEffect(effect); + awaitingDecision.addAction(action); + + playerDecided(playerId, "0"); + } + protected LotroDeck createSimplestDeck() { LotroDeck lotroDeck = new LotroDeck(); // 10_121,1_2 diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/DrawEffectAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/DrawEffectAtTest.java new file mode 100644 index 000000000..95b59b36f --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/DrawEffectAtTest.java @@ -0,0 +1,196 @@ +package com.gempukku.lotro.at.effects; + +import com.gempukku.lotro.at.AbstractAtTest; +import com.gempukku.lotro.cards.TriggerConditions; +import com.gempukku.lotro.game.AbstractActionProxy; +import com.gempukku.lotro.game.PhysicalCardImpl; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.actions.RequiredTriggerAction; +import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.effects.DrawCardsEffect; +import com.gempukku.lotro.logic.effects.PreventEffect; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; +import com.gempukku.lotro.logic.timing.Preventable; +import org.junit.Test; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.Assert.*; + +public class DrawEffectAtTest extends AbstractAtTest { + @Test + public void drawingSuccessful() throws DecisionResultInvalidException { + initializeSimplestGame(); + + skipMulligans(); + + final PhysicalCardImpl merry = new PhysicalCardImpl(101, "1_303", P1, _library.getLotroCardBlueprint("1_303")); + + _game.getGameState().putCardOnTopOfDeck(merry); + + final AtomicInteger triggerCount = new AtomicInteger(0); + + _game.getActionsEnvironment().addUntilEndOfTurnActionProxy( + new AbstractActionProxy() { + @Override + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult) { + if (TriggerConditions.forEachCardDrawn(game, effectResult, P1)) { + RequiredTriggerAction action = new RequiredTriggerAction(merry); + action.appendEffect( + new IncrementEffect(triggerCount)); + return Collections.singletonList(action); + } + return null; + } + }); + + DrawCardsEffect drawEffect = new DrawCardsEffect(null, P1, 1); + + carryOutEffectInPhaseActionByPlayer(P1, drawEffect); + + assertEquals(1, _game.getGameState().getHand(P1).size()); + assertEquals(0, _game.getGameState().getDeck(P1).size()); + assertTrue(_game.getGameState().getHand(P1).contains(merry)); + assertTrue(drawEffect.wasSuccessful()); + assertTrue(drawEffect.wasCarriedOut()); + + assertEquals(1, triggerCount.get()); + } + + @Test + public void drawingMultipleNotSuccessful() throws DecisionResultInvalidException { + initializeSimplestGame(); + + skipMulligans(); + + final PhysicalCardImpl merry = new PhysicalCardImpl(101, "1_303", P1, _library.getLotroCardBlueprint("1_303")); + + _game.getGameState().putCardOnTopOfDeck(merry); + + final AtomicInteger triggerCount = new AtomicInteger(0); + + _game.getActionsEnvironment().addUntilEndOfTurnActionProxy( + new AbstractActionProxy() { + @Override + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult) { + if (TriggerConditions.forEachCardDrawn(game, effectResult, P1)) { + RequiredTriggerAction action = new RequiredTriggerAction(merry); + action.appendEffect( + new IncrementEffect(triggerCount)); + return Collections.singletonList(action); + } + return null; + } + }); + + DrawCardsEffect drawEffect = new DrawCardsEffect(null, P1, 2); + + carryOutEffectInPhaseActionByPlayer(P1, drawEffect); + + assertEquals(1, _game.getGameState().getHand(P1).size()); + assertEquals(0, _game.getGameState().getDeck(P1).size()); + assertTrue(_game.getGameState().getHand(P1).contains(merry)); + assertFalse(drawEffect.wasSuccessful()); + assertFalse(drawEffect.wasCarriedOut()); + + assertEquals(1, triggerCount.get()); + } + + @Test + public void drawingMultipleSuccessful() throws DecisionResultInvalidException { + initializeSimplestGame(); + + skipMulligans(); + + final PhysicalCardImpl merry = new PhysicalCardImpl(101, "1_303", P1, _library.getLotroCardBlueprint("1_303")); + final PhysicalCardImpl merry2 = new PhysicalCardImpl(102, "1_303", P1, _library.getLotroCardBlueprint("1_303")); + + _game.getGameState().putCardOnTopOfDeck(merry); + _game.getGameState().putCardOnTopOfDeck(merry2); + + final AtomicInteger triggerCount = new AtomicInteger(0); + + _game.getActionsEnvironment().addUntilEndOfTurnActionProxy( + new AbstractActionProxy() { + @Override + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult) { + if (TriggerConditions.forEachCardDrawn(game, effectResult, P1)) { + RequiredTriggerAction action = new RequiredTriggerAction(merry); + action.appendEffect( + new IncrementEffect(triggerCount)); + return Collections.singletonList(action); + } + return null; + } + }); + + DrawCardsEffect drawEffect = new DrawCardsEffect(null, P1, 2); + + carryOutEffectInPhaseActionByPlayer(P1, drawEffect); + + assertEquals(2, _game.getGameState().getHand(P1).size()); + assertEquals(0, _game.getGameState().getDeck(P1).size()); + assertTrue(_game.getGameState().getHand(P1).contains(merry)); + assertTrue(_game.getGameState().getHand(P1).contains(merry2)); + assertTrue(drawEffect.wasSuccessful()); + assertTrue(drawEffect.wasCarriedOut()); + + assertEquals(2, triggerCount.get()); + } + + @Test + public void insteadOfDraw() throws DecisionResultInvalidException { + initializeSimplestGame(); + + skipMulligans(); + + final PhysicalCardImpl merry = new PhysicalCardImpl(101, "1_303", P1, _library.getLotroCardBlueprint("1_303")); + + _game.getGameState().putCardOnTopOfDeck(merry); + + final AtomicInteger triggerCount = new AtomicInteger(0); + final AtomicInteger preventCount = new AtomicInteger(0); + + _game.getActionsEnvironment().addUntilEndOfTurnActionProxy( + new AbstractActionProxy() { + @Override + public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult) { + if (TriggerConditions.forEachCardDrawn(game, effectResult, P1)) { + RequiredTriggerAction action = new RequiredTriggerAction(merry); + action.appendEffect( + new IncrementEffect(triggerCount)); + return Collections.singletonList(action); + } + return null; + } + + @Override + public List getRequiredBeforeTriggers(LotroGame game, Effect effect) { + if (TriggerConditions.isDrawingACard(effect, game, P1)) { + RequiredTriggerAction action = new RequiredTriggerAction(merry); + action.appendEffect( + new PreventEffect((Preventable) effect)); + action.appendEffect( + new IncrementEffect(preventCount)); + return Collections.singletonList(action); + } + return null; + } + }); + + DrawCardsEffect drawEffect = new DrawCardsEffect(null, P1, 1); + + carryOutEffectInPhaseActionByPlayer(P1, drawEffect); + + assertEquals(0, _game.getGameState().getHand(P1).size()); + assertEquals(1, _game.getGameState().getDeck(P1).size()); + assertTrue(drawEffect.wasSuccessful()); + assertFalse(drawEffect.wasCarriedOut()); + + assertEquals(0, triggerCount.get()); + assertEquals(1, preventCount.get()); + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/WoundEffectAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/WoundEffectAtTest.java index ad008813d..e270f6bbb 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/WoundEffectAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/effects/WoundEffectAtTest.java @@ -9,8 +9,6 @@ import com.gempukku.lotro.game.AbstractActionProxy; import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.game.state.LotroGame; import com.gempukku.lotro.logic.actions.RequiredTriggerAction; -import com.gempukku.lotro.logic.actions.SystemQueueAction; -import com.gempukku.lotro.logic.decisions.CardActionSelectionDecision; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import com.gempukku.lotro.logic.effects.WoundCharactersEffect; import com.gempukku.lotro.logic.modifiers.ModifierFlag; @@ -264,13 +262,4 @@ public class WoundEffectAtTest extends AbstractAtTest { assertEquals(1, triggerCount.get()); assertEquals(1, preventCount.get()); } - - private void carryOutEffectInPhaseActionByPlayer(String playerId, Effect effect) throws DecisionResultInvalidException { - CardActionSelectionDecision awaitingDecision = (CardActionSelectionDecision) _userFeedback.getAwaitingDecision(playerId); - SystemQueueAction action = new SystemQueueAction(); - action.appendEffect(effect); - awaitingDecision.addAction(action); - - playerDecided(playerId, "0"); - } }