|
|
|
|
@@ -29,277 +29,83 @@ public class FilterFactory {
|
|
|
|
|
for (Race value : Race.values())
|
|
|
|
|
appendFilter(value);
|
|
|
|
|
|
|
|
|
|
simpleFilters.put("ring bearer", (actionContext) -> Filters.ringBearer);
|
|
|
|
|
simpleFilters.put("ringbearer", (actionContext) -> Filters.ringBearer);
|
|
|
|
|
simpleFilters.put("ring-bearer", (actionContext) -> Filters.ringBearer);
|
|
|
|
|
simpleFilters.put("any", (actionContext) -> Filters.any);
|
|
|
|
|
simpleFilters.put("self", ActionContext::getSource);
|
|
|
|
|
simpleFilters.put("allyincurrentregion", (actionContext) -> Filters.isAllyInCurrentRegion());
|
|
|
|
|
simpleFilters.put("another", (actionContext) -> Filters.not(actionContext.getSource()));
|
|
|
|
|
simpleFilters.put("your", (actionContext) -> Filters.owner(actionContext.getPerformingPlayer()));
|
|
|
|
|
simpleFilters.put("unique", (actionContext) -> Filters.unique);
|
|
|
|
|
simpleFilters.put("bearer", (actionContext -> Filters.hasAttached(actionContext.getSource())));
|
|
|
|
|
simpleFilters.put("character", (actionContext) -> Filters.character);
|
|
|
|
|
simpleFilters.put("mounted", (actionContext) -> Filters.mounted);
|
|
|
|
|
simpleFilters.put("weapon", (actionContext) -> Filters.weapon);
|
|
|
|
|
simpleFilters.put("item", (actionContext) -> Filters.item);
|
|
|
|
|
simpleFilters.put("wounded", (actionContext) -> Filters.wounded);
|
|
|
|
|
simpleFilters.put("unwounded", (actionContext) -> Filters.unwounded);
|
|
|
|
|
simpleFilters.put("exhausted", (actionContext) -> Filters.exhausted);
|
|
|
|
|
simpleFilters.put("inskirmish", (actionContext) -> Filters.inSkirmish);
|
|
|
|
|
simpleFilters.put("infierceskirmish", (actionContext) -> Filters.inFierceSkirmish);
|
|
|
|
|
simpleFilters.put("inplay", (actionContext) -> Filters.inPlay);
|
|
|
|
|
simpleFilters.put("notassignedtoskirmish",
|
|
|
|
|
(actionContext) -> Filters.notAssignedToSkirmish);
|
|
|
|
|
simpleFilters.put("skirmishloser",
|
|
|
|
|
(actionContext) -> {
|
|
|
|
|
final CharacterLostSkirmishResult lostSkirmish = (CharacterLostSkirmishResult) actionContext.getEffectResult();
|
|
|
|
|
return lostSkirmish.getLoser();
|
|
|
|
|
});
|
|
|
|
|
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("any", (actionContext) -> Filters.any);
|
|
|
|
|
simpleFilters.put("attachedtoinsameregion",
|
|
|
|
|
actionContext -> {
|
|
|
|
|
final PhysicalCard attachedTo = actionContext.getSource().getAttachedTo();
|
|
|
|
|
return Filters.region(GameUtils.getRegion(attachedTo.getSiteNumber()));
|
|
|
|
|
});
|
|
|
|
|
simpleFilters.put("insameregion",
|
|
|
|
|
actionContext -> Filters.region(GameUtils.getRegion(actionContext.getSource().getSiteNumber())));
|
|
|
|
|
simpleFilters.put("bearer", (actionContext -> Filters.hasAttached(actionContext.getSource())));
|
|
|
|
|
simpleFilters.put("character", (actionContext) -> Filters.character);
|
|
|
|
|
simpleFilters.put("controlledsite",
|
|
|
|
|
(actionContext -> Filters.siteControlled(actionContext.getPerformingPlayer())));
|
|
|
|
|
simpleFilters.put("currentsite",
|
|
|
|
|
(actionContext) -> Filters.currentSite);
|
|
|
|
|
simpleFilters.put("currentsitenumber",
|
|
|
|
|
(actionContext -> Filters.siteNumber(actionContext.getGame().getGameState().getCurrentSiteNumber())));
|
|
|
|
|
simpleFilters.put("siteincurrentregion",
|
|
|
|
|
(actionContext) -> Filters.siteInCurrentRegion);
|
|
|
|
|
simpleFilters.put("sitehassitenumber",
|
|
|
|
|
(actionContext) -> Filters.siteHasSiteNumber);
|
|
|
|
|
simpleFilters.put("exhausted", (actionContext) -> Filters.exhausted);
|
|
|
|
|
simpleFilters.put("idinstored",
|
|
|
|
|
(actionContext ->
|
|
|
|
|
new Filter() {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
|
|
|
|
|
final String whileInZoneData = (String) actionContext.getSource().getWhileInZoneData();
|
|
|
|
|
if (whileInZoneData == null)
|
|
|
|
|
return false;
|
|
|
|
|
for (String cardId : whileInZoneData.split(",")) {
|
|
|
|
|
if (cardId.equals(String.valueOf(physicalCard.getCardId())))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(Filter) (game, physicalCard) -> {
|
|
|
|
|
final String whileInZoneData = (String) actionContext.getSource().getWhileInZoneData();
|
|
|
|
|
if (whileInZoneData == null)
|
|
|
|
|
return false;
|
|
|
|
|
for (String cardId : whileInZoneData.split(",")) {
|
|
|
|
|
if (cardId.equals(String.valueOf(physicalCard.getCardId())))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
simpleFilters.put("controlledsite",
|
|
|
|
|
(actionContext -> Filters.siteControlled(actionContext.getPerformingPlayer())));
|
|
|
|
|
|
|
|
|
|
parameterFilters.put("culture", (parameter, environment) -> {
|
|
|
|
|
final Culture culture = Culture.valueOf(parameter.toUpperCase());
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> culture;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("signet", (parameter, environment) -> {
|
|
|
|
|
final Signet signet = Signet.valueOf(parameter.toUpperCase());
|
|
|
|
|
if (signet == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> signet;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("cultureFromMemory", ((parameter, environment) -> actionContext -> {
|
|
|
|
|
Set<Culture> cultures = new HashSet<>();
|
|
|
|
|
for (PhysicalCard physicalCard : actionContext.getCardsFromMemory(parameter)) {
|
|
|
|
|
cultures.add(physicalCard.getBlueprint().getCulture());
|
|
|
|
|
}
|
|
|
|
|
return Filters.or(cultures.toArray(new Culture[0]));
|
|
|
|
|
}));
|
|
|
|
|
parameterFilters.put("side", (parameter, environment) -> {
|
|
|
|
|
final Side side = Side.Parse(parameter);
|
|
|
|
|
if (side == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find side for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> side;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasToken", (parameter, environment) -> {
|
|
|
|
|
final Culture culture = Culture.valueOf(parameter.toUpperCase());
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
final Token token = Token.findTokenForCulture(culture);
|
|
|
|
|
if (token == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find token for culture: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> Filters.hasToken(token);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasTokenCount", (parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final Culture culture = Culture.valueOf(parameterSplit[1].toUpperCase());
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
final Token token = Token.findTokenForCulture(culture);
|
|
|
|
|
if (token == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find token for culture: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> Filters.hasToken(token, count);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasAttached",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.hasAttached(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasAttachedCount",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameterSplit[1], environment);
|
|
|
|
|
return (actionContext) -> Filters.hasAttached(count, filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasStacked",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.hasStacked(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasStackedCount",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameterSplit[1], environment);
|
|
|
|
|
return (actionContext) -> Filters.hasStacked(count, filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("attachedTo",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.attachedTo(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("name",
|
|
|
|
|
(parameter, environment) -> (actionContext) -> (Filter)
|
|
|
|
|
(game, physicalCard) -> physicalCard.getBlueprint().getTitle().equalsIgnoreCase(parameter));
|
|
|
|
|
parameterFilters.put("title",parameterFilters.get("name"));
|
|
|
|
|
parameterFilters.put("nameInStackedOn",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return actionContext -> {
|
|
|
|
|
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
|
|
|
|
return (Filter) (game, physicalCard) -> {
|
|
|
|
|
for (PhysicalCard cardWithStack : Filters.filterActive(game, sourceFilterable)) {
|
|
|
|
|
for (PhysicalCard stackedCard : game.getGameState().getStackedCards(cardWithStack)) {
|
|
|
|
|
if (stackedCard.getBlueprint().getTitle().equals(physicalCard.getBlueprint().getTitle()))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}));
|
|
|
|
|
simpleFilters.put("infierceskirmish", (actionContext) -> Filters.inFierceSkirmish);
|
|
|
|
|
simpleFilters.put("inplay", (actionContext) -> Filters.inPlay);
|
|
|
|
|
simpleFilters.put("insameregion",
|
|
|
|
|
actionContext -> Filters.region(GameUtils.getRegion(actionContext.getSource().getSiteNumber())));
|
|
|
|
|
simpleFilters.put("inskirmish", (actionContext) -> Filters.inSkirmish);
|
|
|
|
|
simpleFilters.put("item", (actionContext) -> Filters.item);
|
|
|
|
|
simpleFilters.put("mounted", (actionContext) -> Filters.mounted);
|
|
|
|
|
simpleFilters.put("notassignedtoskirmish",
|
|
|
|
|
(actionContext) -> Filters.notAssignedToSkirmish);
|
|
|
|
|
simpleFilters.put("ringbearer", (actionContext) -> Filters.ringBearer);
|
|
|
|
|
simpleFilters.put("ring-bearer", (actionContext) -> Filters.ringBearer);
|
|
|
|
|
simpleFilters.put("ringbound",
|
|
|
|
|
(actionContext) -> Filters.ringBoundCompanion);
|
|
|
|
|
simpleFilters.put("ring-bound",
|
|
|
|
|
(actionContext) -> Filters.ringBoundCompanion);
|
|
|
|
|
simpleFilters.put("self", ActionContext::getSource);
|
|
|
|
|
simpleFilters.put("sitehassitenumber",
|
|
|
|
|
(actionContext) -> Filters.siteHasSiteNumber);
|
|
|
|
|
simpleFilters.put("siteincurrentregion",
|
|
|
|
|
(actionContext) -> Filters.siteInCurrentRegion);
|
|
|
|
|
simpleFilters.put("skirmishloser",
|
|
|
|
|
(actionContext) -> {
|
|
|
|
|
final CharacterLostSkirmishResult lostSkirmish = (CharacterLostSkirmishResult) actionContext.getEffectResult();
|
|
|
|
|
return lostSkirmish.getLoser();
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("inSkirmishAgainst",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.inSkirmishAgainst(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("assignedToSkirmish",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.assignedToSkirmishAgainst(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("resistanceLessThan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
int amount = Integer.parseInt(parameter);
|
|
|
|
|
return (actionContext) -> Filters.maxResistance(amount - 1);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("resistanceMoreThan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
int amount = Integer.parseInt(parameter);
|
|
|
|
|
return (actionContext) -> Filters.minResistance(amount + 1);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("strengthLessThan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
int amount = Integer.parseInt(parameter);
|
|
|
|
|
return (actionContext) -> Filters.lessStrengthThan(amount);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("strengthMoreThan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
int amount = Integer.parseInt(parameter);
|
|
|
|
|
return (actionContext) -> Filters.moreStrengthThan(amount);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("vitalityMoreThan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
int amount = Integer.parseInt(parameter);
|
|
|
|
|
return (actionContext) -> Filters.moreVitalityThan(amount);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("not",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.not(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("allyHome",
|
|
|
|
|
simpleFilters.put("unbound",
|
|
|
|
|
(actionContext) -> Filters.unboundCompanion);
|
|
|
|
|
simpleFilters.put("unique", (actionContext) -> Filters.unique);
|
|
|
|
|
simpleFilters.put("unwounded", (actionContext) -> Filters.unwounded);
|
|
|
|
|
simpleFilters.put("weapon", (actionContext) -> Filters.weapon);
|
|
|
|
|
simpleFilters.put("wounded", (actionContext) -> Filters.wounded);
|
|
|
|
|
simpleFilters.put("your", (actionContext) -> Filters.owner(actionContext.getPerformingPlayer()));
|
|
|
|
|
|
|
|
|
|
parameterFilters.put("allyhome",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final String[] parameterSplit = parameter.split(",");
|
|
|
|
|
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameterSplit[0].toUpperCase().replace('_', ' '));
|
|
|
|
|
final SitesBlock sitesBlock = SitesBlock.findBlock(parameterSplit[0]);
|
|
|
|
|
int number = Integer.parseInt(parameterSplit[1]);
|
|
|
|
|
return (actionContext) -> Filters.isAllyHome(number, sitesBlock);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("allyInRegion",
|
|
|
|
|
parameterFilters.put("allyinregion",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final String[] parameterSplit = parameter.split(",");
|
|
|
|
|
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameterSplit[0].toUpperCase().replace('_', ' '));
|
|
|
|
|
int number = Integer.parseInt(parameterSplit[1]);
|
|
|
|
|
return (actionContext) -> Filters.isAllyInRegion(number, sitesBlock);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("allyInCurrentRegion",
|
|
|
|
|
(parameter, environment) -> (actionContext) -> Filters.isAllyInCurrentRegion());
|
|
|
|
|
parameterFilters.put("siteBlock",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameter.toUpperCase().replace(' ', '_'));
|
|
|
|
|
return (actionContext) -> Filters.siteBlock(sitesBlock);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("siteNumber",
|
|
|
|
|
(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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
FilterableSource[] filterables = new FilterableSource[filters.length];
|
|
|
|
|
for (int i = 0; i < filters.length; i++)
|
|
|
|
|
filterables[i] = environment.getFilterFactory().generateFilter(filters[i], environment);
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
Filterable[] filters1 = new Filterable[filterables.length];
|
|
|
|
|
for (int i = 0; i < filterables.length; i++)
|
|
|
|
|
filters1[i] = filterables[i].getFilterable(actionContext);
|
|
|
|
|
|
|
|
|
|
return Filters.or(filters1);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("and",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final String[] filters = splitIntoFilters(parameter);
|
|
|
|
|
@@ -314,9 +120,116 @@ public class FilterFactory {
|
|
|
|
|
return Filters.and(filters1);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("memory",
|
|
|
|
|
(parameter, environment) -> (actionContext) -> Filters.in(actionContext.getCardsFromMemory(parameter)));
|
|
|
|
|
parameterFilters.put("maxTwilight",
|
|
|
|
|
parameterFilters.put("assignabletoskirmishagainst",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource againstFilterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return actionContext -> {
|
|
|
|
|
final Side side = GameUtils.getSide(actionContext.getGame(), actionContext.getPerformingPlayer());
|
|
|
|
|
return Filters.assignableToSkirmishAgainst(side, againstFilterableSource.getFilterable(actionContext));
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("assignedtoskirmish",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.assignedToSkirmishAgainst(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("attachedto",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.attachedTo(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("culture", (parameter, environment) -> {
|
|
|
|
|
final Culture culture = Culture.findCulture(parameter);
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> culture;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("culturefrommemory", ((parameter, environment) -> actionContext -> {
|
|
|
|
|
Set<Culture> cultures = new HashSet<>();
|
|
|
|
|
for (PhysicalCard physicalCard : actionContext.getCardsFromMemory(parameter)) {
|
|
|
|
|
cultures.add(physicalCard.getBlueprint().getCulture());
|
|
|
|
|
}
|
|
|
|
|
return Filters.or(cultures.toArray(new Culture[0]));
|
|
|
|
|
}));
|
|
|
|
|
parameterFilters.put("hasattached",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.hasAttached(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasattachedcount",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameterSplit[1], environment);
|
|
|
|
|
return (actionContext) -> Filters.hasAttached(count, filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasstacked",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.hasStacked(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasstackedcount",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameterSplit[1], environment);
|
|
|
|
|
return (actionContext) -> Filters.hasStacked(count, filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hasanytokens", (parameter, environment) -> {
|
|
|
|
|
int count = Integer.parseInt(parameter != null ? parameter : "1");
|
|
|
|
|
return (actionContext) -> Filters.hasAnyCultureTokens(count);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hastoken", (parameter, environment) -> {
|
|
|
|
|
final Culture culture = Culture.findCulture(parameter);
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
final Token token = Token.findTokenForCulture(culture);
|
|
|
|
|
if (token == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find token for culture: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> Filters.hasToken(token);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("hastokencount", (parameter, environment) -> {
|
|
|
|
|
String[] parameterSplit = parameter.split(",", 2);
|
|
|
|
|
int count = Integer.parseInt(parameterSplit[0]);
|
|
|
|
|
final Culture culture = Culture.findCulture(parameterSplit[1]);
|
|
|
|
|
if (culture == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find culture for: " + parameter);
|
|
|
|
|
final Token token = Token.findTokenForCulture(culture);
|
|
|
|
|
if (token == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find token for culture: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> Filters.hasToken(token, count);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("inskirmishagainst",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.inSkirmishAgainst(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("loweststrength",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return actionContext -> {
|
|
|
|
|
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
|
|
|
|
return Filters.and(
|
|
|
|
|
sourceFilterable, Filters.strengthEqual(
|
|
|
|
|
new SingleMemoryEvaluator(
|
|
|
|
|
new Evaluator() {
|
|
|
|
|
@Override
|
|
|
|
|
public int evaluateExpression(LotroGame game, PhysicalCard cardAffected) {
|
|
|
|
|
int minStrength = Integer.MAX_VALUE;
|
|
|
|
|
for (PhysicalCard card : Filters.filterActive(game, sourceFilterable))
|
|
|
|
|
minStrength = Math.min(minStrength, game.getModifiersQuerying().getStrength(game, card));
|
|
|
|
|
return minStrength;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("maxtwilight",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
if (parameter.startsWith("memory(") && parameter.endsWith(")")) {
|
|
|
|
|
String memory = parameter.substring(parameter.indexOf("(") + 1, parameter.lastIndexOf(")"));
|
|
|
|
|
@@ -337,7 +250,9 @@ public class FilterFactory {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("minTwilight",
|
|
|
|
|
parameterFilters.put("memory",
|
|
|
|
|
(parameter, environment) -> (actionContext) -> Filters.in(actionContext.getCardsFromMemory(parameter)));
|
|
|
|
|
parameterFilters.put("mintwilight",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
if (parameter.startsWith("memory(") && parameter.endsWith(")")) {
|
|
|
|
|
String memory = parameter.substring(parameter.indexOf("(") + 1, parameter.lastIndexOf(")"));
|
|
|
|
|
@@ -358,34 +273,55 @@ public class FilterFactory {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("lowestStrength",
|
|
|
|
|
|
|
|
|
|
parameterFilters.put("name",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
String name = Sanitize(parameter);
|
|
|
|
|
return (actionContext) -> (Filter)
|
|
|
|
|
(game, physicalCard) -> name != null
|
|
|
|
|
&& physicalCard.getBlueprint().getTitle() != null
|
|
|
|
|
&& name.equals(Sanitize(physicalCard.getBlueprint().getTitle()));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("namefrommemory",
|
|
|
|
|
(parameter, environment) -> actionContext -> {
|
|
|
|
|
Set<String> titles = new HashSet<>();
|
|
|
|
|
for (PhysicalCard physicalCard : actionContext.getCardsFromMemory(parameter))
|
|
|
|
|
titles.add(physicalCard.getBlueprint().getTitle());
|
|
|
|
|
return (Filter) (game, physicalCard) -> titles.contains(physicalCard.getBlueprint().getTitle());
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("nameinstackedon",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return actionContext -> {
|
|
|
|
|
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
|
|
|
|
return Filters.and(
|
|
|
|
|
sourceFilterable, Filters.strengthEqual(
|
|
|
|
|
new SingleMemoryEvaluator(
|
|
|
|
|
new Evaluator() {
|
|
|
|
|
@Override
|
|
|
|
|
public int evaluateExpression(LotroGame game, PhysicalCard cardAffected) {
|
|
|
|
|
int minStrength = Integer.MAX_VALUE;
|
|
|
|
|
for (PhysicalCard card : Filters.filterActive(game, sourceFilterable))
|
|
|
|
|
minStrength = Math.min(minStrength, game.getModifiersQuerying().getStrength(game, card));
|
|
|
|
|
return minStrength;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
return (Filter) (game, physicalCard) -> {
|
|
|
|
|
for (PhysicalCard cardWithStack : Filters.filterActive(game, sourceFilterable)) {
|
|
|
|
|
for (PhysicalCard stackedCard : game.getGameState().getStackedCards(cardWithStack)) {
|
|
|
|
|
if (stackedCard.getBlueprint().getTitle().equals(physicalCard.getBlueprint().getTitle()))
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("assignableToSkirmishAgainst",
|
|
|
|
|
parameterFilters.put("not",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final FilterableSource againstFilterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return actionContext -> {
|
|
|
|
|
final Side side = GameUtils.getSide(actionContext.getGame(), actionContext.getPerformingPlayer());
|
|
|
|
|
return Filters.assignableToSkirmishAgainst(side, againstFilterableSource.getFilterable(actionContext));
|
|
|
|
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
|
|
|
|
return (actionContext) -> Filters.not(filterableSource.getFilterable(actionContext));
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("or",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final String[] filters = splitIntoFilters(parameter);
|
|
|
|
|
FilterableSource[] filterables = new FilterableSource[filters.length];
|
|
|
|
|
for (int i = 0; i < filters.length; i++)
|
|
|
|
|
filterables[i] = environment.getFilterFactory().generateFilter(filters[i], environment);
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
Filterable[] filters1 = new Filterable[filterables.length];
|
|
|
|
|
for (int i = 0; i < filterables.length; i++)
|
|
|
|
|
filters1[i] = filterables[i].getFilterable(actionContext);
|
|
|
|
|
|
|
|
|
|
return Filters.or(filters1);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("race",
|
|
|
|
|
@@ -398,7 +334,7 @@ public class FilterFactory {
|
|
|
|
|
else
|
|
|
|
|
return Race.valueOf(value) == physicalCard.getBlueprint().getRace();
|
|
|
|
|
};
|
|
|
|
|
} else if (parameter.equals("cannotSpot")) {
|
|
|
|
|
} else if (parameter.equals("cannotspot")) {
|
|
|
|
|
return actionContext -> (Filter) (game, physicalCard) -> {
|
|
|
|
|
final Race race = physicalCard.getBlueprint().getRace();
|
|
|
|
|
if (race != null)
|
|
|
|
|
@@ -406,27 +342,108 @@ public class FilterFactory {
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
throw new InvalidCardDefinitionException("Unknown race definition in filter");
|
|
|
|
|
throw new InvalidCardDefinitionException("Unknown race definition in filter: " + parameter
|
|
|
|
|
+ ". Do not use race() for races; instead just list the race by itself.");
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("nameFromMemory",
|
|
|
|
|
new FilterableSourceProducer() {
|
|
|
|
|
@Override
|
|
|
|
|
public FilterableSource createFilterableSource(String parameter, CardGenerationEnvironment environment) {
|
|
|
|
|
return new FilterableSource() {
|
|
|
|
|
@Override
|
|
|
|
|
public Filterable getFilterable(ActionContext actionContext) {
|
|
|
|
|
Set<String> titles = new HashSet<>();
|
|
|
|
|
for (PhysicalCard physicalCard : actionContext.getCardsFromMemory(parameter))
|
|
|
|
|
titles.add(physicalCard.getBlueprint().getTitle());
|
|
|
|
|
return new Filter() {
|
|
|
|
|
@Override
|
|
|
|
|
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
|
|
|
|
|
return titles.contains(physicalCard.getBlueprint().getTitle());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
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("resistancelessthan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.maxResistance(amount - 1);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("resistancemorethan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.minResistance(amount + 1);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("side", (parameter, environment) -> {
|
|
|
|
|
final Side side = Side.Parse(parameter);
|
|
|
|
|
if (side == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find side for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> side;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("signet", (parameter, environment) -> {
|
|
|
|
|
final Signet signet = Signet.findSignet(parameter);
|
|
|
|
|
if (signet == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find signet for: " + parameter);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> signet;
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("siteblock",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final SitesBlock sitesBlock = SitesBlock.findBlock(parameter);
|
|
|
|
|
return (actionContext) -> Filters.siteBlock(sitesBlock);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("sitenumber",
|
|
|
|
|
(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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> Filters.siteNumberBetweenInclusive(min, max);
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("strengthlessthan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.lessStrengthThan(amount);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("strengthmorethan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.moreStrengthThan(amount);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("title",parameterFilters.get("name"));
|
|
|
|
|
parameterFilters.put("vitalitylessthan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.lessVitalityThan(amount);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("vitalitymorethan",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(parameter, environment);
|
|
|
|
|
return (actionContext) -> {
|
|
|
|
|
int amount = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
|
|
|
|
return Filters.moreVitalityThan(amount);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
parameterFilters.put("zone",
|
|
|
|
|
(parameter, environment) -> {
|
|
|
|
|
@@ -436,7 +453,7 @@ public class FilterFactory {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void appendFilter(Filterable value) {
|
|
|
|
|
final String filterName = value.toString().toLowerCase().replace("_", " ");
|
|
|
|
|
final String filterName = Sanitize(value.toString());
|
|
|
|
|
final String optionalFilterName = value.toString().toLowerCase().replace("_", "-");
|
|
|
|
|
if (simpleFilters.containsKey(filterName))
|
|
|
|
|
throw new RuntimeException("Duplicate filter name: " + filterName);
|
|
|
|
|
@@ -508,23 +525,33 @@ public class FilterFactory {
|
|
|
|
|
if (filterString.contains("(") && filterString.endsWith(")")) {
|
|
|
|
|
String filterName = filterString.substring(0, filterString.indexOf("("));
|
|
|
|
|
String filterParameter = filterString.substring(filterString.indexOf("(") + 1, filterString.lastIndexOf(")"));
|
|
|
|
|
return lookupFilter(filterName, filterParameter, environment);
|
|
|
|
|
return lookupFilter(Sanitize(filterName), Sanitize(filterParameter), environment);
|
|
|
|
|
}
|
|
|
|
|
return lookupFilter(filterString, null, environment);
|
|
|
|
|
return lookupFilter(Sanitize(filterString), null, environment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private FilterableSource lookupFilter(String name, String parameter, CardGenerationEnvironment environment) throws
|
|
|
|
|
InvalidCardDefinitionException {
|
|
|
|
|
if (parameter == null) {
|
|
|
|
|
FilterableSource result = simpleFilters.get(name.toLowerCase());
|
|
|
|
|
FilterableSource result = simpleFilters.get(Sanitize(name));
|
|
|
|
|
if (result != null)
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final FilterableSourceProducer filterableSourceProducer = parameterFilters.get(name);
|
|
|
|
|
final FilterableSourceProducer filterableSourceProducer = parameterFilters.get(Sanitize(name));
|
|
|
|
|
if (filterableSourceProducer == null)
|
|
|
|
|
throw new InvalidCardDefinitionException("Unable to find filter: " + name);
|
|
|
|
|
|
|
|
|
|
return filterableSourceProducer.createFilterableSource(parameter, environment);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static String Sanitize(String input)
|
|
|
|
|
{
|
|
|
|
|
return input
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.replace(" ", "")
|
|
|
|
|
.replace("_", "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|