feat: configurable food cost and same team tag restriction
Some checks failed
Build / build (push) Has been cancelled

foodCost.xxx replaces halveFood.xxx, supports percentage or fixed value

teleportSameTeamOnly: only target players with matching team name tag
This commit is contained in:
LiuEnder
2026-04-26 11:36:40 +08:00
parent 08cba8216a
commit f8e58cc2f1
3 changed files with 59 additions and 24 deletions

View File

@@ -32,9 +32,13 @@ public class Config {
.define("allowCrossDimension.permanent", true);
public static final ModConfigSpec.BooleanValue TELEPORT_TEAM_ONLY = BUILDER
.comment("Teleport Mirror can only target players on the same team")
.comment("Teleport Mirror can only target players on the same team object")
.define("teleportTeamOnly", true);
public static final ModConfigSpec.BooleanValue TELEPORT_SAME_TEAM_ONLY = BUILDER
.comment("Teleport Mirror can only target players with the same team name (team tag). Default: off.")
.define("teleportSameTeamOnly", false);
public static final ModConfigSpec.IntValue BASIC_DURABILITY = BUILDER
.comment("Durability for Basic tier mirrors")
.defineInRange("basicDurability", 10, 0, Integer.MAX_VALUE);
@@ -47,21 +51,21 @@ public class Config {
.comment("Durability for Advanced tier mirrors")
.defineInRange("advancedDurability", 100, 0, Integer.MAX_VALUE);
public static final ModConfigSpec.BooleanValue HALVE_FOOD_BASIC = BUILDER
.comment("Halve food when using Basic tier mirrors")
.define("halveFood.basic", true);
public static final ModConfigSpec.ConfigValue<String> FOOD_COST_BASIC = BUILDER
.comment("Food cost for Basic tier mirrors. \"50%\" = 50% of current food. \"10\" = fixed 10 half-shanks. Empty \"\" = no cost.")
.define("foodCost.basic", "50%");
public static final ModConfigSpec.BooleanValue HALVE_FOOD_INTERMEDIATE = BUILDER
.comment("Halve food when using Intermediate tier mirrors")
.define("halveFood.intermediate", true);
public static final ModConfigSpec.ConfigValue<String> FOOD_COST_INTERMEDIATE = BUILDER
.comment("Food cost for Intermediate tier mirrors. \"50%\" = 50% of current food. \"10\" = fixed 10 half-shanks. Empty \"\" = no cost.")
.define("foodCost.intermediate", "50%");
public static final ModConfigSpec.BooleanValue HALVE_FOOD_ADVANCED = BUILDER
.comment("Halve food when using Advanced tier mirrors")
.define("halveFood.advanced", true);
public static final ModConfigSpec.ConfigValue<String> FOOD_COST_ADVANCED = BUILDER
.comment("Food cost for Advanced tier mirrors. \"50%\" = 50% of current food. \"10\" = fixed 10 half-shanks. Empty \"\" = no cost.")
.define("foodCost.advanced", "50%");
public static final ModConfigSpec.BooleanValue HALVE_FOOD_PERMANENT = BUILDER
.comment("Halve food when using Permanent tier mirrors")
.define("halveFood.permanent", false);
public static final ModConfigSpec.ConfigValue<String> FOOD_COST_PERMANENT = BUILDER
.comment("Food cost for Permanent tier mirrors. \"50%\" = 50% of current food. \"10\" = fixed 10 half-shanks. Empty \"\" = no cost.")
.define("foodCost.permanent", "");
public static final ModConfigSpec.ConfigValue<String> EFFECTS_RETURN_BASIC = BUILDER
.comment("Effects for Basic Return Mirror. Format: \"effect_id,dur_sec,amplifier;...\"")

View File

@@ -191,12 +191,12 @@ public class MirrorItem extends Item {
};
}
private boolean shouldHalveFood() {
private String getFoodCostConfig() {
return switch (tier) {
case BASIC -> Config.HALVE_FOOD_BASIC.get();
case INTERMEDIATE -> Config.HALVE_FOOD_INTERMEDIATE.get();
case ADVANCED -> Config.HALVE_FOOD_ADVANCED.get();
case PERMANENT -> Config.HALVE_FOOD_PERMANENT.get();
case BASIC -> Config.FOOD_COST_BASIC.get();
case INTERMEDIATE -> Config.FOOD_COST_INTERMEDIATE.get();
case ADVANCED -> Config.FOOD_COST_ADVANCED.get();
case PERMANENT -> Config.FOOD_COST_PERMANENT.get();
};
}
@@ -233,15 +233,35 @@ public class MirrorItem extends Item {
player.addEffect(new MobEffectInstance(holder, durationSeconds * 20, amplifier)));
}
if (shouldHalveFood()) {
halveFood(player);
}
applyFoodCost(player);
}
private void halveFood(Player player) {
private void applyFoodCost(Player player) {
String config = getFoodCostConfig();
if (config == null || config.isBlank()) {
return;
}
FoodData foodData = player.getFoodData();
foodData.setFoodLevel(Math.max(1, foodData.getFoodLevel() / 2));
foodData.setSaturation(0);
String trimmed = config.trim();
if (trimmed.endsWith("%")) {
String pctStr = trimmed.substring(0, trimmed.length() - 1);
try {
float percentage = Float.parseFloat(pctStr) / 100f;
int cost = Math.round(foodData.getFoodLevel() * percentage);
foodData.setFoodLevel(Math.max(0, foodData.getFoodLevel() - cost));
foodData.setSaturation(Math.max(0, foodData.getSaturationLevel() * (1f - percentage)));
} catch (NumberFormatException ignored) {
}
} else {
try {
int cost = Integer.parseInt(trimmed);
foodData.setFoodLevel(Math.max(0, foodData.getFoodLevel() - cost));
foodData.setSaturation(Math.max(0, foodData.getSaturationLevel() - cost));
} catch (NumberFormatException ignored) {
}
}
}
@Override

View File

@@ -39,6 +39,7 @@ public class MirrorNetwork {
List<String> names = new ArrayList<>();
List<UUID> uuids = new ArrayList<>();
boolean teamOnly = Config.TELEPORT_TEAM_ONLY.get();
boolean sameTeamOnly = Config.TELEPORT_SAME_TEAM_ONLY.get();
for (ServerPlayer onlinePlayer : player.server.getPlayerList().getPlayers()) {
if (onlinePlayer.getUUID().equals(player.getUUID())) {
@@ -49,6 +50,16 @@ public class MirrorNetwork {
continue;
}
}
if (sameTeamOnly) {
var playerTeam = player.getTeam();
var targetTeam = onlinePlayer.getTeam();
if (playerTeam == null || targetTeam == null) {
continue;
}
if (!playerTeam.getName().equals(targetTeam.getName())) {
continue;
}
}
names.add(onlinePlayer.getName().getString());
uuids.add(onlinePlayer.getUUID());
}