mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 20:39:10 +00:00
添加高斯分布和最大耐久值
This commit is contained in:
@@ -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 <T> void register(Key key, ItemDataModifierFactory<T> factory) {
|
||||
((WritableRegistry<ItemDataModifierFactory<?>>) 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);
|
||||
|
||||
@@ -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<I> implements SimpleNetworkItemDataModifier<I> {
|
||||
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<I> apply(Item<I> item, ItemBuildContext context) {
|
||||
item.maxDamage(argument.getInt(context));
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Key componentType(Item<I> item, ItemBuildContext context) {
|
||||
return ComponentKeys.MAX_DAMAGE;
|
||||
}
|
||||
|
||||
public static class Factory<I> implements ItemDataModifierFactory<I> {
|
||||
|
||||
@Override
|
||||
public ItemDataModifier<I> create(Object arg) {
|
||||
NumberProvider numberProvider = NumberProviders.fromObject(arg);
|
||||
return new MaxDamageModifier<>(numberProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,11 +90,11 @@ public abstract class AbstractRecipeSerializer<T, R extends Recipe<T>> 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<T> resultItem = (BuildableItem<T>) CraftEngine.instance().itemManager().getBuildableItem(Key.of(id)).orElseThrow(() -> new LocalizedResourceConfigException("warning.config.recipe.invalid_visual_result", id));
|
||||
BuildableItem<T> resultItem = (BuildableItem<T>) 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<PostProcessor<T>> processors = ResourceConfigUtils.parseConfigAsList(resultMap.get("post-processors"), PostProcessors::fromMap);
|
||||
return new CustomRecipeResult<>(
|
||||
|
||||
@@ -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<String, Object> 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user