From b0a39e72414d7e5745d427f1b4f0f1ace5e87b73 Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Mon, 26 Aug 2019 21:03:33 -0700 Subject: [PATCH] Added additional cards to JSON card definition --- .../src/main/web/cards/set1.json | 65 +++++++++++++- .../lotro/cards/set1/shire/Card1_306.java | 4 +- .../build/field/EffectFieldProcessor.java | 6 +- .../field/effect/EffectAppenderFactory.java | 1 + .../AssignToSkirmishAgainstMinion.java | 85 +++++++++++++++++++ .../field/effect/filter/FilterFactory.java | 21 +++-- .../effect/modifier/ModifyRoamingPenalty.java | 34 ++++++++ .../modifier/OpponentMayNotDiscard.java | 25 ++++++ 8 files changed, 228 insertions(+), 13 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AssignToSkirmishAgainstMinion.java create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/ModifyRoamingPenalty.java create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/OpponentMayNotDiscard.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 8991a3404..d1854fb75 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 @@ -122,6 +122,18 @@ } } }, + "1_158": { + "title": "Uruk-hai Raiding Party", + "side": "shadow", + "culture": "isengard", + "cost": 4, + "type": "minion", + "race": "uruk-hai", + "strength": 9, + "vitality": 3, + "site": 5, + "keyword": "damage+1" + }, "1_178": { "title": "Goblin Runner", "side": "shadow", @@ -144,6 +156,40 @@ } } }, + "1_262": { + "title": "Orc Assassin", + "side": "shadow", + "culture": "sauron", + "cost": 2, + "type": "minion", + "race": "orc", + "strength": 6, + "vitality": 2, + "site": 6, + "keyword": "tracker", + "effects": [ + { + "type": "modifyRoamingPenalty", + "filter": "culture(sauron),minion,your", + "amount": -1 + }, + { + "type": "activated", + "phase": "assignment", + "requirement": { + "type": "canSpot", + "filter": "hobbit,companion", + "count": 2 + }, + "effect": { + "type": "assignToSkirmishAgainstMinion", + "player": "fp", + "fpCharacter": "choose(hobbit)", + "against": "self" + } + } + ] + }, "1_297": { "title": "Hobbit Party Guest", "side": "free people", @@ -194,9 +240,26 @@ "resistance": 6, "signet": "aragorn", "effects": { - "type": "modifystrength", + "type": "modifyStrength", "filter": "self,hasAttached(weapon)", "amount": 2 } + }, + "1_306": { + "title": "Pippin", + "subtitle": "Friend to Frodo", + "unique": true, + "side": "free people", + "cost": 0, + "type": "companion", + "race": "hobbit", + "strength": 3, + "vitality": 4, + "resistance": 6, + "signet": "frodo", + "effects": { + "type": "opponentMayNotDiscard", + "filter": "your,culture(shire),tale" + } } } \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set1/shire/Card1_306.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set1/shire/Card1_306.java index fbeef3495..b3c956206 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set1/shire/Card1_306.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set1/shire/Card1_306.java @@ -33,6 +33,6 @@ public class Card1_306 extends AbstractCompanion { @Override public List getInPlayModifiers(LotroGame game, PhysicalCard self) { -return Collections.singletonList(new CantDiscardFromPlayByPlayerModifier(self, "Can't be discarded by opponent", Filters.and(Culture.SHIRE, Keyword.TALE), self.getOwner())); -} + return Collections.singletonList(new CantDiscardFromPlayByPlayerModifier(self, "Can't be discarded by opponent", Filters.and(Culture.SHIRE, Keyword.TALE), self.getOwner())); + } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java index 386374705..54ff2c07b 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/EffectFieldProcessor.java @@ -8,9 +8,7 @@ import com.gempukku.lotro.cards.build.field.effect.ActivatedEffectProcessor; import com.gempukku.lotro.cards.build.field.effect.ActivatedTriggerEffectProcessor; import com.gempukku.lotro.cards.build.field.effect.EventEffectProcessor; import com.gempukku.lotro.cards.build.field.effect.TriggerEffectProcessor; -import com.gempukku.lotro.cards.build.field.effect.modifier.AddKeyword; -import com.gempukku.lotro.cards.build.field.effect.modifier.ArcheryTotal; -import com.gempukku.lotro.cards.build.field.effect.modifier.ModifyStrength; +import com.gempukku.lotro.cards.build.field.effect.modifier.*; import org.json.simple.JSONObject; import java.util.HashMap; @@ -25,8 +23,10 @@ public class EffectFieldProcessor implements FieldProcessor { effectProcessors.put("activated", new ActivatedEffectProcessor()); effectProcessors.put("event", new EventEffectProcessor()); effectProcessors.put("modifystrength", new ModifyStrength()); + effectProcessors.put("modifyroamingpenalty", new ModifyRoamingPenalty()); effectProcessors.put("addkeyword", new AddKeyword()); effectProcessors.put("archerytotal", new ArcheryTotal()); + effectProcessors.put("opponentmaynotdiscard", new OpponentMayNotDiscard()); } @Override 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 7cd50c7a3..d99094f2e 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 @@ -29,6 +29,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("replaceinskirmish", new ReplaceInSkirmish()); effectAppenderProducers.put("canttakemorewoundsthan", new CantTakeMoreWoundsThan()); effectAppenderProducers.put("choice", new Choice()); + effectAppenderProducers.put("assigntoskirmishagainstminion", new AssignToSkirmishAgainstMinion()); } 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/AssignToSkirmishAgainstMinion.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AssignToSkirmishAgainstMinion.java new file mode 100644 index 000000000..4fb0447c8 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/AssignToSkirmishAgainstMinion.java @@ -0,0 +1,85 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +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.common.Filterable; +import com.gempukku.lotro.common.Side; +import com.gempukku.lotro.filters.Filters; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.GameUtils; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.effects.AssignmentEffect; +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; + +public class AssignToSkirmishAgainstMinion implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "player", "fpCharacter", "against"); + + final String player = FieldUtils.getString(effectObject.get("player"), "player", "owner"); + final String fpCharacter = FieldUtils.getString(effectObject.get("fpCharacter"), "fpCharacter"); + final String against = FieldUtils.getString(effectObject.get("against"), "against"); + + final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); + final FilterableSource minionFilter = environment.getFilterFactory().generateFilter(against); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + CardResolver.resolveCard(fpCharacter, + (playerId, game, source, effectResult, effect) -> { + final String assigningPlayer = playerSource.getPlayer(playerId, game, source, effectResult, effect); + Side assigningSide = GameUtils.isFP(game, assigningPlayer) ? Side.FREE_PEOPLE : Side.SHADOW; + final Filterable filter = minionFilter.getFilterable(playerId, game, source, effectResult, effect); + return Filters.assignableToSkirmishAgainst(assigningSide, filter, false, false); + }, "_tempFpCharacter", player, "Choose character to assign to minion", environment)); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + final String assigningPlayer = playerSource.getPlayer(playerId, game, self, effectResult, effect); + final Filterable filter = minionFilter.getFilterable(playerId, game, self, effectResult, effect); + final PhysicalCard minion = Filters.findFirstActive(game, filter); + final PhysicalCard fpCharacter = action.getCardFromMemory("_tempFpCharacter"); + return new AssignmentEffect(assigningPlayer, fpCharacter, minion); + } + }); + + return result; + } + + @Override + public Requirement createCostRequirement(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + final String player = FieldUtils.getString(effectObject.get("player"), "player", "owner"); + final String type = FieldUtils.getString(effectObject.get("fpCharacter"), "fpCharacter"); + final String against = FieldUtils.getString(effectObject.get("against"), "against"); + + final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment); + final FilterableSource minionFilter = environment.getFilterFactory().generateFilter(against); + + 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) -> { + final String assigningPlayer = playerSource.getPlayer(playerId, game, self, effectResult, effect); + Side assigningSide = GameUtils.isFP(game, assigningPlayer) ? Side.FREE_PEOPLE : Side.SHADOW; + + final Filterable minion = minionFilter.getFilterable(playerId, game, self, effectResult, effect); + + return PlayConditions.isActive(game, + filterableSource.getFilterable(playerId, game, self, effectResult, effect), + Filters.assignableToSkirmishAgainst(assigningSide, minion, false, false)); + }; + } + 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 e02ccb381..bb5353964 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 @@ -84,7 +84,14 @@ public class FilterFactory { parameterFilters.put("not", (parameter, filterFactory) -> { final FilterableSource filterableSource = filterFactory.generateFilter(parameter); - return (FilterableSource) (playerId, game, source, effectResult, effect) -> Filters.not(filterableSource.getFilterable(playerId, game, source, effectResult, effect)); + return (playerId, game, source, effectResult, effect) -> Filters.not(filterableSource.getFilterable(playerId, game, source, effectResult, effect)); + }); + parameterFilters.put("site", + (parameter, filterFactory) -> (playerId, game, source, effectResult, effect) -> { + final String[] parameterSplit = parameter.split(","); + final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameterSplit[0].toUpperCase().replace('_', ' ')); + int number = Integer.parseInt(parameterSplit[1]); + return Filters.and(Filters.siteBlock(sitesBlock), Filters.siteNumber(number)); }); } @@ -160,16 +167,16 @@ public class FilterFactory { } private FilterableSource lookupFilter(String name, String parameter) throws InvalidCardDefinitionException { - FilterableSource result = simpleFilters.get(name.toLowerCase()); - if (result != null) - return result; + if (parameter == null) { + FilterableSource result = simpleFilters.get(name.toLowerCase()); + if (result != null) + return result; + } final FilterableSourceProducer filterableSourceProducer = parameterFilters.get(name); if (filterableSourceProducer == null) throw new InvalidCardDefinitionException("Unable to find filter: " + name); - result = filterableSourceProducer.createFilterableSource(parameter, this); - - return result; + return filterableSourceProducer.createFilterableSource(parameter, this); } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/ModifyRoamingPenalty.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/ModifyRoamingPenalty.java new file mode 100644 index 000000000..8600a9acd --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/ModifyRoamingPenalty.java @@ -0,0 +1,34 @@ +package com.gempukku.lotro.cards.build.field.effect.modifier; + +import com.gempukku.lotro.cards.build.*; +import com.gempukku.lotro.cards.build.field.EffectProcessor; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.game.PhysicalCard; +import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.modifiers.Modifier; +import com.gempukku.lotro.logic.modifiers.RoamingPenaltyModifier; +import org.json.simple.JSONObject; + +public class ModifyRoamingPenalty implements EffectProcessor { + @Override + public void processEffect(JSONObject value, BuiltLotroCardBlueprint blueprint, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(value, "filter", "condition", "amount"); + + final int amount = FieldUtils.getInteger(value.get("amount"), "amount"); + final JSONObject[] conditionArray = FieldUtils.getObjectArray(value.get("condition"), "condition"); + final String filter = FieldUtils.getString(value.get("filter"), "filter", "self"); + + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); + final Requirement[] requirements = environment.getRequirementFactory().getRequirements(conditionArray, environment); + + blueprint.appendInPlayModifier( + new ModifierSource() { + @Override + public Modifier getModifier(LotroGame game, PhysicalCard self) { + return new RoamingPenaltyModifier(self, + filterableSource.getFilterable(null, game, self, null, null), + new RequirementCondition(requirements, null, self, null, null), amount); + } + }); + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/OpponentMayNotDiscard.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/OpponentMayNotDiscard.java new file mode 100644 index 000000000..2f02b8f60 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/modifier/OpponentMayNotDiscard.java @@ -0,0 +1,25 @@ +package com.gempukku.lotro.cards.build.field.effect.modifier; + +import com.gempukku.lotro.cards.build.BuiltLotroCardBlueprint; +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.field.EffectProcessor; +import com.gempukku.lotro.cards.build.field.FieldUtils; +import com.gempukku.lotro.logic.modifiers.CantDiscardFromPlayByPlayerModifier; +import org.json.simple.JSONObject; + +public class OpponentMayNotDiscard implements EffectProcessor { + @Override + public void processEffect(JSONObject effectObject, BuiltLotroCardBlueprint blueprint, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "filter"); + + final String filter = FieldUtils.getString(effectObject.get("filter"), "filter", "self"); + final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter); + + blueprint.appendInPlayModifier( + (game, self) -> new CantDiscardFromPlayByPlayerModifier(self, "Can't be discarded by opponent", + filterableSource.getFilterable(null, game, self, null, null), + self.getOwner())); + } +}