Small fix to Death logic

This commit is contained in:
2025-10-21 09:28:35 +02:00
parent c522379536
commit 1b734209ad
6 changed files with 73 additions and 53 deletions
@@ -1,5 +1,6 @@
package net.fretux.knockedback; package net.fretux.knockedback;
import net.fretux.knockedback.config.Config;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@@ -10,7 +11,6 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.fretux.knockedback.config.Config;
import java.util.*; import java.util.*;
@@ -18,8 +18,18 @@ import java.util.*;
public class KnockedManager { public class KnockedManager {
private static final Map<UUID, Integer> knockedEntities = new HashMap<>(); private static final Map<UUID, Integer> knockedEntities = new HashMap<>();
private static final Set<UUID> grippedEntities = new HashSet<>(); private static final Set<UUID> grippedEntities = new HashSet<>();
private static final Set<UUID> killingNow = new HashSet<>();
private static int getKnockedDuration() { public static void markKillInProgress(LivingEntity e) {
killingNow.add(e.getUUID());
}
public static void unmarkKillInProgress(LivingEntity e) {
killingNow.remove(e.getUUID());
}
public static int getKnockedDuration() {
return Config.COMMON.knockedDuration.get(); return Config.COMMON.knockedDuration.get();
} }
@@ -131,43 +141,55 @@ public class KnockedManager {
private static void killAndRemove(LivingEntity entity) { private static void killAndRemove(LivingEntity entity) {
removeKnockedState(entity); removeKnockedState(entity);
entity.kill(); entity.setHealth(0.0F);
PlayerExecutionHandler.cancelExecution(entity.getUUID());
} }
@SubscribeEvent @SubscribeEvent
public static void onLivingHurt(LivingHurtEvent event) { public static void onLivingHurt(LivingHurtEvent event) {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (!(entity instanceof Player player)) return;
DamageSource src = event.getSource(); DamageSource src = event.getSource();
if (!(entity instanceof Player player)) return;
if (killingNow.contains(player.getUUID())) return;
if (MobKillHandler.isBeingMobExecuted(player.getUUID())
|| PlayerExecutionHandler.isBeingPlayerExecuted(player.getUUID())) {
if (event.getSource().getEntity() instanceof LivingEntity) {
event.setCanceled(true);
}
return;
}
String damageType = src.getMsgId(); String damageType = src.getMsgId();
boolean isFatal = player.getHealth() - event.getAmount() <= 0; boolean isFatal = player.getHealth() - event.getAmount() <= 0;
if (isFatal && Config.COMMON.explosionsBypassKnockdown.get() && if (isFatal) {
(damageType.contains("explosion") || damageType.contains("fireworks"))) { if (Config.COMMON.explosionsBypassKnockdown.get() &&
killAndRemove(player); (damageType.contains("explosion") || damageType.contains("fireworks"))) {
return; killAndRemove(player);
} return;
if (isFatal && Config.COMMON.fallDamageBypassesKnockdown.get() && damageType.contains("fall")) { }
killAndRemove(player); if (Config.COMMON.fallDamageBypassesKnockdown.get() && damageType.contains("fall")) {
return; killAndRemove(player);
} return;
if (isFatal && Config.COMMON.lavaBypassesKnockdown.get() && }
(damageType.contains("lava") || damageType.contains("inFire") || if (Config.COMMON.lavaBypassesKnockdown.get() &&
damageType.contains("fire") || damageType.contains("onFire") || (damageType.contains("lava") || damageType.contains("inFire") ||
damageType.contains("fireball") || damageType.contains("hotFloor"))) { damageType.contains("fire") || damageType.contains("onFire") ||
killAndRemove(player); damageType.contains("fireball") || damageType.contains("hotFloor"))) {
return; killAndRemove(player);
return;
}
} }
boolean hasTotem = player.getMainHandItem().is(Items.TOTEM_OF_UNDYING) boolean hasTotem = player.getMainHandItem().is(Items.TOTEM_OF_UNDYING)
|| player.getOffhandItem().is(Items.TOTEM_OF_UNDYING); || player.getOffhandItem().is(Items.TOTEM_OF_UNDYING);
if (isFatal && !isKnocked(entity)) { if (!isKnocked(player)) {
if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) { if (isFatal) {
event.setCanceled(true); if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) {
applyKnockedState(entity); event.setCanceled(true);
applyKnockedState(player);
}
} }
return;
} }
if (isKnocked(entity)) { knockedEntities.put(player.getUUID(), getKnockedDuration());
knockedEntities.put(entity.getUUID(), getKnockedDuration()); event.setCanceled(true);
event.setCanceled(true);
}
} }
} }
@@ -1,5 +1,6 @@
package net.fretux.knockedback; package net.fretux.knockedback;
import net.fretux.knockedback.config.Config;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@@ -11,7 +12,6 @@ import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.fretux.knockedback.config.Config;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.*;
@@ -24,7 +24,6 @@ public class MobKillHandler {
public static int getExecutionTime() { public static int getExecutionTime() {
return Config.COMMON.executionTime.get(); return Config.COMMON.executionTime.get();
} }
private static final Map<UUID, KillAttempt> killAttempts = new HashMap<>(); private static final Map<UUID, KillAttempt> killAttempts = new HashMap<>();
private static class KillAttempt { private static class KillAttempt {
@@ -49,7 +48,6 @@ public class MobKillHandler {
@SubscribeEvent @SubscribeEvent
public void onMobHurt(LivingHurtEvent event) { public void onMobHurt(LivingHurtEvent event) {
if (!Config.COMMON.mobsCanExecute.get()) return;
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (!(entity instanceof Mob mob)) return; if (!(entity instanceof Mob mob)) return;
UUID mobUuid = mob.getUUID(); UUID mobUuid = mob.getUUID();
@@ -79,10 +77,6 @@ public class MobKillHandler {
private void tickKillAttempts() { private void tickKillAttempts() {
var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(); var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
if (!net.fretux.knockedback.config.Config.COMMON.mobsCanExecute.get()) {
killAttempts.clear();
return;
}
Map<UUID, KillAttempt> updated = new HashMap<>(); Map<UUID, KillAttempt> updated = new HashMap<>();
for (UUID knockedId : KnockedManager.getKnockedUuids()) { for (UUID knockedId : KnockedManager.getKnockedUuids()) {
Player knocked = getPlayerByUuid(knockedId); Player knocked = getPlayerByUuid(knockedId);
@@ -123,6 +117,9 @@ public class MobKillHandler {
if (attempt.timeLeft <= 0) { if (attempt.timeLeft <= 0) {
executeKnockedPlayer(knocked, mob); executeKnockedPlayer(knocked, mob);
continue; continue;
} else {
mob.getNavigation().stop();
mob.setTarget(null);
} }
} }
updated.put(knockedId, attempt); updated.put(knockedId, attempt);
@@ -133,8 +130,11 @@ public class MobKillHandler {
private void executeKnockedPlayer(Player knocked, Mob mob) { private void executeKnockedPlayer(Player knocked, Mob mob) {
removeKnockedState(knocked); removeKnockedState(knocked);
knocked.kill(); mob.setTarget(null);
mob.getNavigation().stop(); mob.getNavigation().stop();
KnockedManager.markKillInProgress(knocked);
knocked.kill();
KnockedManager.unmarkKillInProgress(knocked);
if (knocked instanceof ServerPlayer sp) { if (knocked instanceof ServerPlayer sp) {
NetworkHandler.CHANNEL.send( NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> sp), PacketDistributor.PLAYER.with(() -> sp),
@@ -143,6 +143,7 @@ public class MobKillHandler {
} }
} }
@Nullable @Nullable
private Mob getMobInRange(Player p) { private Mob getMobInRange(Player p) {
if (!(p.level() instanceof ServerLevel world)) return null; if (!(p.level() instanceof ServerLevel world)) return null;
@@ -14,16 +14,18 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.UUID;
@Mod.EventBusSubscriber(modid = "knockedback", bus = Mod.EventBusSubscriber.Bus.FORGE) @Mod.EventBusSubscriber(modid = "knockedback", bus = Mod.EventBusSubscriber.Bus.FORGE)
public class PlayerExecutionHandler { public class PlayerExecutionHandler {
public static final double EXECUTION_RANGE = 2.0; public static final double EXECUTION_RANGE = 2.0;
private static final Set<UUID> killingNow = new HashSet<>();
public static int getExecutionTime() { public static int getExecutionTime() {
return Config.COMMON.executionTime.get(); return Config.COMMON.executionTime.get();
} }
public static boolean isBeingPlayerExecuted(UUID knockedId) { public static boolean isBeingPlayerExecuted(UUID knockedId) {
return executionAttempts.containsKey(knockedId); return executionAttempts.containsKey(knockedId);
} }
@@ -60,7 +62,7 @@ public class PlayerExecutionHandler {
} }
public static void register() { public static void register() {
MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler());
} }
public static void startExecution(ServerPlayer executor, Player target) { public static void startExecution(ServerPlayer executor, Player target) {
@@ -121,7 +123,9 @@ public class PlayerExecutionHandler {
UUID id = knockedPlayer.getUUID(); UUID id = knockedPlayer.getUUID();
KnockedManager.removeKnockedState(knockedPlayer); KnockedManager.removeKnockedState(knockedPlayer);
cancelExecution(id); cancelExecution(id);
KnockedManager.markKillInProgress(knockedPlayer);
knockedPlayer.kill(); knockedPlayer.kill();
KnockedManager.unmarkKillInProgress(knockedPlayer);
NetworkHandler.CHANNEL.send( NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> executor), PacketDistributor.PLAYER.with(() -> executor),
new ExecutionProgressPacket(0) new ExecutionProgressPacket(0)
@@ -19,7 +19,6 @@ public class Config {
public final ForgeConfigSpec.BooleanValue explosionsBypassKnockdown; public final ForgeConfigSpec.BooleanValue explosionsBypassKnockdown;
public final ForgeConfigSpec.BooleanValue fallDamageBypassesKnockdown; public final ForgeConfigSpec.BooleanValue fallDamageBypassesKnockdown;
public final ForgeConfigSpec.BooleanValue lavaBypassesKnockdown; public final ForgeConfigSpec.BooleanValue lavaBypassesKnockdown;
public final ForgeConfigSpec.BooleanValue mobsCanExecute;
public Common(ForgeConfigSpec.Builder builder) { public Common(ForgeConfigSpec.Builder builder) {
builder.push("general"); builder.push("general");
@@ -50,12 +49,6 @@ public class Config {
.comment("If true, lava or fire damage kills instead of knocking down. Default: true.") .comment("If true, lava or fire damage kills instead of knocking down. Default: true.")
.define("lavaBypassesKnockdown", 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(); builder.pop();
} }
} }
@@ -16,8 +16,7 @@
"message.knockedback.been_dropped": "Du wurdest von %1$s abgesetzt", "message.knockedback.been_dropped": "Du wurdest von %1$s abgesetzt",
"message.knockedback.you_executed": "Du hast %1$s hingerichtet!", "message.knockedback.you_executed": "Du hast %1$s hingerichtet!",
"message.knockedback.you_were_executed": "Du wurdest von %1$s hingerichtet!", "message.knockedback.you_were_executed": "Du wurdest von %1$s hingerichtet!",
"overlay.knockedback.recovery_time": "Zeit bis Erholung: %s s",
"death.attack.knockedback_execution": "%1$s wurde gnadenlos hingerichtet!"
"overlay.knockedback.recovery_time": "Zeit bis Erholung: %s s"
} }
@@ -14,5 +14,6 @@
"message.knockedback.execution_interrupted_executor": "Your execution was interrupted!", "message.knockedback.execution_interrupted_executor": "Your execution was interrupted!",
"message.knockedback.you_executed": "You executed %s!", "message.knockedback.you_executed": "You executed %s!",
"message.knockedback.you_were_executed": "You were executed by %s!", "message.knockedback.you_were_executed": "You were executed by %s!",
"overlay.knockedback.recovery_time": "Time until recovery: %s s" "overlay.knockedback.recovery_time": "Time until recovery: %s s",
"death.attack.knockedback_execution": "%1$s was executed mercilessly."
} }