diff --git a/shared/src/main/java/net/blay09/mods/waystones/config/WaystonesConfigData.java b/shared/src/main/java/net/blay09/mods/waystones/config/WaystonesConfigData.java index 2894f924..a40afbfe 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/config/WaystonesConfigData.java +++ b/shared/src/main/java/net/blay09/mods/waystones/config/WaystonesConfigData.java @@ -32,12 +32,12 @@ public static class Costs { @Synced @ExpectedType(String.class) - @Comment("List of cost modifiers with comma-separated parameters in parentheses. Will be applied in order.") + @Comment("List of cost modifiers with comma-separated parameters in parentheses. Conditions can be defined as comma-separated list in square brackets. Will be applied in order.") public List costModifiers = List.of( - "scaled_add_xp(distance, 0.01)", - "conditional_multiply_xp(source_is_warp_plate, 0)", - "conditional_multiply_xp(target_is_global, 0)", - "conditional_add_xp(is_interdimensional, 27)", + "[is_not_interdimensional] scaled_add_xp(distance, 0.01)", + "[is_interdimensional] add_xp(27)", + "[source_is_warp_plate] multiply_xp(0)", + "[target_is_global] multiply_xp(0)", "min_xp(0)", "max_xp(27)"); } diff --git a/shared/src/main/java/net/blay09/mods/waystones/cost/CostContextImpl.java b/shared/src/main/java/net/blay09/mods/waystones/cost/CostContextImpl.java index bd564562..9ac38275 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/cost/CostContextImpl.java +++ b/shared/src/main/java/net/blay09/mods/waystones/cost/CostContextImpl.java @@ -19,12 +19,16 @@ public CostContextImpl(IWaystoneTeleportContext context) { this.context = context; } - public void apply(Pair, P> modifierAndParameters) { - applyModifier(modifierAndParameters.getFirst(), modifierAndParameters.getSecond()); - } - @SuppressWarnings("unchecked") - public void applyModifier(CostModifier modifier, P parameters) { + public void apply(CostRegistry.ConfiguredCostModifier configuredModifier) { + for (final var condition : configuredModifier.conditions()) { + if (!matchesCondition(condition)) { + return; + } + } + + final var modifier = configuredModifier.modifier(); + final var parameters = configuredModifier.parameters(); var costInstance = (T) costInstances.get(modifier.getCostType()); if (costInstance == null) { costInstance = CostRegistry.getCostType(modifier.getCostType()).createInstance(); diff --git a/shared/src/main/java/net/blay09/mods/waystones/cost/CostRegistry.java b/shared/src/main/java/net/blay09/mods/waystones/cost/CostRegistry.java index 27b5f89a..df08f934 100644 --- a/shared/src/main/java/net/blay09/mods/waystones/cost/CostRegistry.java +++ b/shared/src/main/java/net/blay09/mods/waystones/cost/CostRegistry.java @@ -1,6 +1,5 @@ package net.blay09.mods.waystones.cost; -import com.mojang.datafixers.util.Pair; import net.blay09.mods.waystones.api.IWaystoneTeleportContext; import net.blay09.mods.waystones.api.WaystoneTypes; import net.blay09.mods.waystones.api.WaystoneVisibility; @@ -12,9 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Function; public class CostRegistry { @@ -27,6 +24,9 @@ public class CostRegistry { private static final Map costVariableResolvers = new HashMap<>(); private static final Map costConditionResolvers = new HashMap<>(); + public record ConfiguredCostModifier(CostModifier modifier, List conditions, P parameters) { + } + public record IntParameter(int value) { } @@ -39,9 +39,6 @@ public record IdParameter(ResourceLocation value) { public record VariableScaledParameter(IdParameter id, FloatParameter scale) { } - public record ConditionalFloatParameter(IdParameter id, FloatParameter scale) { - } - public static void registerDefaults() { final var experiencePoints = new ExperiencePointsCostType(); final var levels = new ExperienceLevelCostType(); @@ -53,22 +50,10 @@ public static void registerDefaults() { cost.setLevels((int) (cost.getLevels() + parameters.value)); return cost; }); - registerModifier("conditional_add_levels", levels, ConditionalFloatParameter.class, (cost, context, parameters) -> { - if (context.matchesCondition(parameters.id.value)) { - cost.setLevels((int) (cost.getLevels() + parameters.scale.value)); - } - return cost; - }); registerModifier("multiply_levels", levels, FloatParameter.class, (cost, context, parameters) -> { cost.setLevels((int) (cost.getLevels() * parameters.value)); return cost; }); - registerModifier("conditional_multiply_levels", levels, ConditionalFloatParameter.class, (cost, context, parameters) -> { - if (context.matchesCondition(parameters.id.value)) { - cost.setLevels((int) (cost.getLevels() * parameters.scale.value)); - } - return cost; - }); registerModifier("scaled_add_levels", levels, VariableScaledParameter.class, (cost, context, parameters) -> { final var sourceValue = context.getContextValue(parameters.id.value); cost.setLevels((int) (cost.getLevels() + sourceValue * parameters.scale.value)); @@ -91,22 +76,10 @@ public static void registerDefaults() { cost.setPoints(cost.getPoints() + parameters.value); return cost; }); - registerModifier("conditional_add_xp", experiencePoints, ConditionalFloatParameter.class, (cost, context, parameters) -> { - if (context.matchesCondition(parameters.id.value)) { - cost.setPoints((int) (cost.getPoints() + parameters.scale.value)); - } - return cost; - }); registerModifier("multiply_xp", experiencePoints, FloatParameter.class, (cost, context, parameters) -> { cost.setPoints((int) (cost.getPoints() * parameters.value)); return cost; }); - registerModifier("conditional_multiply_xp", experiencePoints, ConditionalFloatParameter.class, (cost, context, parameters) -> { - if (context.matchesCondition(parameters.id.value)) { - cost.setPoints((int) (cost.getPoints() * parameters.scale.value)); - } - return cost; - }); registerModifier("scaled_add_xp", experiencePoints, VariableScaledParameter.class, (cost, context, parameters) -> { final var sourceValue = context.getContextValue(parameters.id.value); cost.setPoints((int) (cost.getPoints() + sourceValue * parameters.scale.value)); @@ -125,7 +98,6 @@ public static void registerDefaults() { registerSerializer(FloatParameter.class, it -> new FloatParameter(Float.parseFloat(it))); registerSerializer(IdParameter.class, it -> new IdParameter(waystonesResourceLocation(it))); registerDefaultSerializer(VariableScaledParameter.class); - registerDefaultSerializer(ConditionalFloatParameter.class); registerConditionResolver("is_interdimensional", IWaystoneTeleportContext::isDimensionalTeleport); registerConditionResolver("source_is_warp_plate", @@ -175,15 +147,33 @@ public static void register(CostConditionResolver costConditionResolver) { costConditionResolvers.put(costConditionResolver.getId(), costConditionResolver); } - public static Optional, P>> deserializeModifier(String modifier) { - final var openParen = modifier.indexOf('('); - final var closeParen = modifier.indexOf(')'); - if (openParen == -1 || closeParen == -1) { + public static Optional> deserializeModifier(String modifier) { + // format: [commaSeparatedConditions] modifierId(parameter1, parameter2, ...) + final var conditionStart = modifier.indexOf('['); + final var conditionEnd = modifier.indexOf(']'); + final List conditions = new ArrayList<>(); + if (conditionStart != -1 && conditionEnd != -1) { + final var conditionString = modifier.substring(conditionStart + 1, conditionEnd); + for (final var condition : conditionString.split(",")) { + final var conditionId = waystonesResourceLocation(condition.trim()); + final var costCondition = CostRegistry.getConditionResolver(conditionId); + if (costCondition == null) { + logger.error("Failed to process waystone cost: Unknown condition {}", conditionId); + return Optional.empty(); + } + conditions.add(conditionId); + } + } + + final var parameterStart = modifier.indexOf('('); + final var parameterEnd = modifier.indexOf(')'); + if (parameterStart == -1 || parameterEnd == -1) { return Optional.empty(); } - final var modifierId = waystonesResourceLocation(modifier.substring(0, openParen)); - final var parameterString = modifier.substring(openParen + 1, closeParen); + final var modifierStart = conditionEnd != -1 ? conditionEnd + 1 : 0; + final var modifierId = waystonesResourceLocation(modifier.substring(modifierStart, parameterStart).trim()); + final var parameterString = modifier.substring(parameterStart + 1, parameterEnd); final var costModifier = CostRegistry.getCostModifier(modifierId); if (costModifier == null) { return Optional.empty(); @@ -191,7 +181,7 @@ public static Optional, P>> deserial try { final var parameters = deserializeParameter(costModifier.getParameterType(), parameterString); - return Optional.of(Pair.of(costModifier, parameters)); + return Optional.of(new ConfiguredCostModifier(costModifier, conditions, parameters)); } catch (Exception e) { logger.error("Failed to process waystone cost", e); return Optional.empty();