From 6fd5d8490008b5b1c4c3cf77b2867c3c652210e5 Mon Sep 17 00:00:00 2001 From: fretuks Date: Fri, 17 Oct 2025 03:50:09 +0200 Subject: [PATCH] Added Config File --- build.gradle | 7 ++ .../java/net/fretux/knockedback/Config.java | 58 --------------- .../net/fretux/knockedback/KnockedBack.java | 3 +- .../fretux/knockedback/KnockedManager.java | 73 ++++++++++--------- .../fretux/knockedback/MobKillHandler.java | 14 +++- .../knockedback/PlayerExecutionHandler.java | 9 ++- .../client/ExecutionProgressOverlay.java | 4 +- .../net/fretux/knockedback/config/Config.java | 62 ++++++++++++++++ 8 files changed, 129 insertions(+), 101 deletions(-) delete mode 100644 src/main/java/net/fretux/knockedback/Config.java create mode 100644 src/main/java/net/fretux/knockedback/config/Config.java diff --git a/build.gradle b/build.gradle index 5c3034f..d46dc87 100644 --- a/build.gradle +++ b/build.gradle @@ -79,6 +79,13 @@ minecraft { source sourceSets.main } } + jvmArgs += [ + "--add-opens=java.base/java.lang=ALL-UNNAMED", + "--add-opens=java.base/java.lang.module=ALL-UNNAMED", + "--add-exports=java.base/jdk.internal.module=ALL-UNNAMED", + "--add-reads=knockedback=ALL-UNNAMED", + "--add-modules=ALL-SYSTEM" + ] } client { diff --git a/src/main/java/net/fretux/knockedback/Config.java b/src/main/java/net/fretux/knockedback/Config.java deleted file mode 100644 index dd7ca18..0000000 --- a/src/main/java/net/fretux/knockedback/Config.java +++ /dev/null @@ -1,58 +0,0 @@ -package net.fretux.knockedback; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.config.ModConfigEvent; -import net.minecraftforge.registries.ForgeRegistries; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -@Mod.EventBusSubscriber(modid = KnockedBack.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class Config -{ - private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); - - private static final ForgeConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER - .comment("Whether to log the dirt block on common setup") - .define("logDirtBlock", true); - - private static final ForgeConfigSpec.IntValue MAGIC_NUMBER = BUILDER - .comment("A magic number") - .defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE); - - public static final ForgeConfigSpec.ConfigValue MAGIC_NUMBER_INTRODUCTION = BUILDER - .comment("What you want the introduction message to be for the magic number") - .define("magicNumberIntroduction", "The magic number is... "); - - // a list of strings that are treated as resource locations for items - private static final ForgeConfigSpec.ConfigValue> ITEM_STRINGS = BUILDER - .comment("A list of items to log on common setup.") - .defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), Config::validateItemName); - - static final ForgeConfigSpec SPEC = BUILDER.build(); - - public static boolean logDirtBlock; - public static int magicNumber; - public static String magicNumberIntroduction; - public static Set items; - - private static boolean validateItemName(final Object obj) - { - return obj instanceof final String itemName && ForgeRegistries.ITEMS.containsKey(new ResourceLocation(itemName)); - } - - @SubscribeEvent - static void onLoad(final ModConfigEvent event) - { - logDirtBlock = LOG_DIRT_BLOCK.get(); - magicNumber = MAGIC_NUMBER.get(); - magicNumberIntroduction = MAGIC_NUMBER_INTRODUCTION.get(); - items = ITEM_STRINGS.get().stream() - .map(itemName -> ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName))) - .collect(Collectors.toSet()); - } -} diff --git a/src/main/java/net/fretux/knockedback/KnockedBack.java b/src/main/java/net/fretux/knockedback/KnockedBack.java index 588962c..1f2225c 100644 --- a/src/main/java/net/fretux/knockedback/KnockedBack.java +++ b/src/main/java/net/fretux/knockedback/KnockedBack.java @@ -14,6 +14,7 @@ import net.minecraftforge.event.server.ServerStartingEvent; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.fretux.knockedback.config.Config; import org.slf4j.Logger; @Mod(KnockedBack.MOD_ID) @@ -22,7 +23,7 @@ public class KnockedBack { private static final Logger LOGGER = LogUtils.getLogger(); public KnockedBack() { - ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.SPEC); + ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.COMMON_SPEC); FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new KnockedEffect()); diff --git a/src/main/java/net/fretux/knockedback/KnockedManager.java b/src/main/java/net/fretux/knockedback/KnockedManager.java index 5d9f5c1..4b92500 100644 --- a/src/main/java/net/fretux/knockedback/KnockedManager.java +++ b/src/main/java/net/fretux/knockedback/KnockedManager.java @@ -10,6 +10,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; +import net.fretux.knockedback.config.Config; import java.util.*; @@ -17,14 +18,17 @@ import java.util.*; public class KnockedManager { private static final Map knockedEntities = new HashMap<>(); private static final Set grippedEntities = new HashSet<>(); - private static final int KNOCKED_DURATION = 400; + + private static int getKnockedDuration() { + return Config.COMMON.knockedDuration.get(); + } public static void applyKnockedState(LivingEntity entity) { if (!(entity instanceof Player)) { return; } if (!isKnocked(entity)) { - knockedEntities.put(entity.getUUID(), KNOCKED_DURATION); + knockedEntities.put(entity.getUUID(), getKnockedDuration()); entity.setHealth(1.0F); } } @@ -34,16 +38,15 @@ public class KnockedManager { if (!(event.player instanceof ServerPlayer sp)) return; if (KnockedManager.isKnocked(sp)) { boolean grounded = sp.onGround() || sp.isInWater(); - sp.setNoGravity(false); // Always allow gravity + sp.setNoGravity(false); if (!grounded) { - sp.setDeltaMovement(0, sp.getDeltaMovement().y() - 0.08, 0); // Gravity acceleration + sp.setDeltaMovement(0, sp.getDeltaMovement().y() - 0.08, 0); } } } - public static boolean isKnocked(LivingEntity entity) { return knockedEntities.containsKey(entity.getUUID()); } @@ -126,43 +129,45 @@ public class KnockedManager { } } + private static void killAndRemove(LivingEntity entity) { + removeKnockedState(entity); + entity.kill(); + } + @SubscribeEvent public static void onLivingHurt(LivingHurtEvent event) { LivingEntity entity = event.getEntity(); - if (!(entity instanceof Player player)) { - return; - } - if (player.getMainHandItem().getItem() == Items.TOTEM_OF_UNDYING - || player.getOffhandItem().getItem() == Items.TOTEM_OF_UNDYING) { - return; - } + if (!(entity instanceof Player player)) return; DamageSource src = event.getSource(); String damageType = src.getMsgId(); boolean isFatal = player.getHealth() - event.getAmount() <= 0; - if (!isKnocked(entity)) { - if (isFatal) { - if (src.getEntity() instanceof LivingEntity) { - event.setCanceled(true); - applyKnockedState(entity); - } + if (isFatal && Config.COMMON.explosionsBypassKnockdown.get() && + (damageType.contains("explosion") || damageType.contains("fireworks"))) { + killAndRemove(player); + return; + } + if (isFatal && Config.COMMON.fallDamageBypassesKnockdown.get() && damageType.contains("fall")) { + killAndRemove(player); + return; + } + if (isFatal && Config.COMMON.lavaBypassesKnockdown.get() && + (damageType.contains("lava") || damageType.contains("inFire") || + damageType.contains("fire") || damageType.contains("onFire") || + damageType.contains("fireball") || damageType.contains("hotFloor"))) { + killAndRemove(player); + return; + } + boolean hasTotem = player.getMainHandItem().is(Items.TOTEM_OF_UNDYING) + || player.getOffhandItem().is(Items.TOTEM_OF_UNDYING); + if (isFatal && !isKnocked(entity)) { + if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) { + event.setCanceled(true); + applyKnockedState(entity); } - return; } - knockedEntities.put(entity.getUUID(), KNOCKED_DURATION); - if (damageType.equals("fire") || damageType.equals("lava") || damageType.equals("onFire") || - damageType.equals("explosion") || damageType.equals("explosion.player") || damageType.equals("fireball")) { - entity.setHealth(0.0F); - removeKnockedState(entity); - PlayerExecutionHandler.cancelExecution(entity.getUUID()); - return; + if (isKnocked(entity)) { + knockedEntities.put(entity.getUUID(), getKnockedDuration()); + event.setCanceled(true); } - if ((damageType.equals("fall") || damageType.equals("explosion") || damageType.equals("explosion.player")) && - event.getAmount() >= entity.getHealth()) { - entity.setHealth(0.0F); - removeKnockedState(entity); - PlayerExecutionHandler.cancelExecution(entity.getUUID()); - return; - } - event.setCanceled(true); } } \ No newline at end of file diff --git a/src/main/java/net/fretux/knockedback/MobKillHandler.java b/src/main/java/net/fretux/knockedback/MobKillHandler.java index a80e39c..002ea84 100644 --- a/src/main/java/net/fretux/knockedback/MobKillHandler.java +++ b/src/main/java/net/fretux/knockedback/MobKillHandler.java @@ -1,6 +1,5 @@ package net.fretux.knockedback; -import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.player.Player; @@ -12,6 +11,7 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; +import net.fretux.knockedback.config.Config; import javax.annotation.Nullable; import java.util.*; @@ -21,7 +21,10 @@ import static net.fretux.knockedback.KnockedManager.setGripped; @Mod.EventBusSubscriber(modid = KnockedBack.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) public class MobKillHandler { - private static final int EXECUTION_DELAY_TICKS = 3 * 20; + public static int getExecutionTime() { + return Config.COMMON.executionTime.get(); + } + private static final Map killAttempts = new HashMap<>(); private static class KillAttempt { @@ -46,6 +49,7 @@ public class MobKillHandler { @SubscribeEvent public void onMobHurt(LivingHurtEvent event) { + if (!Config.COMMON.mobsCanExecute.get()) return; LivingEntity entity = event.getEntity(); if (!(entity instanceof Mob mob)) return; UUID mobUuid = mob.getUUID(); @@ -75,6 +79,10 @@ public class MobKillHandler { private void tickKillAttempts() { var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); + if (!net.fretux.knockedback.config.Config.COMMON.mobsCanExecute.get()) { + killAttempts.clear(); + return; + } Map updated = new HashMap<>(); for (UUID knockedId : KnockedManager.getKnockedUuids()) { Player knocked = getPlayerByUuid(knockedId); @@ -103,7 +111,7 @@ public class MobKillHandler { setGripped(knocked, true); KillAttempt attempt = killAttempts.get(knockedId); if (attempt == null || !attempt.mobUuid.equals(mob.getUUID())) { - attempt = new KillAttempt(mob.getUUID(), EXECUTION_DELAY_TICKS); + attempt = new KillAttempt(mob.getUUID(), getExecutionTime()); } else { attempt.timeLeft--; if (knocked instanceof ServerPlayer sp) { diff --git a/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java b/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java index 0db016e..1c835d8 100644 --- a/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java +++ b/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java @@ -1,5 +1,6 @@ package net.fretux.knockedback; +import net.fretux.knockedback.config.Config; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; @@ -20,7 +21,9 @@ import java.util.UUID; @Mod.EventBusSubscriber(modid = "knockedback", bus = Mod.EventBusSubscriber.Bus.FORGE) public class PlayerExecutionHandler { public static final double EXECUTION_RANGE = 2.0; - public static final int EXECUTION_DELAY_TICKS = 60; + public static int getExecutionTime() { + return Config.COMMON.executionTime.get(); + } public static boolean isBeingPlayerExecuted(UUID knockedId) { return executionAttempts.containsKey(knockedId); } @@ -52,12 +55,12 @@ public class PlayerExecutionHandler { public PlayerExecutionAttempt(UUID executorUuid) { this.executorUuid = executorUuid; - this.timeLeft = EXECUTION_DELAY_TICKS; + this.timeLeft = getExecutionTime(); } } public static void register() { - MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); + MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); } public static void startExecution(ServerPlayer executor, Player target) { diff --git a/src/main/java/net/fretux/knockedback/client/ExecutionProgressOverlay.java b/src/main/java/net/fretux/knockedback/client/ExecutionProgressOverlay.java index 4def5b9..47bb9c5 100644 --- a/src/main/java/net/fretux/knockedback/client/ExecutionProgressOverlay.java +++ b/src/main/java/net/fretux/knockedback/client/ExecutionProgressOverlay.java @@ -12,7 +12,6 @@ import net.minecraftforge.fml.common.Mod; public class ExecutionProgressOverlay { private static final int BAR_WIDTH = 100; private static final int BAR_HEIGHT = 8; - private static final int TOTAL_TICKS = net.fretux.knockedback.PlayerExecutionHandler.EXECUTION_DELAY_TICKS; @SubscribeEvent public static void onRender(RenderGuiOverlayEvent.Post event) { @@ -23,7 +22,8 @@ public class ExecutionProgressOverlay { int sh = mc.getWindow().getGuiScaledHeight(); int x = (sw - BAR_WIDTH) / 2; int y = (sh - BAR_HEIGHT) / 2; - float progress = 1.0f - (ClientExecutionState.getTimeLeft() / (float) TOTAL_TICKS); + int totalTicks = net.fretux.knockedback.PlayerExecutionHandler.getExecutionTime(); + float progress = 1.0f - (ClientExecutionState.getTimeLeft() / (float) totalTicks); int fillWidth = (int) (BAR_WIDTH * progress); gui.fill(x, y, x + BAR_WIDTH, y + BAR_HEIGHT, 0x80000000); gui.fill(x, y, x + fillWidth, y + BAR_HEIGHT, 0x80FFFFFF); diff --git a/src/main/java/net/fretux/knockedback/config/Config.java b/src/main/java/net/fretux/knockedback/config/Config.java new file mode 100644 index 0000000..45f82ee --- /dev/null +++ b/src/main/java/net/fretux/knockedback/config/Config.java @@ -0,0 +1,62 @@ +package net.fretux.knockedback.config; + +import net.minecraftforge.common.ForgeConfigSpec; + +public class Config { + public static final ForgeConfigSpec COMMON_SPEC; + public static final Common COMMON; + + static { + ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder(); + COMMON = new Common(builder); + COMMON_SPEC = builder.build(); + } + + public static class Common { + public final ForgeConfigSpec.IntValue knockedDuration; + public final ForgeConfigSpec.IntValue executionTime; + public final ForgeConfigSpec.BooleanValue totemPreventsKnockdown; + public final ForgeConfigSpec.BooleanValue explosionsBypassKnockdown; + public final ForgeConfigSpec.BooleanValue fallDamageBypassesKnockdown; + public final ForgeConfigSpec.BooleanValue lavaBypassesKnockdown; + public final ForgeConfigSpec.BooleanValue mobsCanExecute; + + public Common(ForgeConfigSpec.Builder builder) { + builder.push("general"); + + knockedDuration = builder + .comment("How long (in ticks) a player remains knocked before recovering. Default: 400 (20 seconds).") + .defineInRange("knockedDuration", 400, 100, 1200); + + executionTime = builder + .comment("How long (in ticks) it takes to execute a knocked player. Default: 60 (3 seconds).") + .defineInRange("executionTime", 60, 20, 200); + + builder.pop().push("damage_behavior"); + + totemPreventsKnockdown = builder + .comment("If true, Totems of Undying prevent entering the knocked state. Default: true.") + .define("totemPreventsKnockdown", true); + + explosionsBypassKnockdown = builder + .comment("If true, explosions immediately kill instead of knocking down. Default: true.") + .define("explosionsBypassKnockdown", true); + + fallDamageBypassesKnockdown = builder + .comment("If true, fatal fall damage kills instead of knocking down. Default: true.") + .define("fallDamageBypassesKnockdown", true); + + lavaBypassesKnockdown = builder + .comment("If true, lava or fire damage kills instead of knocking down. Default: true.") + .define("lavaBypassesKnockdown", true); + + builder.pop().push("mobs"); + + mobsCanExecute = builder + .comment("If true, hostile and aggressive neutral mobs can execute knocked players. Default: true.") + .define("mobsCanExecute", true); + + builder.pop(); + } + } +} \ No newline at end of file