From 33ce5436a5d6c2093a209425200a6385c3e03bf8 Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Tue, 27 Aug 2019 12:02:17 -0700 Subject: [PATCH] 4 Fellowship companions --- .../src/main/web/cards/set1.json | 93 +++++++++++++++++++ .../field/effect/EffectAppenderFactory.java | 1 + .../appender/DoesNotAddToArcheryTotal.java | 68 ++++++++++++++ .../field/effect/filter/FilterFactory.java | 24 +++++ .../field/effect/requirement/Location.java | 28 ++++++ .../requirement/RequirementFactory.java | 1 + .../lotro/logic/timing/PlayConditions.java | 6 +- 7 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DoesNotAddToArcheryTotal.java create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/Location.java diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1.json index e4742b4af..0f38c8f75 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set1.json @@ -119,6 +119,26 @@ } } }, + "1_30": { + "title": "Arwen", + "subtitle": "Daughter of Elrond", + "unique": true, + "side": "free people", + "culture": "elven", + "cost": 2, + "type": "companion", + "race": "elf", + "strength": 6, + "vitality": 3, + "resistance": 6, + "signet": "aragorn", + "keyword": "ranger", + "effects": { + "type": "modifyStrength", + "amount": 3, + "filter": "self,inSkirmishAgainst(nazgul)" + } + }, "1_38": { "title": "Double Shot", "side": "free people", @@ -139,6 +159,64 @@ } } }, + "1_48": { + "title": "Haldir", + "subtitle": "Elf of the Golden Wood", + "unique": true, + "side": "free people", + "culture": "elven", + "cost": 2, + "type": "companion", + "race": "elf", + "strength": 5, + "vitality": 3, + "resistance": 6, + "requirement": { + "type": "canSpot", + "filter": "elf" + }, + "effects": { + "type": "modifyStrength", + "amount": 2, + "condition": { + "type": "location", + "filter": "siteBlock(fellowship),or(siteNumber(6),siteNumber(7),siteNumber(8))" + } + } + }, + "1_50": { + "title": "Legolas", + "subtitle": "Greenleaf", + "unique": true, + "side": "free people", + "culture": "elven", + "cost": 2, + "type": "companion", + "race": "elf", + "strength": 6, + "vitality": 3, + "resistance": 6, + "signet": "frodo", + "keyword": "archer", + "effects": { + "type": "activated", + "phase": "archery", + "cost": { + "type": "exert", + "filter": "self" + }, + "effect": [ + { + "type": "wound", + "filter": "choose(minion)" + }, + { + "type": "doesNotAddToArcheryTotal", + "filter": "self" + } + ] + } + }, "1_51": { "title": "Legolas", "subtitle": "Prince of Mirkwood", @@ -159,6 +237,21 @@ "amount": 3 } }, + "1_53": { + "title": "Lorien Elf", + "side": "free people", + "culture": "elven", + "cost": 1, + "type": "companion", + "race": "elf", + "strength": 4, + "vitality": 2, + "resistance": 6, + "requirement": { + "type": "canSpot", + "filter": "elf" + } + }, "1_94": { "title": "Athelas", "side": "free people", 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 1018aca0f..4372dbc31 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 @@ -31,6 +31,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("choice", new Choice()); effectAppenderProducers.put("assigntoskirmishagainstminion", new AssignToSkirmishAgainstMinion()); effectAppenderProducers.put("putcardfromhandonbottomofdeck", new PutCardFromHandOnBottomOfDeck()); + effectAppenderProducers.put("doesnotaddtoarcherytotal", new DoesNotAddToArcheryTotal()); } 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/DoesNotAddToArcheryTotal.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DoesNotAddToArcheryTotal.java new file mode 100644 index 000000000..ba9398964 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DoesNotAddToArcheryTotal.java @@ -0,0 +1,68 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.FilterableSource; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.Requirement; +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.CountResolver; +import com.gempukku.lotro.filters.Filters; +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.AddUntilEndOfPhaseModifierEffect; +import com.gempukku.lotro.logic.modifiers.DoesNotAddToArcheryTotalModifier; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; +import com.gempukku.lotro.logic.timing.PlayConditions; +import org.json.simple.JSONObject; + +import java.util.Collection; + +public class DoesNotAddToArcheryTotal implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memory"); + + final CountResolver.Count count = CountResolver.resolveCount(effectObject.get("count"), 1); + final String filter = FieldUtils.getString(effectObject.get("filter"), "filter"); + final String memory = FieldUtils.getString(effectObject.get("memory"), "memory", "_temp"); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCards(filter, + count.getMin(), count.getMax(), memory, "owner", "Choose cards to make not add to archery total", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + final Collection cardsFromMemory = action.getCardsFromMemory(memory); + return new AddUntilEndOfPhaseModifierEffect( + new DoesNotAddToArcheryTotalModifier(self, Filters.in(cardsFromMemory))); + } + }); + + return result; + } + + @Override + public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "count", "filter", "memory"); + + final CountResolver.Count count = CountResolver.resolveCount(effectObject.get("count"), 1); + final String type = FieldUtils.getString(effectObject.get("filter"), "filter"); + + if (type.startsWith("choose(") && type.endsWith(")")) { + final String filter = type.substring(type.indexOf("(") + 1, type.lastIndexOf(")")); + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); + + return (playerId, game, self, effectResult, effect) -> PlayConditions.isActive(game, count.getMin(), + filterableSource.getFilterable(playerId, game, self, effectResult, effect)); + } + return null; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/filter/FilterFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/filter/FilterFactory.java index bb5353964..be7a6470a 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/filter/FilterFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/filter/FilterFactory.java @@ -93,6 +93,30 @@ public class FilterFactory { int number = Integer.parseInt(parameterSplit[1]); return Filters.and(Filters.siteBlock(sitesBlock), Filters.siteNumber(number)); }); + parameterFilters.put("siteBlock", + (parameter, filterFactory) -> { + final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameter.toUpperCase().replace(' ', '_')); + return (playerId, game, source, effectResult, effect) -> Filters.siteBlock(sitesBlock); + }); + parameterFilters.put("siteNumber", + (parameter, filterFactory) -> { + int number = Integer.parseInt(parameter); + return (playerId, game, source, effectResult, effect) -> Filters.siteNumber(number); + }); + parameterFilters.put("or", + (parameter, filterFactory) -> { + final String[] filters = splitIntoFilters(parameter); + FilterableSource[] filterables = new FilterableSource[filters.length]; + for (int i = 0; i < filters.length; i++) + filterables[i] = filterFactory.generateFilter(filters[i]); + return (playerId, game, source, effectResult, effect) -> { + Filterable[] filters1 = new Filterable[filterables.length]; + for (int i = 0; i < filterables.length; i++) + filters1[i] = filterables[i].getFilterable(playerId, game, source, effectResult, effect); + + return Filters.or(filters1); + }; + }); } private void appendFilter(Filterable value) { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/Location.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/Location.java new file mode 100644 index 000000000..88aae246b --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/Location.java @@ -0,0 +1,28 @@ +package com.gempukku.lotro.cards.build.field.effect.requirement; + +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.FilterableSource; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +import com.gempukku.lotro.cards.build.Requirement; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.common.Filterable; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import org.json.simple.JSONObject; + +public class Location implements RequirementProducer { + @Override + public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(object, "filter"); + + final String filter = FieldUtils.getString(object.get("filter"), "filter"); + + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); + + return (playerId, game, self, effectResult, effect) -> { + final Filterable filterable = filterableSource.getFilterable(playerId, game, self, effectResult, effect); + final PhysicalCard currentSite = game.getGameState().getCurrentSite(); + return Filters.and(filterable).accepts(game, currentSite); + }; + } +} 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 318cef4e2..87373a9ca 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 @@ -17,6 +17,7 @@ public class RequirementFactory { requirementProducers.put("canspotburdens", new CanSpotBurdens()); requirementProducers.put("controlssite", new ControlsSite()); requirementProducers.put("twilightpoollessthan", new TwilightPoolLessThan()); + requirementProducers.put("location", new Location()); } public Requirement getRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/PlayConditions.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/PlayConditions.java index ef98112bd..e5f783e12 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/PlayConditions.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/PlayConditions.java @@ -234,7 +234,11 @@ public class PlayConditions { } public static boolean isActive(LotroGame game, Filterable... filters) { - return Filters.countActive(game, filters) > 0; + return isActive(game, 1, filters); + } + + public static boolean isActive(LotroGame game, int count, Filterable... filters) { + return Filters.countActive(game, filters) >= count; } public static boolean canSpot(LotroGame game, int count, Filterable... filters) {