diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-dwarven.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-dwarven.json index 3a18b3af0..d4670f105 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-dwarven.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-dwarven.json @@ -409,6 +409,7 @@ "effect": [ { "type": "choice", + "memorize": "revealChoice", "texts": [ "Reveal top 3 cards of your deck.", "Reveal top 3 cards of your opponent's deck." @@ -417,34 +418,77 @@ { "type": "revealTopCardsOfDrawDeck", "count": 3, - "memorize": "revealedCards", + "memorize": "revealedFreepsCards", "deck": "you" }, { "type": "revealTopCardsOfDrawDeck", "count": 3, - "memorize": "revealedCards", + "memorize": "revealedShadowCards", "deck": "shadowPlayer" } ] }, { - "type": "optional", - "text": "Would you like to discard 1 Shadow card revealed?", - "effect": { - "type": "discardCardsFromDrawDeck", - "filter": "choose(side(shadow),memory(revealedCards))" - } + "type": "conditional", + "condition": { + "type": "memoryLike", + "memory": "revealChoice", + "value": "your deck" + }, + "effect": [ + { + "type": "optional", + "text": "Would you like to discard 1 Shadow card revealed?", + "effect": { + "type": "discardCardsFromDrawDeck", + "filter": "choose(side(shadow),memory(revealedFreepsCards))" + } + }, + { + "type": "reorderTopCardsOfDrawDeck", + "player": "you", + "deck": "you", + "count": { + "type": "forEachMatchingInMemory", + "memory": "revealedFreepsCards", + "filter": "zone(deck)" + } + } + ] }, { - "type": "reorderTopCardsOfDrawDeck", - "count": { - "type": "forEachMatchingInMemory", - "memory": "revealedCards", - "filter": "zone(deck)" - } - } + "type": "conditional", + "condition": { + "type": "memoryLike", + "memory": "revealChoice", + "value": "your opponent's deck" + }, + "effect": [ + { + "type": "optional", + "text": "Would you like to discard 1 Shadow card revealed?", + "effect": { + "type": "discardCardsFromDrawDeck", + "deck": "shadow", + "filter": "choose(side(shadow),memory(revealedShadowCards))" + } + }, + { + "type": "reorderTopCardsOfDrawDeck", + "player": "you", + "deck": "shadow", + "count": { + "type": "forEachMatchingInMemory", + "memory": "revealedShadowCards", + "filter": "zone(deck)" + } + } + ] + }, + + ] } }, diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Choice.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Choice.java index ff16c18ef..b4c15c476 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Choice.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Choice.java @@ -19,11 +19,12 @@ import java.util.List; public class Choice implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "player", "effects", "texts"); + FieldUtils.validateAllowedFields(effectObject, "player", "effects", "texts", "memorize"); final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); final JSONObject[] effectArray = FieldUtils.getObjectArray(effectObject.get("effects"), "effects"); final String[] textArray = FieldUtils.getStringArray(effectObject.get("texts"), "texts"); + final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); if (effectArray.length != textArray.length) throw new InvalidCardDefinitionException("Number of texts and effects does not match in choice effect"); @@ -51,12 +52,15 @@ public class Choice implements EffectAppenderProducer { textIndex++; } - if (playableEffectAppenders.size() == 0) + if (playableEffectAppenders.size() == 0) { + actionContext.setValueToMemory(memorize, ""); return null; + } if (playableEffectAppenders.size() == 1) { SubAction subAction = new SubAction(action); playableEffectAppenders.get(0).appendEffect(cost, subAction, delegateActionContext); + actionContext.setValueToMemory(memorize, textArray[0]); return new StackActionEffect(subAction); } @@ -67,6 +71,7 @@ public class Choice implements EffectAppenderProducer { @Override protected void validDecisionMade(int index, String result) { playableEffectAppenders.get(index).appendEffect(cost, subAction, delegateActionContext); + actionContext.setValueToMemory(memorize, result); } })); return new StackActionEffect(subAction); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromDrawDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromDrawDeck.java index eaa3ffba2..59ba1bbd8 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromDrawDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromDrawDeck.java @@ -1,13 +1,11 @@ package com.gempukku.lotro.cards.build.field.effect.appender; -import com.gempukku.lotro.cards.build.ActionContext; -import com.gempukku.lotro.cards.build.CardGenerationEnvironment; -import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; -import com.gempukku.lotro.cards.build.ValueSource; +import com.gempukku.lotro.cards.build.*; import com.gempukku.lotro.cards.build.field.FieldUtils; import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.CardResolver; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; import com.gempukku.lotro.game.PhysicalCard; import com.gempukku.lotro.logic.actions.CostToEffectAction; @@ -22,17 +20,19 @@ import java.util.List; public class DiscardCardsFromDrawDeck implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memorize"); + FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memorize", "player", "deck"); final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)"); final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); + final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); + final String deck = FieldUtils.getString(effectObject.get("deck"), "deck", "you"); final ValueSource countSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInDeck(filter, null, countSource, memorize, "you", "Choose cards to discard", environment)); + CardResolver.resolveCardsInDeck(filter, null, countSource, memorize, player, deck, "Choose cards to discard", environment)); result.addEffectAppender( new DelayedAppender() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PlayCardFromDrawDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PlayCardFromDrawDeck.java index d23e468c3..3c1ad82ea 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PlayCardFromDrawDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PlayCardFromDrawDeck.java @@ -47,7 +47,7 @@ public class PlayCardFromDrawDeck implements EffectAppenderProducer { } return Filters.playable(actionContext.getGame(), costModifier); }, - new ConstantEvaluator(1), memorize, "you", "Choose card to play", environment)); + new ConstantEvaluator(1), memorize, "you", "you", "Choose card to play", environment)); result.addEffectAppender( new DelayedAppender() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckIntoHand.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckIntoHand.java index 1c619940f..77d08ea4e 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckIntoHand.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckIntoHand.java @@ -32,7 +32,7 @@ public class PutCardsFromDeckIntoHand implements EffectAppenderProducer { MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment)); + CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment)); result.addEffectAppender( new DelayedAppender() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnBottomOfDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnBottomOfDeck.java index 6a14885b4..70fd40fc4 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnBottomOfDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnBottomOfDeck.java @@ -33,7 +33,7 @@ public class PutCardsFromDeckOnBottomOfDeck implements EffectAppenderProducer { MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment)); + CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment)); result.addEffectAppender( new DelayedAppender() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnTopOfDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnTopOfDeck.java index e2fdfa20b..f10d2eaec 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnTopOfDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/PutCardsFromDeckOnTopOfDeck.java @@ -34,7 +34,7 @@ public class PutCardsFromDeckOnTopOfDeck implements EffectAppenderProducer { MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp", "you", "Choose cards from deck", environment)); + CardResolver.resolveCardsInDeck(filter, valueSource, "_temp", "you", "Choose cards from deck", environment)); result.addEffectAppender( new DelayedAppender() { @Override @@ -42,7 +42,7 @@ public class PutCardsFromDeckOnTopOfDeck implements EffectAppenderProducer { final Collection cards = actionContext.getCardsFromMemory("_temp"); List result = new LinkedList<>(); for (PhysicalCard card : cards) { - result.add(new PutCardFromDeckOnTopOfDeckEffect(action.getActionSource(), card)); + result.add(new PutCardFromDeckOnTopOfDeckEffect(action.getActionSource().getOwner(), card)); } return result; diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReorderTopCardsOfDrawDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReorderTopCardsOfDrawDeck.java index 98946d2f5..d983b6076 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReorderTopCardsOfDrawDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReorderTopCardsOfDrawDeck.java @@ -1,12 +1,10 @@ package com.gempukku.lotro.cards.build.field.effect.appender; -import com.gempukku.lotro.cards.build.ActionContext; -import com.gempukku.lotro.cards.build.CardGenerationEnvironment; -import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; -import com.gempukku.lotro.cards.build.ValueSource; +import com.gempukku.lotro.cards.build.*; import com.gempukku.lotro.cards.build.field.FieldUtils; import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; +import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver; import com.gempukku.lotro.logic.actions.CostToEffectAction; import com.gempukku.lotro.logic.effects.ReorderTopCardsOfDeckEffect; @@ -17,20 +15,25 @@ import org.json.simple.JSONObject; public class ReorderTopCardsOfDrawDeck implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "count"); + FieldUtils.validateAllowedFields(effectObject, "count", "player", "deck"); final ValueSource valueSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); + final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); + final String deck = FieldUtils.getString(effectObject.get("deck"), "deck", "you"); + + final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); + final PlayerSource deckSource = PlayerResolver.resolvePlayer(deck, environment); return new DelayedAppender() { @Override public boolean isPlayableInFull(ActionContext actionContext) { final Evaluator count = valueSource.getEvaluator(actionContext); - return actionContext.getGame().getGameState().getDeck(actionContext.getPerformingPlayer()).size() >= count.evaluateExpression(actionContext.getGame(), null); + return actionContext.getGame().getGameState().getDeck(deckSource.getPlayer(actionContext)).size() >= count.evaluateExpression(actionContext.getGame(), null); } @Override protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { final int count = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null); - return new ReorderTopCardsOfDeckEffect(action, actionContext.getPerformingPlayer(), count); + return new ReorderTopCardsOfDeckEffect(action, playerSource.getPlayer(actionContext), deckSource.getPlayer(actionContext), count); } }; } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDeck.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDeck.java index 80e31cdd4..64804b0bf 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDeck.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/StackCardsFromDeck.java @@ -35,7 +35,7 @@ public class StackCardsFromDeck implements EffectAppenderProducer { result.addEffectAppender( CardResolver.resolveCard(where, "_temp1", "you", "Choose card to stack on", environment)); result.addEffectAppender( - CardResolver.resolveCardsInDeck(filter, null, valueSource, "_temp2", "you", "Choose cards to stack", environment)); + CardResolver.resolveCardsInDeck(filter, valueSource, "_temp2", "you", "Choose cards to stack", environment)); result.addEffectAppender( new DelayedAppender() { @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java index e9b15405e..265db0da7 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/CardResolver.java @@ -185,14 +185,16 @@ public class CardResolver { } public static EffectAppender resolveCardsInDeck(String type, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - return resolveCardsInDeck(type, null, countSource, memory, choicePlayer, choiceText, environment); + return resolveCardsInDeck(type, null, countSource, memory, choicePlayer, choicePlayer, choiceText, environment); } - public static EffectAppender resolveCardsInDeck(String type, FilterableSource choiceFilter, ValueSource countSource, String memory, String choicePlayer, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + public static EffectAppender resolveCardsInDeck(String type, FilterableSource choiceFilter, ValueSource countSource, String memory, String choicePlayer, String targetDeck, String choiceText, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { final PlayerSource playerSource = PlayerResolver.resolvePlayer(choicePlayer, environment); + final PlayerSource deckSource = PlayerResolver.resolvePlayer(targetDeck, environment); + Function> cardSource = actionContext -> { - String playerId = playerSource.getPlayer(actionContext); - return actionContext.getGame().getGameState().getDeck(playerId); + String deckId = deckSource.getPlayer(actionContext); + return actionContext.getGame().getGameState().getDeck(deckId); }; if (type.startsWith("memory(") && type.endsWith(")")) { @@ -202,7 +204,8 @@ public class CardResolver { } else if (type.startsWith("choose(") && type.endsWith(")")) { ChoiceEffectSource effectSource = (possibleCards, action, actionContext, min, max) -> { String choicePlayerId = playerSource.getPlayer(actionContext); - return new ChooseCardsFromDeckEffect(choicePlayerId, min, max, Filters.in(possibleCards)) { + String targetDeckId = deckSource.getPlayer(actionContext); + return new ChooseCardsFromDeckEffect(choicePlayerId, targetDeckId, min, max, Filters.in(possibleCards)) { @Override protected void cardsSelected(LotroGame game, Collection cards) { actionContext.setCardMemory(memory, cards); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/MemoryLike.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/MemoryLike.java new file mode 100644 index 000000000..a39e63384 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/MemoryLike.java @@ -0,0 +1,22 @@ +package com.gempukku.lotro.cards.build.field.effect.requirement; + +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.Requirement; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import org.json.simple.JSONObject; + +public class MemoryLike implements RequirementProducer { + @Override + public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(object, "memory", "value"); + + final String memory = FieldUtils.getString(object.get("memory"), "memory"); + final String value = FieldUtils.getString(object.get("value"), "value"); + + return (actionContext) -> { + String valueFromMemory = actionContext.getValueFromMemory(memory); + return valueFromMemory != null && valueFromMemory.contains(value); + }; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java index 95e8dfffa..549c4f6fc 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java @@ -36,6 +36,7 @@ public class RequirementFactory { requirementProducers.put("isside", new IsSideRequirementProducer()); requirementProducers.put("location", new Location()); requirementProducers.put("memoryis", new MemoryIs()); + requirementProducers.put("memorylike", new MemoryLike()); requirementProducers.put("memorymatches", new MemoryMatches()); requirementProducers.put("movecountminimum", new MoveCountMinimum()); requirementProducers.put("perphaselimit", new PerPhaseLimit()); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameCommunicationChannel.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameCommunicationChannel.java index 8ff6d70cd..ff6f157cc 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameCommunicationChannel.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameCommunicationChannel.java @@ -120,7 +120,7 @@ public class GameCommunicationChannel implements GameStateListener, LongPollable public void cardsRemoved(String playerPerforming, Collection cards) { Set removedCardsVisibleByPlayer = new HashSet(); for (PhysicalCard card : cards) { - if (card.getZone().isPublic() || (card.getZone().isVisibleByOwner() && card.getOwner().equals(_self))) + if (card.getZone().isPublic() || (card.getZone().isVisibleByOwner() && card.getOwner().equals(_self) || playerPerforming != card.getOwner())) removedCardsVisibleByPlayer.add(card); } if (removedCardsVisibleByPlayer.size() > 0) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardFromDeckOnTopOfDeckEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardFromDeckOnTopOfDeckEffect.java index e3f2cb87b..4dcb6de69 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardFromDeckOnTopOfDeckEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardFromDeckOnTopOfDeckEffect.java @@ -10,12 +10,12 @@ import com.gempukku.lotro.logic.timing.AbstractEffect; import java.util.Collections; public class PutCardFromDeckOnTopOfDeckEffect extends AbstractEffect { - private PhysicalCard _source; + private String _performingPlayer; private PhysicalCard _physicalCard; - public PutCardFromDeckOnTopOfDeckEffect(PhysicalCard source, PhysicalCard physicalCard) { + public PutCardFromDeckOnTopOfDeckEffect(String player, PhysicalCard physicalCard) { _physicalCard = physicalCard; - _source = source; + _performingPlayer = player; } @Override @@ -37,7 +37,7 @@ public class PutCardFromDeckOnTopOfDeckEffect extends AbstractEffect { protected FullEffectResult playEffectReturningResult(LotroGame game) { if (isPlayableInFull(game)) { GameState gameState = game.getGameState(); - gameState.removeCardsFromZone(_source.getOwner(), Collections.singleton(_physicalCard)); + gameState.removeCardsFromZone(_performingPlayer, Collections.singleton(_physicalCard)); gameState.putCardOnTopOfDeck(_physicalCard); return new FullEffectResult(true); } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardsFromDeckOnTopOfDrawDeckEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardsFromDeckOnTopOfDrawDeckEffect.java index b0eebbeef..7eedaa683 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardsFromDeckOnTopOfDrawDeckEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/PutCardsFromDeckOnTopOfDrawDeckEffect.java @@ -61,7 +61,7 @@ public class PutCardsFromDeckOnTopOfDrawDeckEffect extends AbstractSubActionEffe protected void cardsSelected(LotroGame game, Collection selectedCards) { for (PhysicalCard selectedCard : selectedCards) { _subAction.appendEffect( - new PutCardFromDeckOnTopOfDeckEffect(_source, selectedCard)); + new PutCardFromDeckOnTopOfDeckEffect(_source.getOwner(), selectedCard)); _remainingCards.remove(selectedCard); if (_remainingCards.size() > 0) _subAction.appendEffect( diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ReorderTopCardsOfDeckEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ReorderTopCardsOfDeckEffect.java index 6c9150938..45bdee19e 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ReorderTopCardsOfDeckEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ReorderTopCardsOfDeckEffect.java @@ -15,11 +15,20 @@ import java.util.Set; public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect { private Action _action; private String _playerId; + private String _deckId; private int _count; public ReorderTopCardsOfDeckEffect(Action action, String playerId, int count) { _action = action; _playerId = playerId; + _deckId = playerId; + _count = count; + } + + public ReorderTopCardsOfDeckEffect(Action action, String playerId, String deckId, int count) { + _action = action; + _playerId = playerId; + _deckId = deckId; _count = count; } @@ -35,12 +44,12 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect { @Override public boolean isPlayableInFull(LotroGame game) { - return game.getGameState().getDeck(_playerId).size() >= _count; + return game.getGameState().getDeck(_deckId).size() >= _count; } @Override public void playEffect(LotroGame game) { - final List deck = game.getGameState().getDeck(_playerId); + final List deck = game.getGameState().getDeck(_deckId); int count = Math.min(deck.size(), _count); Set cards = new HashSet(deck.subList(0, count)); @@ -57,7 +66,7 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect { private CostToEffectAction _subAction; public ChooseAndPutNextCardFromDeckOnTopOfDeck(CostToEffectAction subAction, Collection remainingCards) { - super(_playerId, "Choose a card to put on top of your deck", remainingCards, 1, 1); + super(_playerId, "Choose a card to put on top of the deck", remainingCards, 1, 1); _subAction = subAction; _remainingCards = remainingCards; } @@ -66,7 +75,7 @@ public class ReorderTopCardsOfDeckEffect extends AbstractSubActionEffect { protected void cardsSelected(LotroGame game, Collection selectedCards) { for (PhysicalCard selectedCard : selectedCards) { _subAction.appendEffect( - new PutCardFromDeckOnTopOfDeckEffect(_action.getActionSource(), selectedCard)); + new PutCardFromDeckOnTopOfDeckEffect(_playerId, selectedCard)); _remainingCards.remove(selectedCard); if (_remainingCards.size() > 0) _subAction.appendEffect( diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoDiscardEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoDiscardEffect.java index 3ac0b31c2..909d9733c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoDiscardEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoDiscardEffect.java @@ -13,7 +13,12 @@ public class ChooseAndPutCardFromDeckIntoDiscardEffect extends ChooseCardsFromDe private Action _action; public ChooseAndPutCardFromDeckIntoDiscardEffect(Action action, String playerId, int minimum, int maximum, Filterable... filters) { - super(playerId, minimum, maximum, filters); + super(playerId, playerId, minimum, maximum, filters); + _action = action; + } + + public ChooseAndPutCardFromDeckIntoDiscardEffect(Action action, String playerId, String deckId, int minimum, int maximum, Filterable... filters) { + super(playerId, deckId, minimum, maximum, filters); _action = action; } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoHandEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoHandEffect.java index ff99f4294..c77960c45 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoHandEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseAndPutCardFromDeckIntoHandEffect.java @@ -13,7 +13,12 @@ public class ChooseAndPutCardFromDeckIntoHandEffect extends ChooseCardsFromDeckE private Action _action; public ChooseAndPutCardFromDeckIntoHandEffect(Action action, String playerId, int minimum, int maximum, Filterable... filters) { - super(playerId, minimum, maximum, filters); + super(playerId, playerId, minimum, maximum, filters); + _action = action; + } + + public ChooseAndPutCardFromDeckIntoHandEffect(Action action, String playerId, String deckId, int minimum, int maximum, Filterable... filters) { + super(playerId, deckId, minimum, maximum, filters); _action = action; } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseCardsFromDeckEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseCardsFromDeckEffect.java index 774c676e0..ec37f7b33 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseCardsFromDeckEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/choose/ChooseCardsFromDeckEffect.java @@ -15,12 +15,22 @@ import java.util.LinkedList; public abstract class ChooseCardsFromDeckEffect extends AbstractEffect { private String _playerId; + private String _deckId; private int _minimum; private int _maximum; private Filter _filter; public ChooseCardsFromDeckEffect(String playerId, int minimum, int maximum, Filterable... filters) { _playerId = playerId; + _deckId = playerId; + _minimum = minimum; + _maximum = maximum; + _filter = Filters.and(filters); + } + + public ChooseCardsFromDeckEffect(String playerId, String deckId, int minimum, int maximum, Filterable... filters) { + _playerId = playerId; + _deckId = deckId; _minimum = minimum; _maximum = maximum; _filter = Filters.and(filters); @@ -38,13 +48,13 @@ public abstract class ChooseCardsFromDeckEffect extends AbstractEffect { @Override public boolean isPlayableInFull(LotroGame game) { - Collection cards = Filters.filter(game.getGameState().getDeck(_playerId), game, _filter); + Collection cards = Filters.filter(game.getGameState().getDeck(_deckId), game, _filter); return cards.size() >= _minimum; } @Override protected FullEffectResult playEffectReturningResult(final LotroGame game) { - Collection cards = Filters.filter(game.getGameState().getDeck(_playerId), game, _filter); + Collection cards = Filters.filter(game.getGameState().getDeck(_deckId), game, _filter); boolean success = cards.size() >= _minimum; diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java index 33336a746..a31bed795 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java @@ -770,4 +770,10 @@ public class GenericCardTestHelper extends AbstractAtTest { } }); } + + public void AcknowledgeReveal() throws DecisionResultInvalidException + { + playerDecided(P1, ""); + playerDecided(P2, ""); + } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card1_018Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card1_018Tests.java new file mode 100644 index 000000000..ba789a908 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card1_018Tests.java @@ -0,0 +1,194 @@ +package com.gempukku.lotro.cards.official.set01; + +import com.gempukku.lotro.cards.GenericCardTestHelper; +import com.gempukku.lotro.common.*; +import com.gempukku.lotro.game.CardNotFoundException; +import com.gempukku.lotro.game.PhysicalCardImpl; +import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + + +public class Card1_018Tests +{ + protected GenericCardTestHelper GetScenario() throws CardNotFoundException, DecisionResultInvalidException { + return new GenericCardTestHelper( + new HashMap() + {{ + put("halls", "1_18"); + put("gimli", "1_13"); + + put("scard1", "1_178"); + put("scard2", "1_21"); + put("scard3", "1_203"); + + put("fcard1", "2_75"); + put("fcard2", "2_51"); + put("fcard3", "2_96"); + + }} + ); + } + + @Test + public void HallsStatsAndKeywordsAreCorrect() throws DecisionResultInvalidException, CardNotFoundException { + + /** + * Set: V1 + * Title: *A Shadow of the Past + * Side: Free Peoples + * Culture: sauron + * Twilight Cost: 1 + * Type: condition + * Subtype: Support Area + * Game Text: While you can spot 4 burdens, each [sauron] Orc is fierce. + * While you can spot 6 burdens, each [Sauron] Orc is damage +1. + * Discard this condition at the start of the regroup phase. + */ + + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl halls = scn.GetFreepsCard("halls"); + + assertFalse(halls.getBlueprint().isUnique()); + assertEquals(Side.FREE_PEOPLE, halls.getBlueprint().getSide()); + assertEquals(Culture.DWARVEN, halls.getBlueprint().getCulture()); + assertEquals(CardType.EVENT, halls.getBlueprint().getCardType()); + //assertEquals(Race.CREATURE, halls.getBlueprint().getRace()); + assertTrue(scn.HasKeyword(halls, Keyword.FELLOWSHIP)); // test for keywords as needed + assertEquals(1, halls.getBlueprint().getTwilightCost()); + //assertEquals(, halls.getBlueprint().getStrength()); + //assertEquals(, halls.getBlueprint().getVitality()); + //assertEquals(, halls.getBlueprint().getResistance()); + //assertEquals(Signet., halls.getBlueprint().getSignet()); + //assertEquals(, halls.getBlueprint().getSiteNumber()); // Change this to getAllyHomeSiteNumbers for allies + + } + + @Test + public void HallsExertsToRevealDiscardAndRearrangeFreepsDeck() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl halls = scn.GetFreepsCard("halls"); + scn.FreepsMoveCharToTable(gimli); + scn.FreepsMoveCardToHand(halls); + + PhysicalCardImpl fcard1 = scn.GetFreepsCard("fcard1"); + PhysicalCardImpl fcard2 = scn.GetFreepsCard("fcard2"); + PhysicalCardImpl fcard3 = scn.GetFreepsCard("fcard3"); + scn.FreepsMoveCardsToTopOfDeck(fcard3, fcard2, fcard1); + + PhysicalCardImpl scard1 = scn.GetShadowCard("scard1"); + PhysicalCardImpl scard2 = scn.GetShadowCard("scard2"); + PhysicalCardImpl scard3 = scn.GetShadowCard("scard3"); + scn.ShadowMoveCardsToTopOfDeck(scard3, scard2, scard1); + + scn.StartGame(); + + assertTrue(scn.FreepsCardPlayAvailable(halls)); + assertEquals(0, scn.GetWoundsOn(gimli)); + + scn.FreepsPlayCard(halls); + + assertEquals(1, scn.GetWoundsOn(gimli)); + assertTrue(scn.FreepsDecisionAvailable("Choose action to perform")); + assertEquals(2, scn.FreepsGetMultipleChoices().size()); + scn.FreepsChooseMultipleChoiceOption("your deck"); + List choices = scn.FreepsGetADParamAsList("blueprintId"); + assertTrue(choices.contains(fcard1.getBlueprintId())); + assertTrue(choices.contains(fcard2.getBlueprintId())); + assertTrue(choices.contains(fcard3.getBlueprintId())); + + scn.AcknowledgeReveal(); + assertTrue(scn.FreepsDecisionAvailable("Would you like to discard")); + scn.FreepsChooseYes(); + assertTrue(scn.FreepsDecisionAvailable("Choose card from deck")); + + choices = scn.FreepsGetADParamAsList("blueprintId"); + assertTrue(choices.contains(fcard1.getBlueprintId())); + assertTrue(choices.contains(fcard2.getBlueprintId())); + assertFalse(choices.contains(fcard3.getBlueprintId())); // freeps card, shouldn't be able to be discarded + + scn.FreepsChooseCardBPFromSelection(fcard1); + assertEquals(Zone.DISCARD, fcard1.getZone()); //discarded shadow card + choices = scn.FreepsGetADParamAsList("blueprintId"); + assertFalse(choices.contains(fcard1.getBlueprintId())); + assertTrue(choices.contains(fcard2.getBlueprintId())); + assertTrue(choices.contains(fcard3.getBlueprintId())); + + scn.FreepsChooseCardBPFromSelection(fcard3); + assertEquals(fcard2.getBlueprintId(), scn.GetFreepsTopOfDeck().getBlueprintId()); + + } + + + @Test + public void HallsExertsToRevealDiscardAndRearrangeShadowDeck() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + GenericCardTestHelper scn = GetScenario(); + + PhysicalCardImpl gimli = scn.GetFreepsCard("gimli"); + PhysicalCardImpl halls = scn.GetFreepsCard("halls"); + scn.FreepsMoveCharToTable(gimli); + scn.FreepsMoveCardToHand(halls); + + PhysicalCardImpl fcard1 = scn.GetFreepsCard("fcard1"); + PhysicalCardImpl fcard2 = scn.GetFreepsCard("fcard2"); + PhysicalCardImpl fcard3 = scn.GetFreepsCard("fcard3"); + scn.FreepsMoveCardsToTopOfDeck(fcard3, fcard2, fcard1); + + PhysicalCardImpl scard1 = scn.GetShadowCard("scard1"); + PhysicalCardImpl scard2 = scn.GetShadowCard("scard2"); + PhysicalCardImpl scard3 = scn.GetShadowCard("scard3"); + scn.ShadowMoveCardsToTopOfDeck(scard3, scard2, scard1); + + scn.StartGame(); + + assertTrue(scn.FreepsCardPlayAvailable(halls)); + assertEquals(0, scn.GetWoundsOn(gimli)); + + scn.FreepsPlayCard(halls); + + assertEquals(1, scn.GetWoundsOn(gimli)); + assertTrue(scn.FreepsDecisionAvailable("Choose action to perform")); + assertEquals(2, scn.FreepsGetMultipleChoices().size()); + scn.FreepsChooseMultipleChoiceOption("your opponent's deck"); + List choices = scn.FreepsGetADParamAsList("blueprintId"); + assertTrue(choices.contains(scard1.getBlueprintId())); + assertTrue(choices.contains(scard2.getBlueprintId())); + assertTrue(choices.contains(scard3.getBlueprintId())); + + scn.AcknowledgeReveal(); + assertTrue(scn.FreepsDecisionAvailable("Would you like to discard")); + scn.FreepsChooseYes(); + assertTrue(scn.FreepsDecisionAvailable("Choose card from deck")); + + choices = scn.FreepsGetADParamAsList("blueprintId"); + assertTrue(choices.contains(scard1.getBlueprintId())); + assertTrue(choices.contains(scard3.getBlueprintId())); + assertFalse(choices.contains(scard2.getBlueprintId())); // freeps card, shouldn't be able to be discarded + + scn.FreepsChooseCardBPFromSelection(scard1); + assertEquals(Zone.DISCARD, scard1.getZone()); //discarded shadow card + choices = scn.FreepsGetADParamAsList("blueprintId"); + assertFalse(choices.contains(scard1.getBlueprintId())); + assertTrue(choices.contains(scard2.getBlueprintId())); + assertTrue(choices.contains(scard3.getBlueprintId())); + + scn.FreepsChooseCardBPFromSelection(scard2); + assertEquals(scard3.getBlueprintId(), scn.GetShadowTopOfDeck().getBlueprintId()); + + } + + + +} \ No newline at end of file