269 lines
10 KiB
Java
269 lines
10 KiB
Java
package top.r3944realms.superleadrope.config;
|
|
|
|
import net.minecraftforge.common.ForgeConfigSpec;
|
|
|
|
import java.util.List;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* The type Leash common config.
|
|
*/
|
|
public class LeashCommonConfig {
|
|
/**
|
|
* The constant BUILDER.
|
|
*/
|
|
public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
|
|
/**
|
|
* The constant SPEC.
|
|
*/
|
|
public static final ForgeConfigSpec SPEC;
|
|
/**
|
|
* The constant COMMON.
|
|
*/
|
|
public static final Common COMMON;
|
|
|
|
static {
|
|
BUILDER.comment("Leash Common Config");
|
|
COMMON = new Common(BUILDER);
|
|
SPEC = BUILDER.build();
|
|
}
|
|
|
|
/**
|
|
* The type Common.
|
|
*/
|
|
public static class Common {
|
|
/**
|
|
* The Enable slp mod command prefix.
|
|
*/
|
|
// Command
|
|
public final ForgeConfigSpec.BooleanValue enableSLPModCommandPrefix;
|
|
/**
|
|
* The Slp mod command prefix.
|
|
*/
|
|
public final ForgeConfigSpec.ConfigValue<String> SLPModCommandPrefix;
|
|
|
|
/**
|
|
* The Teleport whitelist.
|
|
*/
|
|
// Entity
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends String>> teleportWhitelist;
|
|
|
|
/**
|
|
* The Max leash length.
|
|
*/
|
|
// Leash settings
|
|
public final ForgeConfigSpec.DoubleValue maxLeashLength;
|
|
/**
|
|
* The Elastic distance scale.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue elasticDistanceScale;
|
|
/**
|
|
* The Extreme snap factor.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue extremeSnapFactor;
|
|
/**
|
|
* The Spring dampening.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue springDampening;
|
|
/**
|
|
* The Axis specific elasticity.
|
|
*/
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends Double>> axisSpecificElasticity;
|
|
/**
|
|
* The Max leashes per entity.
|
|
*/
|
|
public final ForgeConfigSpec.IntValue maxLeashesPerEntity;
|
|
|
|
/**
|
|
* The Enable true damping.
|
|
*/
|
|
// True damping
|
|
public final ForgeConfigSpec.BooleanValue enableTrueDamping;
|
|
/**
|
|
* The Damping factor.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue dampingFactor;
|
|
/**
|
|
* The Max force.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue maxForce;
|
|
/**
|
|
* The Player spring factor.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue playerSpringFactor;
|
|
/**
|
|
* The Mob spring factor.
|
|
*/
|
|
public final ForgeConfigSpec.DoubleValue mobSpringFactor;
|
|
|
|
/**
|
|
* The Default apply entity location offset.
|
|
*/
|
|
// Leash state offsets
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends String>> defaultApplyEntityLocationOffset;
|
|
/**
|
|
* The Default holder location offset.
|
|
*/
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends String>> defaultHolderLocationOffset;
|
|
|
|
/**
|
|
* The constant OFFSET_PATTERN.
|
|
*/
|
|
// 正则表达式模式
|
|
static final Pattern OFFSET_PATTERN = Pattern.compile(
|
|
"(?i)(?:vec3|vec3d|vector3|offset)\\s*\\(\\s*([-+]?[0-9]*\\.?[0-9]+)\\s*,\\s*([-+]?[0-9]*\\.?[0-9]+)\\s*,\\s*([-+]?[0-9]*\\.?[0-9]+)\\s*\\)\\s*:\\s*\\[\\s*([^]]+?)\\s*]\\s*"
|
|
);
|
|
|
|
/**
|
|
* Instantiates a new Common.
|
|
*
|
|
* @param builder the builder
|
|
*/
|
|
public Common(ForgeConfigSpec.Builder builder) {
|
|
// ===== Command =====
|
|
builder.push("Command");
|
|
enableSLPModCommandPrefix = builder
|
|
.comment("Enable or disable the SLP mod command prefix")
|
|
.define("enableSLPModCommandPrefix", true);
|
|
|
|
SLPModCommandPrefix = builder
|
|
.comment("The prefix of this mod's commands", " [ Default:'slp'] ")
|
|
.define("SLPModCommandPrefix", "slp");
|
|
builder.pop();
|
|
|
|
// ===== Entity =====
|
|
builder.push("Entity");
|
|
teleportWhitelist = builder
|
|
.comment(
|
|
"Entity teleport whitelist.",
|
|
"Accepted formats:",
|
|
" - #modid : allow teleporting to all entities from a specific mod",
|
|
" - modid:entity_name : allow teleporting to a specific entity",
|
|
" - #modid:tag_name : allow teleporting to all entities under a given entity type tag"
|
|
)
|
|
.defineListAllowEmpty(
|
|
List.of("teleportWhitelist"),
|
|
List.of("#minecraft", "modernlife:bicycle", "modernlife:motorboat"),
|
|
o -> o instanceof String s && isValidEntityRefFormat(s)
|
|
);
|
|
builder.pop();
|
|
|
|
// ===== Leash Settings =====
|
|
builder.push("LeashSettings");
|
|
maxLeashLength = builder
|
|
.comment("Maximum leash distance (in blocks) for any entity")
|
|
.defineInRange("maxLeashLength", 6.0, 1.0, 256.0);
|
|
|
|
elasticDistanceScale = builder
|
|
.comment("Default elastic distance for the Super Lead rope")
|
|
.defineInRange("elasticDistanceScale", 1.0, 0.2, 4.0);
|
|
|
|
extremeSnapFactor = builder
|
|
.comment("Leash break factor = maxDistance * factor")
|
|
.defineInRange("extremeSnapFactor", 2.0, 1.0, 4.0);
|
|
|
|
springDampening = builder
|
|
.comment("Spring dampening coefficient")
|
|
.defineInRange("springDampening", 0.7, 0.0, 1.0);
|
|
|
|
axisSpecificElasticity = builder
|
|
.comment("Axis-specific elasticity coefficients for X,Y,Z axes")
|
|
.defineList("axisSpecificElasticity", List.of(0.8, 0.2, 0.8), o -> o instanceof Double);
|
|
|
|
maxLeashesPerEntity = builder
|
|
.comment("Maximum number of leashes per entity")
|
|
.defineInRange("maxLeashesPerEntity", 6, 1, 24);
|
|
builder.pop();
|
|
|
|
// ===== True Damping =====
|
|
builder.push("TrueDamping");
|
|
enableTrueDamping = builder
|
|
.comment("Enable true velocity-based damping force (adds -c*v term)")
|
|
.define("enableTrueDamping", true);
|
|
|
|
dampingFactor = builder
|
|
.comment("Damping factor (resistance against entity velocity)")
|
|
.defineInRange("dampingFactor", 0.1, 0.0, 2.0);
|
|
|
|
maxForce = builder
|
|
.comment("Maximum leash pulling force (to prevent over-aggressive pulling)")
|
|
.defineInRange("maxForce", 1.0, 0.1, 10.0);
|
|
|
|
playerSpringFactor = builder
|
|
.comment("Spring stiffness multiplier for players")
|
|
.defineInRange("playerSpringFactor", 0.3, 0.05, 1.0);
|
|
|
|
mobSpringFactor = builder
|
|
.comment("Spring stiffness multiplier for mobs")
|
|
.defineInRange("mobSpringFactor", 0.5, 0.05, 2.0);
|
|
builder.pop();
|
|
|
|
// ===== Leash State Offsets =====
|
|
builder.push("LeashStateSettings");
|
|
defaultApplyEntityLocationOffset = builder
|
|
.comment(
|
|
"Default leash attachment point offsets for entities.",
|
|
"Reference point: the entity's eyeHeight (eye / head position).",
|
|
"Format: vec3(x,y,z) : [entity_list]",
|
|
"Optional names: vector3, vec3d, offset",
|
|
"Example: vec3(0,0.2,0) : [minecraft:bee, minecraft:horse]",
|
|
"Priority order: specific entity > tag > mod > *"
|
|
)
|
|
.defineListAllowEmpty(
|
|
List.of("defaultApplyEntityLocationOffset"),
|
|
List.of(
|
|
"vec3(0,-0.2,0) : [*]",
|
|
"vec3(0,-0.22,-0.2) : [minecraft:player]"
|
|
),
|
|
o -> o instanceof String s && isValidOffsetRefFormat(s)
|
|
);
|
|
|
|
defaultHolderLocationOffset = builder
|
|
.comment(
|
|
"Default leash holder attachment point offsets (where the leash attaches to the holder).",
|
|
"Reference point: the entity's eyeHeight (eye / head position).",
|
|
"Format: vec3(x,y,z) : [entity_list]",
|
|
"Optional names: vector3, vec3d, offset",
|
|
"Example: vec3(0,-0.5,0) : [minecraft:player]",
|
|
"Priority order: specific entity > tag > mod > *"
|
|
)
|
|
.defineListAllowEmpty(
|
|
List.of("defaultHolderLocationOffset"),
|
|
List.of(
|
|
"vec3(0,-0.2,0) : [*]",
|
|
"vec3(0,-0.6,0) : [minecraft:player]"
|
|
),
|
|
o -> o instanceof String s && isValidOffsetRefFormat(s)
|
|
);
|
|
builder.pop();
|
|
}
|
|
|
|
private static boolean isValidEntityRefFormat(String s) {
|
|
if ("*".equals(s)) return true; // 支持任意实体通配
|
|
if (s.startsWith("#")) {
|
|
String body = s.substring(1);
|
|
return body.matches("[a-z0-9_]+(:[a-z0-9_/]+)?");
|
|
}
|
|
return s.matches("[a-z0-9_]+:[a-z0-9_/]+");
|
|
}
|
|
|
|
private static boolean isValidOffsetRefFormat(String s) {
|
|
Matcher matcher = OFFSET_PATTERN.matcher(s);
|
|
if (!matcher.matches()) return false;
|
|
try {
|
|
Double.parseDouble(matcher.group(1));
|
|
Double.parseDouble(matcher.group(2));
|
|
Double.parseDouble(matcher.group(3));
|
|
String[] entities = matcher.group(4).split(",");
|
|
for (String entity : entities) {
|
|
if (!isValidEntityRefFormat(entity.trim())) return false;
|
|
}
|
|
return true;
|
|
} catch (NumberFormatException e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|