Improvements to the JSON definitions

- Revamped Side parsing so that various aliases can be used such as "freeps"
- Rooted out forRegionNumber value, which was a misnomer and should have been regionNumber
- added regionNumber parameter filter which uses similar logic to the siteNumber filter
- added aliases for ring bound ("ring-bound" and "ringbound")
- removed IsMore condition
- added a slew of related comparison conditions: IsEqual, IsGreaterThan, IsGreaterThanOrEqual, IsLessThan, IsLessThanOrEqual, IsNotEqual
This commit is contained in:
Christian 'ketura' McCarty
2022-07-27 01:35:30 -05:00
parent 4035093c90
commit c64db4ff39
18 changed files with 191 additions and 23 deletions

View File

@@ -208,7 +208,7 @@
{
"type": "conditional",
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachMatchingInMemory",
"memory": "cardsInHand",

View File

@@ -139,7 +139,7 @@
"keyword": "maneuver",
"condition": [
{
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "sum",
"source": [
@@ -995,7 +995,7 @@
"limit": 1
},
{
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachInDeadPile",
"filter": "companion"

View File

@@ -64,7 +64,7 @@
"count": 1
},
{
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "countStacked",
"on": "self",

View File

@@ -123,7 +123,7 @@
"phase": "archery"
},
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "minion"
@@ -164,7 +164,7 @@
"modifier": {
"type": "modifyArcheryTotal",
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "minion"
@@ -298,7 +298,7 @@
"filter": "self"
},
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "minion"
@@ -402,7 +402,7 @@
"phase": "regroup"
},
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "character,man"
@@ -439,7 +439,7 @@
"phase": "assignment"
},
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "companion"

View File

@@ -303,7 +303,7 @@
"type": "activated",
"phase": "maneuver",
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "minion"

View File

@@ -129,7 +129,7 @@
"type": "activated",
"phase": "maneuver",
"condition": {
"type": "isMore",
"type": "isGreaterThan",
"firstNumber": {
"type": "forEachYouCanSpot",
"filter": "minion"

View File

@@ -516,7 +516,7 @@
"effect": {
"type": "addThreats",
"amount": {
"type": "forRegionNumber"
"type": "regionNumber"
}
}
}

View File

@@ -1,5 +1,19 @@
package com.gempukku.lotro.common;
public enum Side implements Filterable {
FREE_PEOPLE, SHADOW
FREE_PEOPLE, SHADOW;
public static Side Parse(String value) {
value = value
.toLowerCase()
.replace("_", " ")
.replace("-", " ");
if(value.contains("shadow"))
return SHADOW;
if(value.contains("freeps") || value.contains("free people") || value.contains("free peoples"))
return FREE_PEOPLE;
return null;
}
}

View File

@@ -102,8 +102,7 @@ public class ValueResolver {
return actionContext -> (game, cardAffected) -> {
return actionContext.getCardFromMemory(memory).getSiteNumber();
};
} else if (type.equalsIgnoreCase("forRegionNumber")) {
FieldUtils.validateAllowedFields(object);
} else if (type.equalsIgnoreCase("regionNumber")) {
return (actionContext) -> (game, cardAffected) -> GameUtils.getRegion(actionContext.getGame());
} else if (type.equalsIgnoreCase("forEachInMemory")) {
FieldUtils.validateAllowedFields(object, "memory", "limit");

View File

@@ -57,6 +57,10 @@ public class FilterFactory {
});
simpleFilters.put("ring bound",
(actionContext) -> Filters.ringBoundCompanion);
simpleFilters.put("ringbound",
(actionContext) -> Filters.ringBoundCompanion);
simpleFilters.put("ring-bound",
(actionContext) -> Filters.ringBoundCompanion);
simpleFilters.put("unbound",
(actionContext) -> Filters.unboundCompanion);
simpleFilters.put("attachedtoinsameregion",
@@ -115,7 +119,7 @@ public class FilterFactory {
return Filters.or(cultures.toArray(new Culture[0]));
}));
parameterFilters.put("side", (parameter, environment) -> {
final Side side = Side.valueOf(parameter.toUpperCase().replace(" ", "_"));
final Side side = Side.Parse(parameter);
if (side == null)
throw new InvalidCardDefinitionException("Unable to find side for: " + parameter);
@@ -268,6 +272,22 @@ public class FilterFactory {
return (actionContext) -> Filters.siteNumberBetweenInclusive(min, max);
});
parameterFilters.put("regionNumber",
(parameter, environment) -> {
int min, max;
if (parameter.contains("-")) {
final String[] split = parameter.split("-", 2);
min = Integer.parseInt(split[0]);
max = Integer.parseInt(split[1]);
} else {
min = max = Integer.parseInt(parameter);
}
if(min < 0 || max > 3 || max < min)
throw new InvalidCardDefinitionException("Region number definition is invalid: " + parameter);
return (actionContext) -> Filters.regionNumberBetweenInclusive(min, max);
});
parameterFilters.put("or",
(parameter, environment) -> {
final String[] filters = splitIntoFilters(parameter);

View File

@@ -0,0 +1,25 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsEqual implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");
final ValueSource firstNumber = ValueResolver.resolveEvaluator(object.get("firstNumber"), environment);
final ValueSource secondNumber = ValueResolver.resolveEvaluator(object.get("secondNumber"), environment);
return actionContext -> {
final int first = firstNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
final int second = secondNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return first == second;
};
}
}

View File

@@ -8,7 +8,7 @@ import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsMore implements RequirementProducer {
public class IsGreaterThan implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");

View File

@@ -0,0 +1,25 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsGreaterThanOrEqual implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");
final ValueSource firstNumber = ValueResolver.resolveEvaluator(object.get("firstNumber"), environment);
final ValueSource secondNumber = ValueResolver.resolveEvaluator(object.get("secondNumber"), environment);
return actionContext -> {
final int first = firstNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
final int second = secondNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return first >= second;
};
}
}

View File

@@ -0,0 +1,25 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsLessThan implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");
final ValueSource firstNumber = ValueResolver.resolveEvaluator(object.get("firstNumber"), environment);
final ValueSource secondNumber = ValueResolver.resolveEvaluator(object.get("secondNumber"), environment);
return actionContext -> {
final int first = firstNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
final int second = secondNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return first < second;
};
}
}

View File

@@ -0,0 +1,25 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsLessThanOrEqual implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");
final ValueSource firstNumber = ValueResolver.resolveEvaluator(object.get("firstNumber"), environment);
final ValueSource secondNumber = ValueResolver.resolveEvaluator(object.get("secondNumber"), environment);
return actionContext -> {
final int first = firstNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
final int second = secondNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return first <= second;
};
}
}

View File

@@ -0,0 +1,25 @@
package com.gempukku.lotro.cards.build.field.effect.requirement;
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
import com.gempukku.lotro.cards.build.Requirement;
import com.gempukku.lotro.cards.build.ValueSource;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
import org.json.simple.JSONObject;
public class IsNotEqual implements RequirementProducer {
@Override
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "firstNumber", "secondNumber");
final ValueSource firstNumber = ValueResolver.resolveEvaluator(object.get("firstNumber"), environment);
final ValueSource secondNumber = ValueResolver.resolveEvaluator(object.get("secondNumber"), environment);
return actionContext -> {
final int first = firstNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
final int second = secondNumber.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
return first != second;
};
}
}

View File

@@ -32,7 +32,12 @@ public class RequirementFactory {
requirementProducers.put("hasinhand", new HasInHand());
requirementProducers.put("hasinzonedata", new HasInZoneData());
requirementProducers.put("haveinitiative", new HaveInitiative());
requirementProducers.put("ismore", new IsMore());
requirementProducers.put("isequal", new IsEqual());
requirementProducers.put("isgreaterthan", new IsGreaterThan());
requirementProducers.put("isgreaterthanorequal", new IsGreaterThanOrEqual());
requirementProducers.put("islessthan", new IsLessThan());
requirementProducers.put("islessthanorequal", new IsLessThanOrEqual());
requirementProducers.put("isnotequal", new IsNotEqual());
requirementProducers.put("isowner", new IsOwnerRequirementProducer());
requirementProducers.put("isside", new IsSideRequirementProducer());
requirementProducers.put("location", new Location());

View File

@@ -744,8 +744,6 @@ public class Filters {
}
};
public static Filter siteNumber(final int siteNumber) {
return siteNumberBetweenInclusive(siteNumber, siteNumber);
}
@@ -775,12 +773,19 @@ public class Filters {
}
});
public static Filter region(final int region) {
public static Filter region(final int region) { return regionNumberBetweenInclusive(region, region); }
public static Filter regionNumberBetweenInclusive(final int minRegionNumber, final int maxRegionNumber) {
return new Filter() {
@Override
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
int siteNumber = physicalCard.getSiteNumber();
return GameUtils.getRegion(siteNumber) == region;
if(physicalCard.getSiteNumber() == null)
return false;
int regionNumber = GameUtils.getRegion(physicalCard.getSiteNumber());
return regionNumber >= minRegionNumber && regionNumber <= maxRegionNumber;
}
};
}