Merge pull request #13 from Fretuks/add-master-toggle-for-mob-executions

Add mob execution toggle and stabilize knocked handling
This commit is contained in:
2026-01-16 23:35:09 +01:00
committed by GitHub
3 changed files with 46 additions and 15 deletions
@@ -54,6 +54,7 @@ public class KnockedManager {
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (!(event.player instanceof ServerPlayer sp)) return;
if (KnockedManager.isKnocked(sp)) {
applyKnockedEffects(sp);
boolean grounded = sp.onGround() || sp.isInWater();
sp.setNoGravity(false);
if (!grounded) {
@@ -168,14 +169,24 @@ public class KnockedManager {
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);
boolean isFatal = player.getHealth() - event.getAmount() <= 0;
if (isKnocked(player)) {
if (src.is(KnockedBackDamageTags.BYPASS_KNOCKDOWN)) {
if (isFatal) {
killAndRemove(player);
}
return;
}
knockedEntities.put(player.getUUID(), getKnockedDuration());
applyKnockedEffects(player);
event.setCanceled(true);
return;
}
if (MobKillHandler.isBeingMobExecuted(player.getUUID())
|| PlayerExecutionHandler.isBeingPlayerExecuted(player.getUUID())) {
event.setCanceled(true);
return;
}
boolean isFatal = player.getHealth() - event.getAmount() <= 0;
if (isFatal) {
if (src.is(KnockedBackDamageTags.BYPASS_KNOCKDOWN)) {
killAndRemove(player);
@@ -184,18 +195,12 @@ public class KnockedManager {
}
boolean hasTotem = player.getMainHandItem().is(Items.TOTEM_OF_UNDYING)
|| player.getOffhandItem().is(Items.TOTEM_OF_UNDYING);
if (!isKnocked(player)) {
if (isFatal) {
if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) {
event.setCanceled(true);
applyKnockedState(player);
}
if (isFatal) {
if (!hasTotem || !Config.COMMON.totemPreventsKnockdown.get()) {
event.setCanceled(true);
applyKnockedState(player);
}
return;
}
knockedEntities.put(player.getUUID(), getKnockedDuration());
applyKnockedEffects(player);
event.setCanceled(true);
}
@SubscribeEvent
@@ -79,6 +79,24 @@ public class MobKillHandler {
private void tickKillAttempts() {
var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
if (!Config.COMMON.mobExecutionEnabled.get()) {
if (!killAttempts.isEmpty()) {
for (UUID knockedId : new HashSet<>(killAttempts.keySet())) {
Player knocked = getPlayerByUuid(knockedId);
if (knocked instanceof ServerPlayer sp) {
NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> sp),
new ExecutionProgressPacket(0, null)
);
}
if (knocked != null) {
setGripped(knocked, false);
}
}
killAttempts.clear();
}
return;
}
Map<UUID, KillAttempt> updated = new HashMap<>();
for (UUID knockedId : KnockedManager.getKnockedUuids()) {
Player knocked = getPlayerByUuid(knockedId);
@@ -176,6 +194,9 @@ public class MobKillHandler {
}
private boolean isMobAllowedToExecute(Mob mob) {
if (!Config.COMMON.mobExecutionEnabled.get()) {
return false;
}
List<? extends String> allowlist = Config.COMMON.mobExecutionAllowlist.get();
if (allowlist.isEmpty()) {
return true;
@@ -17,6 +17,7 @@ public class Config {
public static class Common {
public final ForgeConfigSpec.IntValue knockedDuration;
public final ForgeConfigSpec.IntValue executionTime;
public final ForgeConfigSpec.BooleanValue mobExecutionEnabled;
public final ForgeConfigSpec.BooleanValue totemPreventsKnockdown;
public final ForgeConfigSpec.ConfigValue<List<? extends String>> mobExecutionAllowlist;
public final ForgeConfigSpec.ConfigValue<List<? extends String>> knockedPotionEffects;
@@ -32,6 +33,10 @@ public class Config {
.comment("How long (in ticks) it takes to execute a knocked player. Default: 60 (3 seconds).")
.defineInRange("executionTime", 60, 20, 200);
mobExecutionEnabled = builder
.comment("If true, mobs can execute knocked players. Default: true.")
.define("mobExecutionEnabled", true);
mobExecutionAllowlist = builder
.comment("List of entity ids allowed to execute knocked players.",
"If empty, any hostile/aggro mob can execute.",