From 2c28f2d2aa6d65cddf1744a2340ae64c15656a89 Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Fri, 13 Sep 2019 16:23:53 -0700 Subject: [PATCH] Some FotR cards --- .../src/main/web/cards/set1/set1-elven.json | 172 ++++++++++++++++++ .../src/main/web/cards/set19.json | 5 +- .../main/web/cards/set40/set40-isengard.json | 2 +- .../cards/build/BuiltLotroCardBlueprint.java | 3 + .../field/effect/EffectAppenderFactory.java | 3 +- ...ardsFromHand.java => DiscardFromHand.java} | 18 +- .../field/effect/appender/RevealHand.java | 52 ++++++ 7 files changed, 243 insertions(+), 12 deletions(-) rename gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/{DiscardCardsFromHand.java => DiscardFromHand.java} (77%) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealHand.java diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-elven.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-elven.json index 586bf7fcb..d6408f8fd 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-elven.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1/set1-elven.json @@ -140,6 +140,107 @@ } } }, + "1_34": { + "title": "*Celeborn", + "subtitle": "Lord of Lorien", + "culture": "elven", + "cost": 2, + "type": "ally", + "allyHome": "fellowship,6", + "race": "elf", + "strength": 6, + "vitality": 3, + "effects": { + "type": "activated", + "phase": "fellowship", + "cost": { + "type": "exert", + "filter": "self" + }, + "effect": { + "type": "heal", + "filter": "choose(culture(elven),ally)" + } + } + }, + "1_35": { + "title": "The Council of Elrond", + "culture": "elven", + "cost": 2, + "type": "event", + "keyword": "fellowship", + "condition": { + "type": "canSpot", + "filter": "elf" + }, + "effects": { + "type": "event", + "effect": { + "type": "playCardFromDrawDeck", + "filter": "choose(tale)" + } + } + }, + "1_36": { + "title": "Curse Their Foul Feet!", + "culture": "elven", + "cost": 0, + "type": "event", + "keyword": "fellowship", + "effects": { + "type": "event", + "cost": { + "type": "exert", + "filter": "choose(elf)" + }, + "effect": [ + { + "type": "revealHand", + "hand": "shadowPlayer", + "memorize": "cardsInHand" + }, + { + "type": "filterCardsInMemory", + "memory": "cardsInHand", + "filter": "orc", + "memorizeMatching": "orcsInHand" + }, + { + "type": "discardFromHand", + "hand": "shadowPlayer", + "forced": true, + "count": { + "type": "forEachInMemory", + "memory": "orcsInHand" + } + } + ] + } + }, + "1_37": { + "title": "Defiance", + "culture": "elven", + "cost": 1, + "type": "event", + "keyword": "skirmish", + "effects": { + "type": "event", + "effect": { + "type": "modifyStrength", + "filter": "choose(elf)", + "memorize": "chosenElf", + "amount": { + "type": "condition", + "condition": { + "type": "canSpot", + "filter": "memory(chosenElf),inSkirmishAgainst(nazgul)" + }, + "true": 4, + "false": 2 + } + } + } + }, "1_38": { "title": "Double Shot", "culture": "elven", @@ -159,6 +260,77 @@ } } }, + "1_39": { + "title": "Elf-song", + "culture": "elven", + "cost": 1, + "type": "event", + "keyword": "fellowship", + "condition": { + "type": "canSpot", + "filter": "elf" + }, + "effects": { + "type": "event", + "effect": { + "type": "removeBurdens" + } + } + }, + "1_40": { + "title": "*Elrond", + "subtitle": "Lord of Rivendell", + "culture": "elven", + "cost": 4, + "type": "ally", + "allyHome": "fellowship,3", + "race": "elf", + "strength": 8, + "vitality": 4, + "condition": { + "type": "canSpot", + "filter": "or(name(Gandalf),elf)" + }, + "effects": [ + { + "type": "trigger", + "trigger": { + "type": "startOfTurn" + }, + "effect": { + "type": "heal", + "filter": "all(ally,allyHome(fellowship,3))" + } + }, + { + "type": "activated", + "phase": "fellowship", + "cost": { + "type": "exert", + "filter": "self" + }, + "effect": { + "type": "drawCards" + } + } + ] + }, + "1_41": { + "title": "Elven Bow", + "culture": "elven", + "cost": 1, + "type": "possession", + "possession": "ranged weapon", + "target": "elf", + "effects": { + "type": "modifier", + "modifier": { + "type": "addKeyword", + "filter": "bearer", + "keyword": "archer" + } + } + }, "1_48": { "title": "*Haldir", "subtitle": "Elf of the Golden Wood", diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set19.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set19.json index 8d6dff2ff..6a365a521 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set19.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set19.json @@ -649,7 +649,10 @@ "culture": "isengard", "cost": 0, "type": "condition", - "keyword": "weather", + "keyword": [ + "support area", + "weather" + ], "effects": [ { "type": "trigger", diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-isengard.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-isengard.json index 1949f3d70..83946160a 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-isengard.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40/set40-isengard.json @@ -274,7 +274,7 @@ "culture": "isengard", "cost": 0, "type": "artifact", - "possession": "palantir", + "keyword": "support area", "condition": { "type": "canSpot", "filter": "culture(isengard),minion" diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java index a9b637005..5fba89ee7 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/BuiltLotroCardBlueprint.java @@ -828,5 +828,8 @@ public class BuiltLotroCardBlueprint implements LotroCardBlueprint { if (keywords.size() > 1 && keywords.containsKey(Keyword.TALE)) throw new InvalidCardDefinitionException("Attachment should not have keywords"); } + if (Arrays.asList(CardType.POSSESSION, CardType.CONDITION, CardType.ARTIFACT).contains(cardType) + && targetFilters == null && (keywords == null || !keywords.containsKey(Keyword.SUPPORT_AREA))) + throw new InvalidCardDefinitionException("Possession, condition or artifact without a filter needs a SUPPORT_AREA keyword"); } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java index 2a81d7680..36ab0d244 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/EffectAppenderFactory.java @@ -69,7 +69,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("preventable", new PreventableAppenderProducer()); effectAppenderProducers.put("cantbeoverwhelmedmultiplier", new CantBeOverwhelmedMultiplier()); effectAppenderProducers.put("cancelskirmish", new CancelSkirmish()); - effectAppenderProducers.put("discardfromhand", new DiscardCardsFromHand()); + effectAppenderProducers.put("discardfromhand", new DiscardFromHand()); effectAppenderProducers.put("chooseandremovetwilight", new ChooseAndRemoveTwilight()); effectAppenderProducers.put("removetwilight", new RemoveTwilight()); effectAppenderProducers.put("removethreats", new RemoveThreats()); @@ -110,6 +110,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("filtercardsinmemory", new FilterCardsInMemory()); effectAppenderProducers.put("discardcardsfromdrawdeck", new DiscardCardsFromDrawDeck()); effectAppenderProducers.put("incrementperturnlimit", new IncrementPerTurnLimit()); + effectAppenderProducers.put("revealhand", new RevealHand()); } public EffectAppender getEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromHand.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardFromHand.java similarity index 77% rename from gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromHand.java rename to gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardFromHand.java index c974d9479..d3a6d6ec3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardCardsFromHand.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DiscardFromHand.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; @@ -17,32 +15,34 @@ import org.json.simple.JSONObject; import java.util.Collection; -public class DiscardCardsFromHand implements EffectAppenderProducer { +public class DiscardFromHand implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "forced", "count", "filter", "memorize"); + FieldUtils.validateAllowedFields(effectObject, "forced", "count", "filter", "memorize", "hand"); + final String player = FieldUtils.getString(effectObject.get("hand"), "hand", "you"); final boolean forced = FieldUtils.getBoolean(effectObject.get("forced"), "forced"); final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "choose(any)"); final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); + final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); final ValueSource countSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); MultiEffectAppender result = new MultiEffectAppender(); result.addEffectAppender( - CardResolver.resolveCardsInHand(filter, countSource, memorize, "you", "Choose cards to discard", environment)); + CardResolver.resolveCardsInHand(filter, countSource, memorize, player, "Choose cards to discard", environment)); result.addEffectAppender( new DelayedAppender() { @Override protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { final Collection cardsToDiscard = actionContext.getCardsFromMemory(memorize); - return new DiscardCardsFromHandEffect(actionContext.getSource(), actionContext.getPerformingPlayer(), cardsToDiscard, forced); + return new DiscardCardsFromHandEffect(actionContext.getSource(), playerSource.getPlayer(actionContext), cardsToDiscard, forced); } @Override public boolean isPlayableInFull(ActionContext actionContext) { - return (!forced || actionContext.getGame().getModifiersQuerying().canDiscardCardsFromHand(actionContext.getGame(), actionContext.getPerformingPlayer(), actionContext.getSource())); + return (!forced || actionContext.getGame().getModifiersQuerying().canDiscardCardsFromHand(actionContext.getGame(), playerSource.getPlayer(actionContext), actionContext.getSource())); } }); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealHand.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealHand.java new file mode 100644 index 000000000..2f4c8e1ce --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/RevealHand.java @@ -0,0 +1,52 @@ +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.PlayerSource; +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.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.effects.RevealHandEffect; +import com.gempukku.lotro.logic.timing.Effect; +import org.json.simple.JSONObject; + +import java.util.Collection; + +public class RevealHand implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "hand", "memorize"); + + final String player = FieldUtils.getString(effectObject.get("hand"), "hand", "you"); + final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); + + final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize"); + + return new DelayedAppender() { + @Override + public boolean isPlayableInFull(ActionContext actionContext) { + final LotroGame game = actionContext.getGame(); + final String revealingPlayer = playerSource.getPlayer(actionContext); + return game.getModifiersQuerying().canLookOrRevealCardsInHand(game, revealingPlayer, actionContext.getPerformingPlayer()); + } + + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + final String revealingPlayer = playerSource.getPlayer(actionContext); + return new RevealHandEffect(actionContext.getSource(), actionContext.getPerformingPlayer(), revealingPlayer) { + @Override + protected void cardsRevealed(Collection cards) { + if (memorize != null) + actionContext.setCardMemory(memorize, cards); + } + }; + } + }; + } + +}