Small qol features

This commit is contained in:
IM23a-spirgif
2025-04-20 20:37:43 +02:00
parent 67d35e8ecf
commit 53eb3f3895
3 changed files with 78 additions and 20 deletions
@@ -36,8 +36,15 @@ public class KnockedManager {
knockedEntities.remove(entity.getUUID()); knockedEntities.remove(entity.getUUID());
grippedEntities.remove(entity.getUUID()); grippedEntities.remove(entity.getUUID());
MobKillHandler.clearKillAttempt(entity.getUUID()); MobKillHandler.clearKillAttempt(entity.getUUID());
if (entity instanceof ServerPlayer sp) {
NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> sp),
new KnockedTimePacket(0)
);
}
} }
public static void setGripped(LivingEntity entity, boolean isGripped) { public static void setGripped(LivingEntity entity, boolean isGripped) {
if (isGripped) { if (isGripped) {
grippedEntities.add(entity.getUUID()); grippedEntities.add(entity.getUUID());
@@ -51,28 +58,51 @@ public class KnockedManager {
} }
public static void tickKnockedStates() { public static void tickKnockedStates() {
var server = net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer();
Iterator<Map.Entry<UUID, Integer>> it = knockedEntities.entrySet().iterator(); Iterator<Map.Entry<UUID, Integer>> it = knockedEntities.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<UUID, Integer> entry = it.next(); Map.Entry<UUID, Integer> entry = it.next();
UUID entityId = entry.getKey(); UUID playerId = entry.getKey();
int timeLeft = entry.getValue(); int timeLeft = entry.getValue();
if (grippedEntities.contains(entityId)) {
entry.setValue(0); // ① If a mob *or* a player is in the middle of executing them, pause:
timeLeft = 0; if (MobKillHandler.isBeingMobExecuted(playerId)
} else { || PlayerExecutionHandler.isBeingPlayerExecuted(playerId)) {
timeLeft--;
if (timeLeft <= 0) { // just re‑send the *current* timeLeft, do NOT decrement
it.remove(); ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
continue; if (p != null) {
} else { NetworkHandler.CHANNEL.send(
entry.setValue(timeLeft); PacketDistributor.PLAYER.with(() -> p),
new KnockedTimePacket(timeLeft)
);
} }
continue;
} }
ServerPlayer knockedPlayer = NetworkHandlerHelper.getPlayerByUuid(
net.minecraftforge.server.ServerLifecycleHooks.getCurrentServer(), entityId); // ② Otherwise count down as normal:
if (knockedPlayer != null) { timeLeft--;
NetworkHandler.CHANNEL.send(PacketDistributor.PLAYER.with(() -> knockedPlayer), if (timeLeft <= 0) {
new KnockedTimePacket(timeLeft)); // send final zero
ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
if (p != null) {
NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> p),
new KnockedTimePacket(0)
);
}
it.remove();
} else {
// update and send
entry.setValue(timeLeft);
ServerPlayer p = NetworkHandlerHelper.getPlayerByUuid(server, playerId);
if (p != null) {
NetworkHandler.CHANNEL.send(
PacketDistributor.PLAYER.with(() -> p),
new KnockedTimePacket(timeLeft)
);
}
} }
} }
} }
@@ -82,9 +112,7 @@ public class KnockedManager {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
DamageSource source = event.getSource(); DamageSource source = event.getSource();
String damageType = source.getMsgId(); String damageType = source.getMsgId();
boolean isFatal = entity.getHealth() - event.getAmount() <= 0; boolean isFatal = entity.getHealth() - event.getAmount() <= 0;
if (!isKnocked(entity)) { if (!isKnocked(entity)) {
if (entity instanceof Player player && isFatal) { if (entity instanceof Player player && isFatal) {
if (!(damageType.equals("fall") || damageType.equals("explosion") || damageType.equals("explosion.player") || if (!(damageType.equals("fall") || damageType.equals("explosion") || damageType.equals("explosion.player") ||
@@ -103,14 +131,12 @@ public class KnockedManager {
removeKnockedState(entity); removeKnockedState(entity);
return; return;
} }
if ((damageType.equals("fall") || damageType.equals("explosion") || damageType.equals("explosion.player")) && if ((damageType.equals("fall") || damageType.equals("explosion") || damageType.equals("explosion.player")) &&
event.getAmount() >= entity.getHealth()) { event.getAmount() >= entity.getHealth()) {
entity.setHealth(0.0F); entity.setHealth(0.0F);
removeKnockedState(entity); removeKnockedState(entity);
return; return;
} }
event.setCanceled(true); event.setCanceled(true);
} }
} }
@@ -24,6 +24,10 @@ import static net.fretux.knockedback.KnockedManager.setGripped;
*/ */
public class MobKillHandler { public class MobKillHandler {
private static final int EXECUTION_DELAY_TICKS = 3 * 20; private static final int EXECUTION_DELAY_TICKS = 3 * 20;
public static boolean isBeingMobExecuted(UUID knockedId) {
return killAttempts.containsKey(knockedId);
}
/** /**
* A record of ongoing kill attempts. * A record of ongoing kill attempts.
* Key = Knocked player's UUID * Key = Knocked player's UUID
@@ -8,6 +8,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
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.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
@@ -22,6 +23,33 @@ public class PlayerExecutionHandler {
public static final double EXECUTION_RANGE = 2.0; public static final double EXECUTION_RANGE = 2.0;
private static final int EXECUTION_DELAY_TICKS = 60; private static final int EXECUTION_DELAY_TICKS = 60;
public static boolean isBeingPlayerExecuted(UUID knockedId) {
return executionAttempts.containsKey(knockedId);
}
public static boolean isExecuting(UUID playerUuid) {
return executionAttempts.values()
.stream()
.anyMatch(attempt -> attempt.executorUuid.equals(playerUuid));
}
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
if (event.side.isServer()
&& event.phase == TickEvent.Phase.END
&& event.player instanceof ServerPlayer sp
&& isExecuting(sp.getUUID())) {
sp.setDeltaMovement(0, 0, 0);
sp.setSprinting(false);
}
}
@SubscribeEvent
public static void onAttackEntity(AttackEntityEvent event) {
if (event.getEntity() instanceof ServerPlayer sp
&& isExecuting(sp.getUUID())) {
event.setCanceled(true);
}
}
private static final Map<UUID, PlayerExecutionAttempt> executionAttempts = new HashMap<>(); private static final Map<UUID, PlayerExecutionAttempt> executionAttempts = new HashMap<>();
private static class PlayerExecutionAttempt { private static class PlayerExecutionAttempt {