diff --git a/src/main/java/net/fretux/knockedback/KnockedManager.java b/src/main/java/net/fretux/knockedback/KnockedManager.java index 4b92500..2412058 100644 --- a/src/main/java/net/fretux/knockedback/KnockedManager.java +++ b/src/main/java/net/fretux/knockedback/KnockedManager.java @@ -1,5 +1,6 @@ package net.fretux.knockedback; +import net.fretux.knockedback.config.Config; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.damagesource.DamageSource; 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.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; -import net.fretux.knockedback.config.Config; import java.util.*; @@ -18,8 +18,18 @@ import java.util.*; public class KnockedManager { private static final Map knockedEntities = new HashMap<>(); private static final Set grippedEntities = new HashSet<>(); + private static final Set 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(); } @@ -40,7 +50,7 @@ public class KnockedManager { boolean grounded = sp.onGround() || sp.isInWater(); sp.setNoGravity(false); if (!grounded) { - sp.setDeltaMovement(0, sp.getDeltaMovement().y() - 0.08, 0); + sp.setDeltaMovement(0, sp.getDeltaMovement().y() - 0.08, 0); } } @@ -130,44 +140,56 @@ public class KnockedManager { } private static void killAndRemove(LivingEntity entity) { - removeKnockedState(entity); - entity.kill(); + removeKnockedState(entity); + entity.setHealth(0.0F); + PlayerExecutionHandler.cancelExecution(entity.getUUID()); } - + @SubscribeEvent public static void onLivingHurt(LivingHurtEvent event) { LivingEntity entity = event.getEntity(); - if (!(entity instanceof Player player)) return; 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(); boolean isFatal = player.getHealth() - event.getAmount() <= 0; - 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; + if (isFatal) { + if (Config.COMMON.explosionsBypassKnockdown.get() && + (damageType.contains("explosion") || damageType.contains("fireworks"))) { + killAndRemove(player); + return; + } + if (Config.COMMON.fallDamageBypassesKnockdown.get() && damageType.contains("fall")) { + killAndRemove(player); + return; + } + if (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); + if (!isKnocked(player)) { + if (isFatal) { + if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) { + event.setCanceled(true); + applyKnockedState(player); + } } + return; } - if (isKnocked(entity)) { - knockedEntities.put(entity.getUUID(), getKnockedDuration()); - event.setCanceled(true); - } + knockedEntities.put(player.getUUID(), getKnockedDuration()); + 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 002ea84..18c3389 100644 --- a/src/main/java/net/fretux/knockedback/MobKillHandler.java +++ b/src/main/java/net/fretux/knockedback/MobKillHandler.java @@ -1,5 +1,6 @@ package net.fretux.knockedback; +import net.fretux.knockedback.config.Config; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Mob; 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.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; -import net.fretux.knockedback.config.Config; import javax.annotation.Nullable; import java.util.*; @@ -24,7 +24,6 @@ public class MobKillHandler { public static int getExecutionTime() { return Config.COMMON.executionTime.get(); } - private static final Map killAttempts = new HashMap<>(); private static class KillAttempt { @@ -49,7 +48,6 @@ 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(); @@ -79,10 +77,6 @@ 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); @@ -123,6 +117,9 @@ public class MobKillHandler { if (attempt.timeLeft <= 0) { executeKnockedPlayer(knocked, mob); continue; + } else { + mob.getNavigation().stop(); + mob.setTarget(null); } } updated.put(knockedId, attempt); @@ -133,8 +130,11 @@ public class MobKillHandler { private void executeKnockedPlayer(Player knocked, Mob mob) { removeKnockedState(knocked); - knocked.kill(); + mob.setTarget(null); mob.getNavigation().stop(); + KnockedManager.markKillInProgress(knocked); + knocked.kill(); + KnockedManager.unmarkKillInProgress(knocked); if (knocked instanceof ServerPlayer sp) { NetworkHandler.CHANNEL.send( PacketDistributor.PLAYER.with(() -> sp), @@ -143,6 +143,7 @@ public class MobKillHandler { } } + @Nullable private Mob getMobInRange(Player p) { if (!(p.level() instanceof ServerLevel world)) return null; diff --git a/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java b/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java index 1c835d8..836f074 100644 --- a/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java +++ b/src/main/java/net/fretux/knockedback/PlayerExecutionHandler.java @@ -14,16 +14,18 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.network.PacketDistributor; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; @Mod.EventBusSubscriber(modid = "knockedback", bus = Mod.EventBusSubscriber.Bus.FORGE) public class PlayerExecutionHandler { public static final double EXECUTION_RANGE = 2.0; + + private static final Set killingNow = new HashSet<>(); + public static int getExecutionTime() { return Config.COMMON.executionTime.get(); } + public static boolean isBeingPlayerExecuted(UUID knockedId) { return executionAttempts.containsKey(knockedId); } @@ -60,7 +62,7 @@ public class PlayerExecutionHandler { } public static void register() { - MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); + MinecraftForge.EVENT_BUS.register(new PlayerExecutionHandler()); } public static void startExecution(ServerPlayer executor, Player target) { @@ -121,7 +123,9 @@ public class PlayerExecutionHandler { UUID id = knockedPlayer.getUUID(); KnockedManager.removeKnockedState(knockedPlayer); cancelExecution(id); + KnockedManager.markKillInProgress(knockedPlayer); knockedPlayer.kill(); + KnockedManager.unmarkKillInProgress(knockedPlayer); NetworkHandler.CHANNEL.send( PacketDistributor.PLAYER.with(() -> executor), new ExecutionProgressPacket(0) diff --git a/src/main/java/net/fretux/knockedback/config/Config.java b/src/main/java/net/fretux/knockedback/config/Config.java index 45f82ee..bfb0aa8 100644 --- a/src/main/java/net/fretux/knockedback/config/Config.java +++ b/src/main/java/net/fretux/knockedback/config/Config.java @@ -19,7 +19,6 @@ public class Config { 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"); @@ -50,12 +49,6 @@ public class Config { .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(); } } diff --git a/src/main/resources/assets/knockedback/lang/de_de.json b/src/main/resources/assets/knockedback/lang/de_de.json index ba8870c..caee08b 100644 --- a/src/main/resources/assets/knockedback/lang/de_de.json +++ b/src/main/resources/assets/knockedback/lang/de_de.json @@ -16,8 +16,7 @@ "message.knockedback.been_dropped": "Du wurdest von %1$s abgesetzt", "message.knockedback.you_executed": "Du hast %1$s hingerichtet!", "message.knockedback.you_were_executed": "Du wurdest von %1$s hingerichtet!", - - - "overlay.knockedback.recovery_time": "Zeit bis Erholung: %s s" + "overlay.knockedback.recovery_time": "Zeit bis Erholung: %s s", + "death.attack.knockedback_execution": "%1$s wurde gnadenlos hingerichtet!" } diff --git a/src/main/resources/assets/knockedback/lang/en_us.json b/src/main/resources/assets/knockedback/lang/en_us.json index 2608a49..3cb7d35 100644 --- a/src/main/resources/assets/knockedback/lang/en_us.json +++ b/src/main/resources/assets/knockedback/lang/en_us.json @@ -14,5 +14,6 @@ "message.knockedback.execution_interrupted_executor": "Your execution was interrupted!", "message.knockedback.you_executed": "You executed %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." } \ No newline at end of file