From 36180e31d5447c57f31d30dafcf43ac742e49914 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Wed, 27 Aug 2025 21:06:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=AB=98=E6=96=AF=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=92=8C=E6=9C=80=E5=A4=A7=E8=80=90=E4=B9=85=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/translations/en.yml | 2 + .../src/main/resources/translations/zh_cn.yml | 2 + .../core/item/modifier/ItemDataModifiers.java | 2 + .../core/item/modifier/MaxDamageModifier.java | 45 ++++++++ .../item/recipe/AbstractRecipeSerializer.java | 6 +- .../number/GaussianNumberProvider.java | 104 ++++++++++++++++++ .../context/number/NumberProviders.java | 2 + 7 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/net/momirealms/craftengine/core/item/modifier/MaxDamageModifier.java create mode 100644 core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/GaussianNumberProvider.java diff --git a/common-files/src/main/resources/translations/en.yml b/common-files/src/main/resources/translations/en.yml index 8e5f7be8b..efd506c7d 100644 --- a/common-files/src/main/resources/translations/en.yml +++ b/common-files/src/main/resources/translations/en.yml @@ -83,6 +83,8 @@ warning.config.number.fixed.invalid_value: "Issue found in file warning.config.number.expression.missing_expression: "Issue found in file - The config '' is missing the required 'expression' argument for 'expression' number." warning.config.number.uniform.missing_min: "Issue found in file - The config '' is missing the required 'min' argument for 'uniform' number." warning.config.number.uniform.missing_max: "Issue found in file - The config '' is missing the required 'max' argument for 'uniform' number." +warning.config.number.gaussian.missing_min: "Issue found in file - The config '' is missing the required 'min' argument for 'gaussian' number." +warning.config.number.gaussian.missing_max: "Issue found in file - The config '' is missing the required 'max' argument for 'gaussian' number." warning.config.condition.all_of.missing_terms: "Issue found in file - The config '' is missing the required 'terms' argument for 'all_of' condition." warning.config.condition.all_of.invalid_terms_type: "Issue found in file - The config '' has a misconfigured 'all_of' condition, 'terms' should be a map list, current type: ''." warning.config.condition.any_of.missing_terms: "Issue found in file - The config '' is missing the required 'terms' argument for 'any_of' condition." diff --git a/common-files/src/main/resources/translations/zh_cn.yml b/common-files/src/main/resources/translations/zh_cn.yml index cbd2408d8..239100483 100644 --- a/common-files/src/main/resources/translations/zh_cn.yml +++ b/common-files/src/main/resources/translations/zh_cn.yml @@ -83,6 +83,8 @@ warning.config.number.fixed.invalid_value: "在文件 发现问 warning.config.number.expression.missing_expression: "在文件 发现问题 - 配置项 '' 缺少 'expression' 数字类型所需的 'expression' 参数" warning.config.number.uniform.missing_min: "在文件 发现问题 - 配置项 '' 缺少 'uniform' 数字类型所需的 'min' 参数" warning.config.number.uniform.missing_max: "在文件 发现问题 - 配置项 '' 缺少 'uniform' 数字类型所需的 'max' 参数" +warning.config.number.gaussian.missing_min: "在文件 发现问题 - 配置项 '' 缺少 'gaussian' 数字类型所需的 'min' 参数" +warning.config.number.gaussian.missing_max: "在文件 发现问题 - 配置项 '' 缺少 'gaussian' 数字类型所需的 'max' 参数" warning.config.condition.all_of.missing_terms: "在文件 发现问题 - 配置项 '' 缺少 'all_of' 条件所需的 'terms' 参数" warning.config.condition.all_of.invalid_terms_type: "在文件 发现问题 - 配置项 '' 的 'all_of' 条件配置错误, 'terms' 应为映射列表, 当前类型: ''" warning.config.condition.any_of.missing_terms: "在文件 发现问题 - 配置项 '' 缺少 'any_of' 条件所需的 'terms' 参数" diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java index 2b6672de8..82eafdef4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/ItemDataModifiers.java @@ -45,6 +45,7 @@ public final class ItemDataModifiers { public static final Key UNBREAKABLE = Key.of("craftengine:unbreakable"); public static final Key DYNAMIC_LORE = Key.of("craftengine:dynamic-lore"); public static final Key OVERWRITABLE_LORE = Key.of("craftengine:overwritable-lore"); + public static final Key MAX_DAMAGE = Key.of("craftengine:max-damage"); public static void register(Key key, ItemDataModifierFactory factory) { ((WritableRegistry>) BuiltInRegistries.ITEM_DATA_MODIFIER_FACTORY) @@ -83,6 +84,7 @@ public final class ItemDataModifiers { register(COMPONENTS, ComponentsModifier.FACTORY); register(REMOVE_COMPONENTS, RemoveComponentModifier.FACTORY); register(FOOD, FoodModifier.FACTORY); + register(MAX_DAMAGE, MaxDamageModifier.FACTORY); } else { register(CUSTOM_NAME, CustomNameModifier.FACTORY); register(ITEM_NAME, CustomNameModifier.FACTORY); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/modifier/MaxDamageModifier.java b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/MaxDamageModifier.java new file mode 100644 index 000000000..277b42ae4 --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/item/modifier/MaxDamageModifier.java @@ -0,0 +1,45 @@ +package net.momirealms.craftengine.core.item.modifier; + +import net.momirealms.craftengine.core.item.ComponentKeys; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.item.ItemDataModifierFactory; +import net.momirealms.craftengine.core.plugin.context.number.NumberProvider; +import net.momirealms.craftengine.core.plugin.context.number.NumberProviders; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; +import org.jetbrains.annotations.Nullable; + +public class MaxDamageModifier implements SimpleNetworkItemDataModifier { + public static final Factory FACTORY = new Factory<>(); + private final NumberProvider argument; + + public MaxDamageModifier(NumberProvider argument) { + this.argument = argument; + } + + @Override + public Key type() { + return ItemDataModifiers.MAX_DAMAGE; + } + + @Override + public Item apply(Item item, ItemBuildContext context) { + item.maxDamage(argument.getInt(context)); + return item; + } + + @Override + public @Nullable Key componentType(Item item, ItemBuildContext context) { + return ComponentKeys.MAX_DAMAGE; + } + + public static class Factory implements ItemDataModifierFactory { + + @Override + public ItemDataModifier create(Object arg) { + NumberProvider numberProvider = NumberProviders.fromObject(arg); + return new MaxDamageModifier<>(numberProvider); + } + } +} diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java index 6d9162d8d..d6a3460f5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/AbstractRecipeSerializer.java @@ -90,11 +90,11 @@ public abstract class AbstractRecipeSerializer> implement if (resultMap == null) { return null; } - String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(resultMap.get("id"), "warning.config.recipe.visual_result.missing_id"); + String id = ResourceConfigUtils.requireNonEmptyStringOrThrow(resultMap.get("id"), "warning.config.recipe.result.missing_id"); int count = ResourceConfigUtils.getAsInt(resultMap.getOrDefault("count", 1), "count"); - BuildableItem resultItem = (BuildableItem) CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_visual_result", id)); + BuildableItem resultItem = (BuildableItem) CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id)); if (resultItem.isEmpty()) { - throw new LocalizedResourceConfigException("warning.config.recipe.invalid_visual_result", id); + throw new LocalizedResourceConfigException("warning.config.recipe.invalid_result", id); } List> processors = ResourceConfigUtils.parseConfigAsList(resultMap.get("post-processors"), PostProcessors::fromMap); return new CustomRecipeResult<>( diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/GaussianNumberProvider.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/GaussianNumberProvider.java new file mode 100644 index 000000000..6ca708f2b --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/GaussianNumberProvider.java @@ -0,0 +1,104 @@ +package net.momirealms.craftengine.core.plugin.context.number; + +import net.momirealms.craftengine.core.plugin.context.Context; +import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.MCUtils; +import net.momirealms.craftengine.core.util.ResourceConfigUtils; + +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class GaussianNumberProvider implements NumberProvider { + public static final FactoryImpl FACTORY = new FactoryImpl(); + + private final double min; + private final double max; + private final double mean; + private final double stdDev; + private final int maxAttempts; + + public GaussianNumberProvider(double min, double max, double mean, double stdDev, int maxAttempts) { + this.min = min; + this.max = max; + this.mean = mean; + this.stdDev = stdDev; + this.maxAttempts = maxAttempts; + validateParameters(); + } + + private void validateParameters() { + if (this.min >= this.max) { + throw new IllegalArgumentException("min must be less than max"); + } + if (this.stdDev <= 0) { + throw new IllegalArgumentException("std-dev must be greater than 0"); + } + if (this.maxAttempts <= 0) { + throw new IllegalArgumentException("max-attempts must be greater than 0"); + } + } + + @Override + public float getFloat(Context context) { + return (float) getDouble(context); + } + + @Override + public double getDouble(Context context) { + Random random = ThreadLocalRandom.current(); + int attempts = 0; + while (attempts < maxAttempts) { + double value = random.nextGaussian() * stdDev + mean; + if (value >= min && value <= max) { + return value; + } + attempts++; + } + return MCUtils.clamp(this.mean, this.min, this.max); + } + + @Override + public Key type() { + return NumberProviders.GAUSSIAN; + } + + public double min() { + return min; + } + + public double max() { + return max; + } + + public int maxAttempts() { + return maxAttempts; + } + + public double mean() { + return mean; + } + + public double stdDev() { + return stdDev; + } + + public static class FactoryImpl implements NumberProviderFactory { + + @Override + public NumberProvider create(Map arguments) { + double min = ResourceConfigUtils.getAsDouble(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("min"), "warning.config.number.gaussian.missing_min"), "min"); + double max = ResourceConfigUtils.getAsDouble(ResourceConfigUtils.requireNonNullOrThrow(arguments.get("max"), "warning.config.number.gaussian.missing_max"), "max"); + double mean = ResourceConfigUtils.getAsDouble(arguments.getOrDefault("mean", (min + max) / 2.0), "mean"); + double stdDev = ResourceConfigUtils.getAsDouble(arguments.getOrDefault("std-dev", (max - min) / 6.0), "std-dev"); + int maxAttempts = ResourceConfigUtils.getAsInt(arguments.getOrDefault("max-attempts", 128), "max-attempts"); + return new GaussianNumberProvider(min, max, mean, stdDev, maxAttempts); + } + } + + @Override + public String toString() { + return String.format("GaussianNumberProvider{min=%.2f, max=%.2f, mean=%.2f, stdDev=%.2f, maxAttempts=%d}", + min, max, mean, stdDev, maxAttempts); + } +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java index 22b698c86..49ce77b1a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java @@ -17,11 +17,13 @@ public class NumberProviders { public static final Key CONSTANT = Key.of("craftengine:constant"); public static final Key UNIFORM = Key.of("craftengine:uniform"); public static final Key EXPRESSION = Key.of("craftengine:expression"); + public static final Key GAUSSIAN = Key.of("craftengine:gaussian"); static { register(FIXED, FixedNumberProvider.FACTORY); register(CONSTANT, FixedNumberProvider.FACTORY); register(UNIFORM, UniformNumberProvider.FACTORY); + register(GAUSSIAN, GaussianNumberProvider.FACTORY); register(EXPRESSION, ExpressionNumberProvider.FACTORY); }