diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/cards/set2/set2-elven.json b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set2/set2-elven.json new file mode 100644 index 000000000..e05482099 --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/web/cards/set2/set2-elven.json @@ -0,0 +1,183 @@ +{ + "2_16": { + "title": "A Blended Race", + "culture": "elven", + "cost": 1, + "type": "condition", + "condition": { + "type": "canSpot", + "filter": "elf" + }, + "keyword": "support area", + "effects": [ + { + "type": "modifier", + "modifier": { + "type": "modifyStrength", + "filter": "uruk-hai", + "amount": -2 + } + }, + { + "type": "modifier", + "modifier": { + "type": "removeKeyword", + "filter": "uruk-hai", + "keyword": "damage" + } + }, + { + "type": "trigger", + "trigger": { + "type": "startOfPhase", + "phase": "regroup" + }, + "effect": { + "type": "discard", + "filter": "self" + } + } + ] + }, + "2_17": { + "title": "Dismay Our Enemies", + "culture": "elven", + "cost": 0, + "type": "event", + "keyword": "response", + "effects": { + "type": "responseEvent", + "trigger": { + "type": "winsSkirmish", + "filter": "elf,archer" + }, + "effect": { + "type": "preventable", + "player": "shadowPlayer", + "effect": { + "type": "discard", + "player": "shadowPlayer", + "filter": "choose(minion)" + }, + "text": "Would you like to remove (3) to prevent discarding a minion?", + "cost": { + "type": "removeTwilight", + "amount": 3 + } + } + } + }, + "2_18": { + "title": "Hosts of the Last Alliance", + "culture": "elven", + "cost": 2, + "type": "condition", + "keyword": [ + "tale", + "support area" + ], + "effects": [ + { + "type": "modifier", + "modifier": { + "type": "modifyArcheryTotal", + "side": "shadow", + "condition": { + "type": "canSpot", + "filter": "elf,companion" + }, + "amount": -1 + } + }, + { + "type": "activatedTrigger", + "trigger": { + "type": "aboutToTakeWound", + "filter": "elf" + }, + "cost": { + "type": "discard", + "filter": "self" + }, + "effect": { + "type": "preventWound", + "filter": "choose(elf)" + } + } + ] + }, + "2_19": { + "title": "Release the Angry Flood", + "culture": "elven", + "cost": 1, + "type": "event", + "keyword": "maneuver", + "effects": { + "type": "event", + "cost": { + "type": "exert", + "filter": "choose(elf)" + }, + "effect": { + "type": "wound", + "filter": "all(nazgul)", + "times": { + "type": "condition", + "condition": { + "type": "location", + "filter": "river" + }, + "true": 2, + "false": 1 + } + } + } + }, + "2_20": { + "title": "Secret Sentinels", + "culture": "elven", + "cost": 2, + "type": "event", + "keyword": "maneuver", + "effects": { + "type": "event", + "cost": { + "type": "exert", + "filter": "choose(elf,ally)" + }, + "effect": [ + { + "type": "memorizeNumber", + "memory": "discardCount", + "amount": 1 + }, + { + "type": "conditional", + "condition": { + "type": "canSpot", + "filter": "orc" + }, + "effect": { + "type": "chooseYesOrNo", + "text": "Would you like to spot an Orc?", + "memorize": "discardCount", + "yes": "2", + "no": "1" + } + }, + { + "type": "discard", + "filter": "choose(condition)", + "count": { + "type": "range", + "from": 1, + "to": { + "type": "fromMemory", + "memory": "discardCount" + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_016.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_016.java deleted file mode 100644 index 870144c9f..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_016.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.gempukku.lotro.cards.set2.elven; - -import com.gempukku.lotro.common.*; -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.RequiredTriggerAction; -import com.gempukku.lotro.logic.cardtype.AbstractPermanent; -import com.gempukku.lotro.logic.effects.SelfDiscardEffect; -import com.gempukku.lotro.logic.modifiers.Modifier; -import com.gempukku.lotro.logic.modifiers.RemoveKeywordModifier; -import com.gempukku.lotro.logic.modifiers.StrengthModifier; -import com.gempukku.lotro.logic.timing.EffectResult; -import com.gempukku.lotro.logic.timing.TriggerConditions; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * Set: Mines of Moria - * Side: Free - * Culture: Elven - * Twilight Cost: 1 - * Type: Condition - * Game Text: To play, spot an Elf. Plays to your support area. Each Uruk-hai is strength -2 and loses all damage - * bonuses. Discard this condition during the regroup phase. - */ -public class Card2_016 extends AbstractPermanent { - public Card2_016() { - super(Side.FREE_PEOPLE, 1, CardType.CONDITION, Culture.ELVEN, "A Blended Race"); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return Filters.canSpot(game, Race.ELF); - } - - @Override - public List getInPlayModifiers(LotroGame game, PhysicalCard self) { - List modifiers = new LinkedList(); - modifiers.add( - new StrengthModifier(self, Race.URUK_HAI, -2)); - modifiers.add( - new RemoveKeywordModifier(self, Race.URUK_HAI, Keyword.DAMAGE)); - return modifiers; - } - - @Override - public List getRequiredAfterTriggers(LotroGame game, EffectResult effectResult, PhysicalCard self) { - if (TriggerConditions.startOfPhase(game, effectResult, Phase.REGROUP)) { - RequiredTriggerAction action = new RequiredTriggerAction(self); - action.appendEffect( - new SelfDiscardEffect(self)); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_017.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_017.java deleted file mode 100644 index 18d2d5038..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_017.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.gempukku.lotro.cards.set2.elven; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.filters.Filters; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.PlayUtils; -import com.gempukku.lotro.logic.actions.CostToEffectAction; -import com.gempukku.lotro.logic.actions.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractResponseEvent; -import com.gempukku.lotro.logic.effects.PreventableEffect; -import com.gempukku.lotro.logic.effects.RemoveTwilightEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndDiscardCardsFromPlayEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseOpponentEffect; -import com.gempukku.lotro.logic.timing.Effect; -import com.gempukku.lotro.logic.timing.EffectResult; -import com.gempukku.lotro.logic.timing.PlayConditions; -import com.gempukku.lotro.logic.timing.TriggerConditions; - -import java.util.Collections; -import java.util.List; - -/** - * Set: Mines of Moria - * Side: Free - * Culture: Elven - * Twilight Cost: 0 - * Type: Event - * Game Text: Response: If an Elf archer wins a skirmish, make an opponent choose a minion to discard. That opponent - * may remove (3) to prevent this. - */ -public class Card2_017 extends AbstractResponseEvent { - public Card2_017() { - super(Side.FREE_PEOPLE, 0, Culture.ELVEN, "Dismay Our Enemies"); - } - - @Override - public List getPlayResponseEventAfterActions(String playerId, LotroGame game, EffectResult effectResult, final PhysicalCard self) { - if (TriggerConditions.winsSkirmish(game, effectResult, Filters.and(Race.ELF, Keyword.ARCHER)) - && PlayConditions.canPlayCardDuringPhase(game, (Phase) null, self) - && PlayUtils.checkPlayRequirements(game, self, Filters.any, 0, 0, false, false)) { - final PlayEventAction action = new PlayEventAction(self); - action.appendEffect( - new ChooseOpponentEffect(playerId) { - @Override - protected void opponentChosen(String opponentId) { - action.appendEffect( - new PreventableEffect(action, - new ChooseAndDiscardCardsFromPlayEffect(action, opponentId, 1, 1, CardType.MINION) { - @Override - public String getText(LotroGame game) { - return "Choose minion to discard"; - } - }, - Collections.singletonList(opponentId), - new PreventableEffect.PreventionCost() { - @Override - public Effect createPreventionCostForPlayer(CostToEffectAction subAction, String playerId) { - return new RemoveTwilightEffect(3); - } - } - )); - } - }); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_018.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_018.java deleted file mode 100644 index e5ba8c830..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_018.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.gempukku.lotro.cards.set2.elven; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.actions.ActivateCardAction; -import com.gempukku.lotro.logic.cardtype.AbstractPermanent; -import com.gempukku.lotro.logic.effects.PreventableCardEffect; -import com.gempukku.lotro.logic.effects.SelfDiscardEffect; -import com.gempukku.lotro.logic.effects.WoundCharactersEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndPreventCardEffect; -import com.gempukku.lotro.logic.modifiers.ArcheryTotalModifier; -import com.gempukku.lotro.logic.modifiers.Modifier; -import com.gempukku.lotro.logic.modifiers.SpotCondition; -import com.gempukku.lotro.logic.timing.Effect; -import com.gempukku.lotro.logic.timing.TriggerConditions; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Set: Mines of Moria - * Side: Free - * Culture: Elven - * Twilight Cost: 2 - * Type: Condition - * Game Text: Tale. Plays to your support area. While you can spot an Elf companion, the minion archery total is -1. - * Response: If an Elf is about to take a wound, discard this condition to prevent that wound. - */ -public class Card2_018 extends AbstractPermanent { - public Card2_018() { - super(Side.FREE_PEOPLE, 2, CardType.CONDITION, Culture.ELVEN, "Hosts of the Last Alliance"); - addKeyword(Keyword.TALE); - } - - @Override - public List getInPlayModifiers(LotroGame game, PhysicalCard self) { -return Collections.singletonList(new ArcheryTotalModifier(self, Side.SHADOW, new SpotCondition(Race.ELF, CardType.COMPANION), -1)); -} - - @Override - public List getOptionalInPlayBeforeActions(String playerId, LotroGame game, Effect effect, PhysicalCard self) { - if (TriggerConditions.isGettingWounded(effect, game, Race.ELF)) { - final WoundCharactersEffect woundEffect = (WoundCharactersEffect) effect; - Collection woundedCharacters = woundEffect.getAffectedCardsMinusPrevented(game); - final ActivateCardAction action = new ActivateCardAction(self); - action.appendCost( - new SelfDiscardEffect(self)); - action.appendEffect( - new ChooseAndPreventCardEffect(self, (PreventableCardEffect) effect, playerId, "Choose an Elf", Race.ELF)); - return Collections.singletonList(action); - } - return null; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_019.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_019.java deleted file mode 100644 index 8258d2fe9..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_019.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.gempukku.lotro.cards.set2.elven; - -import com.gempukku.lotro.common.*; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; -import com.gempukku.lotro.logic.actions.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractEvent; -import com.gempukku.lotro.logic.effects.WoundCharactersEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndExertCharactersEffect; -import com.gempukku.lotro.logic.timing.PlayConditions; - -/** - * Set: Mines of Moria - * Side: Free - * Culture: Elven - * Twilight Cost: 1 - * Type: Event - * Game Text: Maneuver: Exert an Elf to wound each Nazgul once (or twice if at a river). - */ -public class Card2_019 extends AbstractEvent { - public Card2_019() { - super(Side.FREE_PEOPLE, 1, Culture.ELVEN, "Release the Angry Flood", Phase.MANEUVER); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canExert(self, game, Race.ELF); - } - - @Override - public PlayEventAction getPlayEventCardAction(String playerId, LotroGame game, PhysicalCard self) { - PlayEventAction action = new PlayEventAction(self); - action.appendCost( - new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Race.ELF)); - action.appendEffect( - new WoundCharactersEffect(self, Race.NAZGUL)); - if (PlayConditions.location(game, Keyword.RIVER)) - action.appendEffect( - new WoundCharactersEffect(self, Race.NAZGUL)); - return action; - } -} diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_020.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_020.java deleted file mode 100644 index 6bb36517e..000000000 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/set2/elven/Card2_020.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.gempukku.lotro.cards.set2.elven; - -import com.gempukku.lotro.common.*; -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.PlayEventAction; -import com.gempukku.lotro.logic.cardtype.AbstractEvent; -import com.gempukku.lotro.logic.decisions.MultipleChoiceAwaitingDecision; -import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndDiscardCardsFromPlayEffect; -import com.gempukku.lotro.logic.effects.choose.ChooseAndExertCharactersEffect; -import com.gempukku.lotro.logic.timing.PlayConditions; - -/** - * Set: Mines of Moria - * Side: Free - * Culture: Elven - * Twilight Cost: 2 - * Type: Event - * Game Text: Maneuver: Exert an Elf ally to discard a condition (or 2 conditions if you spot an Orc). - */ -public class Card2_020 extends AbstractEvent { - public Card2_020() { - super(Side.FREE_PEOPLE, 2, Culture.ELVEN, "Secret Sentinels", Phase.MANEUVER); - } - - @Override - public boolean checkPlayRequirements(LotroGame game, PhysicalCard self) { - return PlayConditions.canExert(self, game, Race.ELF, CardType.ALLY); - } - - @Override - public PlayEventAction getPlayEventCardAction(final String playerId, LotroGame game, PhysicalCard self) { - final PlayEventAction action = new PlayEventAction(self); - action.appendCost( - new ChooseAndExertCharactersEffect(action, playerId, 1, 1, Race.ELF, CardType.ALLY)); - if (Filters.canSpot(game, Race.ORC)) - action.appendEffect( - new PlayoutDecisionEffect(playerId, - new MultipleChoiceAwaitingDecision(1, "Do you wish to spot an Orc?", new String[]{"Yes", "No"}) { - @Override - protected void validDecisionMade(int index, String result) { - if (result.equals("Yes")) { - action.appendEffect( - new ChooseAndDiscardCardsFromPlayEffect(action, playerId, 2, 2, CardType.CONDITION)); - } else { - action.appendEffect( - new ChooseAndDiscardCardsFromPlayEffect(action, playerId, 1, 1, CardType.CONDITION)); - } - } - })); - else - action.appendEffect( - new ChooseAndDiscardCardsFromPlayEffect(action, playerId, 1, 1, CardType.CONDITION)); - - return action; - } -} 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 223e4a4b4..d4f91e12a 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 @@ -110,6 +110,7 @@ public class EffectAppenderFactory { effectAppenderProducers.put("removecardsindiscardfromgame", new RemoveCardsInDiscardFromGame()); effectAppenderProducers.put("makeselfringbearer", new MakeSelfRingBearer()); effectAppenderProducers.put("choosearace", new ChooseARace()); + effectAppenderProducers.put("chooseyesorno", new ChooseYesOrNo()); effectAppenderProducers.put("chooseakeyword", new ChooseAKeyword()); effectAppenderProducers.put("storewhileinzone", new StoreWhileInZone()); effectAppenderProducers.put("resetwhileinzonedata", new ResetWhileInZoneData()); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseYesOrNo.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseYesOrNo.java new file mode 100644 index 000000000..8bc92c766 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/ChooseYesOrNo.java @@ -0,0 +1,45 @@ +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.field.FieldUtils; +import com.gempukku.lotro.cards.build.field.effect.EffectAppender; +import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; +import com.gempukku.lotro.logic.actions.CostToEffectAction; +import com.gempukku.lotro.logic.decisions.YesNoDecision; +import com.gempukku.lotro.logic.effects.PlayoutDecisionEffect; +import com.gempukku.lotro.logic.timing.Effect; +import org.json.simple.JSONObject; + +public class ChooseYesOrNo implements EffectAppenderProducer { + @Override + public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(effectObject, "text", "memorize", "yes", "no"); + + final String text = FieldUtils.getString(effectObject.get("text"), "text"); + if (text == null) + throw new InvalidCardDefinitionException("Text is required for Yes or No decision"); + final String memorize = FieldUtils.getString(effectObject.get("memorize"), "memorize"); + final String yesAnswer = FieldUtils.getString(effectObject.get("yes"), "yes"); + final String noAnswer = FieldUtils.getString(effectObject.get("no"), "no"); + + return new DelayedAppender() { + @Override + protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { + return new PlayoutDecisionEffect(actionContext.getPerformingPlayer(), + new YesNoDecision(text) { + @Override + protected void yes() { + actionContext.setValueToMemory(memorize, yesAnswer); + } + + @Override + protected void no() { + actionContext.setValueToMemory(memorize, noAnswer); + } + }); + } + }; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java index 846a5bdaa..73ba44d4c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Wound.java @@ -27,7 +27,7 @@ public class Wound implements EffectAppenderProducer { final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); final ValueSource valueSource = ValueResolver.resolveEvaluator(effectObject.get("count"), 1, environment); - final int times = FieldUtils.getInteger(effectObject.get("times"), "times", 1); + final ValueSource times = ValueResolver.resolveEvaluator(effectObject.get("times"), 1, environment); final String filter = FieldUtils.getString(effectObject.get("filter"), "filter"); final String memory = FieldUtils.getString(effectObject.get("memorize"), "memorize", "_temp"); @@ -35,15 +35,16 @@ public class Wound implements EffectAppenderProducer { result.addEffectAppender( CardResolver.resolveCards(filter, - (actionContext) -> Filters.canTakeWounds(actionContext.getSource(), times), + (actionContext) -> Filters.canTakeWounds(actionContext.getSource(), times.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null)), valueSource, memory, player, "Choose cards to wound", environment)); result.addEffectAppender( new DelayedAppender() { @Override protected List createEffects(boolean cost, CostToEffectAction action, ActionContext actionContext) { final Collection cardsFromMemory = actionContext.getCardsFromMemory(memory); + final int timesCount = times.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null); List result = new LinkedList<>(); - for (int i = 0; i < times; i++) + for (int i = 0; i < timesCount; i++) result.add(new WoundCharactersEffect(actionContext.getSource(), Filters.in(cardsFromMemory))); 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 691f9e2d4..196b18e9d 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 @@ -57,7 +57,27 @@ public class ValueResolver { if (value instanceof JSONObject) { JSONObject object = (JSONObject) value; final String type = FieldUtils.getString(object.get("type"), "type"); - if (type.equalsIgnoreCase("condition")) { + if (type.equalsIgnoreCase("range")) { + FieldUtils.validateAllowedFields(object, "from", "to"); + ValueSource fromValue = resolveEvaluator(object.get("from"), environment); + ValueSource toValue = resolveEvaluator(object.get("to"), environment); + return new ValueSource() { + @Override + public Evaluator getEvaluator(ActionContext actionContext) { + throw new RuntimeException("Evaluator has resolved to range"); + } + + @Override + public int getMinimum(ActionContext actionContext) { + return fromValue.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null); + } + + @Override + public int getMaximum(ActionContext actionContext) { + return toValue.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null); + } + }; + } else if (type.equalsIgnoreCase("condition")) { FieldUtils.validateAllowedFields(object, "condition", "true", "false"); final JSONObject[] conditionArray = FieldUtils.getObjectArray(object.get("condition"), "condition"); final Requirement[] conditions = environment.getRequirementFactory().getRequirements(conditionArray, environment); @@ -238,7 +258,7 @@ public class ValueResolver { final ValueSource valueSource = ValueResolver.resolveEvaluator(object.get("source"), 0, environment); return (actionContext) -> new MultiplyEvaluator(multiplier, valueSource.getEvaluator(actionContext)); } else if (type.equalsIgnoreCase("cardAffectedLimitPerPhase")) { - FieldUtils.validateAllowedFields(object, "limit", "source","prefix"); + FieldUtils.validateAllowedFields(object, "limit", "source", "prefix"); final int limit = FieldUtils.getInteger(object.get("limit"), "limit"); final String prefix = FieldUtils.getString(object.get("prefix"), "prefix", ""); final ValueSource valueSource = ValueResolver.resolveEvaluator(object.get("source"), 0, environment);