diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40-elven.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40-elven.json index 7a73a41bf..aa783097b 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40-elven.json +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set40-elven.json @@ -1,2 +1,51 @@ { + "40_33": { + "title": "Arrows of Light", + "side": "free people", + "culture": "elven", + "cost": 2, + "type": "event", + "keyword": "archery", + "requirement": { + "type": "canSpot", + "filter": "elf,archer,companion" + }, + "effects": { + "type": "event", + "cost": { + "type": "reduceArcheryTotal", + "side": "free people", + "memorize": "reducedBy" + }, + "effect": { + "type": "discard", + "count": { + "type": "fromMemory", + "memory": "reducedBy" + }, + "filter": "choose(side(shadow),condition)" + } + } + }, + "40_34": { + "title": "*Arwen", + "subtitle": "Fearless Rider", + "side": "free people", + "culture": "elven", + "cost": 2, + "type": "companion", + "race": "elf", + "strength": 6, + "vitality": 3, + "resistance": 8, + "keyword": "ranger", + "effects": { + "type": "modifyStrength", + "condition": { + "type": "location", + "filter": "or(river,forest)" + }, + "amount": 3 + } + } } \ No newline at end of file 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 ce66f424c..38c015f8d 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 @@ -47,6 +47,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("addtrigger", new AddTrigger()); effectAppenderProducers.put("stackplayedevent", new StackPlayedEvent()); effectAppenderProducers.put("playcardfromdiscard", new PlayCardFromDiscard()); + effectAppenderProducers.put("reducearcherytotal", new ReduceArcheryTotal()); } 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/DelayedAppender.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java index df3798f9e..ed9e9b24c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/DelayedAppender.java @@ -57,14 +57,14 @@ public abstract class DelayedAppender implements EffectAppender { }); } - protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { - return Collections.singletonList(createEffect(action, playerId, game, self, effectResult, effect)); - } - protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { throw new UnsupportedOperationException("One of createEffect or createEffects has to be overwritten"); } + protected Iterable createEffects(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + return Collections.singletonList(createEffect(action, playerId, game, self, effectResult, effect)); + } + @Override public boolean isPlayableInFull(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { return true; diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReduceArcheryTotal.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReduceArcheryTotal.java new file mode 100644 index 000000000..2d7fa8576 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ReduceArcheryTotal.java @@ -0,0 +1,61 @@ +package com.gempukku.lotro.cards.build.field.effect.appender; + +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +import com.gempukku.lotro.cards.build.InvalidCardDefinitionException; +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.common.Side; +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.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.decisions.IntegerAwaitingDecision; +import com.gempukku.lotro.logic.effects.AddUntilEndOfPhaseModifierEffect; +import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect; +import com.gempukku.lotro.logic.modifiers.ArcheryTotalModifier; +import com.gempukku.lotro.logic.timing.Effect; +import com.gempukku.lotro.logic.timing.EffectResult; +import com.gempukku.lotro.logic.timing.RuleUtils; +import org.json.simple.JSONObject; + +public class ReduceArcheryTotal implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "side", "memorize"); + + final Side side = FieldUtils.getEnum(Side.class, effectObject.get("side"), "side"); + final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); + + MultiEffectAppender result = new MultiEffectAppender(); + + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + int archeryTotal = RuleUtils.calculateArcheryTotal(game, side); + return new PlayoutDecisionEffect( + self.getOwner(), + new IntegerAwaitingDecision(1, "Choose number to reduce archery by", 0, archeryTotal, archeryTotal) { + @Override + public void decisionMade(String result) throws DecisionResultInvalidException { + final int validatedResult = getValidatedResult(result); + action.setValueToMemory(memorize, String.valueOf(validatedResult)); + } + }); + } + }); + result.addEffectAppender( + new DelayedAppender() { + @Override + protected Effect createEffect(CostToEffectAction action, String playerId, LotroGame game, PhysicalCard self, EffectResult effectResult, Effect effect) { + int modifier = Integer.parseInt(action.getValueFromMemory(memorize)); + return new AddUntilEndOfPhaseModifierEffect( + new ArcheryTotalModifier(self, side, -modifier)); + } + } + ); + + return result; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/ValueResolver.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/ValueResolver.java index 9853ea490..91ba2e99e 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/ValueResolver.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/resolver/ValueResolver.java @@ -88,6 +88,12 @@ public class ValueResolver { final Filterable on1 = onFilter.getFilterable(playerId, game, self, effectResult, effect); return new CountStackedEvaluator(on1, Filters.any); }; + } else if (type.equalsIgnoreCase("fromMemory")) { + String memory = FieldUtils.getString(object.get("memory"), "memory"); + return (action, playerId, game, self, effectResult, effect) -> { + int value1 = Integer.parseInt(action.getValueFromMemory(memory)); + return new ConstantEvaluator(value1); + }; } else if (type.equalsIgnoreCase("multiply")) { final int multiplier = FieldUtils.getInteger(object.get("multiplier"), "multiplier"); final ValueSource valueSource = ValueResolver.resolveEvaluator(object.get("source"), 0, environment); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleUtils.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleUtils.java index eef0f4fd4..0803ac7ac 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleUtils.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/RuleUtils.java @@ -14,6 +14,13 @@ import java.util.List; import java.util.Set; public class RuleUtils { + public static int calculateArcheryTotal(LotroGame game, Side side) { + if (side == Side.FREE_PEOPLE) + return calculateFellowshipArcheryTotal(game); + else + return calculateShadowArcheryTotal(game); + } + public static int calculateFellowshipArcheryTotal(LotroGame game) { int normalArcheryTotal = Filters.countActive(game, Filters.or(