164 lines
7.9 KiB
Java
164 lines
7.9 KiB
Java
/*
|
|
* Super Lead rope mod
|
|
* Copyright (C) 2025 R3944Realms
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package top.r3944realms.superleadrope.config;
|
|
|
|
import net.minecraftforge.common.ForgeConfigSpec;
|
|
|
|
import java.util.List;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class LeashCommonConfig {
|
|
public static ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
|
|
public static ForgeConfigSpec SPEC;
|
|
public static final Common COMMON;
|
|
static {
|
|
BUILDER.comment("Leash Common Config");
|
|
COMMON = new Common(BUILDER);
|
|
SPEC = BUILDER.build();
|
|
}
|
|
public static class Common {
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends String>> teleportWhitelist;
|
|
public final ForgeConfigSpec.ConfigValue<String> SLPModCommandPrefix;
|
|
public final ForgeConfigSpec.BooleanValue EnableSLPModCommandPrefix;
|
|
public final ForgeConfigSpec.DoubleValue maxLeashLength;
|
|
public final ForgeConfigSpec.DoubleValue elasticDistance;
|
|
public final ForgeConfigSpec.DoubleValue extremeSnapFactor;
|
|
public final ForgeConfigSpec.DoubleValue springDampening;
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends Double>> axisSpecificElasticity;
|
|
public final ForgeConfigSpec.IntValue maxLeashesPerEntity;
|
|
public final ForgeConfigSpec.ConfigValue<List<? extends String>> defaultApplyEntityLocationOffset;
|
|
// 正则表达式模式
|
|
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*" );
|
|
|
|
public Common(ForgeConfigSpec.Builder builder) {
|
|
BUILDER.push("Command");
|
|
EnableSLPModCommandPrefix = builder
|
|
.comment("The prefix of this mod's commands")
|
|
.define("SLPModCommandPrefix", true);
|
|
SLPModCommandPrefix = builder
|
|
.comment("The prefix of this mod's commands", " [ Default:'slp'] ")
|
|
.define("EnableSLPModCommandPrefix", "slp");
|
|
BUILDER.pop();
|
|
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("allowedTeleportEntities"),
|
|
List.of("#minecraft", "modernlife:bicycle", "modernlife:motorboat"),
|
|
o -> o instanceof String s && isValidEntityRefFormat(s)
|
|
);
|
|
builder.pop();
|
|
builder.push("LeashSettings");
|
|
maxLeashLength = builder
|
|
.comment("Maximum leash distance (in blocks) for any entity")
|
|
.defineInRange("maxLeashLength", 12.0, 6.0, 256.0);
|
|
elasticDistance = builder
|
|
.comment("Default elastic distance for the Super Lead rope")
|
|
.defineInRange("elasticDistance", 6.0, 6.0, 128.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();
|
|
builder.push("LeashStateSettings");
|
|
defaultApplyEntityLocationOffset = builder
|
|
.comment(
|
|
"Default leash attachment point offsets for entities.",
|
|
"Format: vec3(x,y,z) : [entity_list]",
|
|
"Optional Name : vector3, vec3d, offset",
|
|
"Entity list can contain:",
|
|
" - modid:entity_id : specific entity (e.g. minecraft:bee)",
|
|
" - #modid:tag_name : entity type tag (e.g. #minecraft:boats)",
|
|
" - #modid : mod-wide (e.g. #minecraft)",
|
|
"Multiple entities can be separated by commas",
|
|
"Example: vec3(0,0.2,0) : [minecraft:bee, minecraft:horse]",
|
|
"Priority: specific entity > tag > mod"
|
|
)
|
|
.defineListAllowEmpty(
|
|
List.of("defaultApplyEntityLocationOffset"),
|
|
List.of(
|
|
"vec3(0,0.2,0) : [minecraft:bee]",
|
|
"vec3(0,1.0,0) : [minecraft:horse, minecraft:donkey]",
|
|
"vec3(0,0.5,0) : [#minecraft:boats]",
|
|
"vec3(0,0.4,0) : [#minecraft:minecarts]",
|
|
"vec3(0,0.3,0) : [#minecraft]",
|
|
"vec3(0,0.6,0) : [#modernlife]"
|
|
),
|
|
o -> o instanceof String s && isValidOffsetRefFormat(s)
|
|
);
|
|
BUILDER.pop();
|
|
}
|
|
|
|
private static boolean isValidEntityRefFormat(String s) {
|
|
if (s.startsWith("#")) {
|
|
String body = s.substring(1);
|
|
// 支持 #modid (整个模组)或 #modid:tag_name (标签)
|
|
return body.matches("[a-z0-9_]+(:[a-z0-9_/]+)?");
|
|
}
|
|
// 普通实体 ID: modid:entity_id
|
|
return s.matches("[a-z0-9_]+:[a-z0-9_/]+");
|
|
}
|
|
|
|
private static boolean isValidOffsetRefFormat(String s) {
|
|
// 匹配格式: vec3(x,y,z) : [entity_list]
|
|
Matcher matcher = Common.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 entityList = matcher.group(4);
|
|
String[] entities = entityList.split(",");
|
|
for (String entity : entities) {
|
|
if (!isValidEntityRefFormat(entity.trim())) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} catch (NumberFormatException e) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|