From d7408f2a5a7644731c68effe54efcdedf1b59c07 Mon Sep 17 00:00:00 2001 From: Gegy Date: Fri, 22 Nov 2024 12:34:44 +0100 Subject: [PATCH] Fix: track with player sensor correctly, don't freeze if player goes offscreen --- .../client/ClientPlayerSensorEffects.java | 18 +++++++- .../sensor/ServerPlayerSensorManager.java | 46 ++++++------------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/lovetropics/extras/client/ClientPlayerSensorEffects.java b/src/main/java/com/lovetropics/extras/client/ClientPlayerSensorEffects.java index 08d9d03..6678731 100644 --- a/src/main/java/com/lovetropics/extras/client/ClientPlayerSensorEffects.java +++ b/src/main/java/com/lovetropics/extras/client/ClientPlayerSensorEffects.java @@ -29,6 +29,7 @@ import net.neoforged.neoforge.event.entity.EntityLeaveLevelEvent; import org.joml.Vector3f; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -158,18 +159,26 @@ public static void captureModelPose(T entity, EntityMod return; } if (model instanceof HumanoidModel humanoidModel) { - CAPTURED_SCREEN_POS.add(capturePlayerPose(entity, poseStack, humanoidModel)); + CapturedScreenBoxes capture = capturePlayerPose(entity, poseStack, humanoidModel); + if (capture != null) { + CAPTURED_SCREEN_POS.add(capture); + } } } + @Nullable private static CapturedScreenBoxes capturePlayerPose(LivingEntity entity, PoseStack poseStack, HumanoidModel humanoidModel) { poseStack.pushPose(); humanoidModel.head.translateAndRotate(poseStack); ScreenBox faceBox = toScreenBox(poseStack, -4.0f, -8.0f, -4.0f, 4.0f, 0.0f, 4.0f); poseStack.popPose(); - return new CapturedScreenBoxes(entity.getUUID(), faceBox); + if (faceBox != null) { + return new CapturedScreenBoxes(entity.getUUID(), faceBox); + } + return null; } + @Nullable private static ScreenBox toScreenBox(PoseStack poseStack, float x0, float y0, float z0, float x1, float y1, float z1) { Vector3f[] vertices = { toScreenPos(poseStack, x0, y0, z0), @@ -186,6 +195,11 @@ private static ScreenBox toScreenBox(PoseStack poseStack, float x0, float y0, fl float maxX = -Float.MAX_VALUE; float maxY = -Float.MAX_VALUE; for (Vector3f vertex : vertices) { + if (vertex.z >= 1.0f || vertex.z <= 0.1f) { + return null; + } else if (vertex.x <= -2.0f || vertex.x >= 2.0f || vertex.y <= -2.0f || vertex.y >= 2.0f) { + return null; + } minX = Math.min(minX, vertex.x); minY = Math.min(minY, vertex.y); maxX = Math.max(maxX, vertex.x); diff --git a/src/main/java/com/lovetropics/extras/item/sensor/ServerPlayerSensorManager.java b/src/main/java/com/lovetropics/extras/item/sensor/ServerPlayerSensorManager.java index bdfb28e..999fbaa 100644 --- a/src/main/java/com/lovetropics/extras/item/sensor/ServerPlayerSensorManager.java +++ b/src/main/java/com/lovetropics/extras/item/sensor/ServerPlayerSensorManager.java @@ -12,6 +12,7 @@ import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.tick.PlayerTickEvent; +import javax.annotation.Nullable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -33,19 +34,14 @@ public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { @SubscribeEvent public static void onPlayerTick(PlayerTickEvent.Post event) { if (event.getEntity() instanceof ServerPlayer player) { + if (player.tickCount % REFRESH_INTERVAL_TICKS != 0) { + return; + } ItemStack headItem = player.getItemBySlot(EquipmentSlot.HEAD); PlayerSensor sensor = headItem.get(ExtraDataComponents.PLAYER_SENSOR); - if (sensor != null) { - SensorState sensorState = SENSOR_STATES.computeIfAbsent(player.getUUID(), playerId -> new SensorState(sensor)); - sensorState.activeSensor = sensor; - if (player.tickCount % REFRESH_INTERVAL_TICKS == 0) { - sensorState.refresh(player); - } - } else { - SensorState sensorState = SENSOR_STATES.remove(player.getUUID()); - if (sensorState != null) { - sensorState.clearAllMarked(player); - } + SensorState sensorState = SENSOR_STATES.get(player.getUUID()); + if (sensorState != null) { + sensorState.refresh(player, sensor); } } } @@ -53,10 +49,8 @@ public static void onPlayerTick(PlayerTickEvent.Post event) { @SubscribeEvent public static void onPlayerTracked(PlayerEvent.StartTracking event) { if (event.getEntity() instanceof ServerPlayer player && event.getTarget() instanceof ServerPlayer target) { - SensorState state = SENSOR_STATES.get(player.getUUID()); - if (state != null) { - state.startTracking(player, target); - } + SensorState state = SENSOR_STATES.computeIfAbsent(player.getUUID(), playerId -> new SensorState()); + state.startTracking(player, target); } } @@ -71,15 +65,14 @@ public static void onPlayerUntracked(PlayerEvent.StopTracking event) { } private static class SensorState { + @Nullable private PlayerSensor activeSensor; private final Set trackedPlayers = new HashSet<>(); private final Set markedPlayers = new HashSet<>(); - private SensorState(PlayerSensor activeSensor) { - this.activeSensor = activeSensor; - } + public void refresh(ServerPlayer player, @Nullable PlayerSensor sensor) { + activeSensor = sensor; - public void refresh(ServerPlayer player) { ServerLevel level = player.serverLevel(); markedPlayers.removeIf(playerId -> { @@ -87,7 +80,7 @@ public void refresh(ServerPlayer player) { // Shouldn't get here - but the client probably forgot about the player if we did too return true; } - if (!activeSensor.matches(target)) { + if (activeSensor == null || !activeSensor.matches(target)) { player.connection.send(new ClientboundSetEntityMarkedPacket(target.getId(), Optional.empty())); return true; } @@ -98,7 +91,7 @@ public void refresh(ServerPlayer player) { if (markedPlayers.contains(playerId)) { continue; } - if (level.getPlayerByUUID(playerId) instanceof ServerPlayer target && activeSensor.matches(target)) { + if (level.getPlayerByUUID(playerId) instanceof ServerPlayer target && activeSensor != null && activeSensor.matches(target)) { markedPlayers.add(playerId); player.connection.send(new ClientboundSetEntityMarkedPacket(target.getId(), Optional.of(activeSensor.appearance()))); } @@ -107,7 +100,7 @@ public void refresh(ServerPlayer player) { public void startTracking(ServerPlayer player, ServerPlayer target) { trackedPlayers.add(target.getUUID()); - refresh(player); + refresh(player, activeSensor); } public void stopTracking(ServerPlayer target) { @@ -115,14 +108,5 @@ public void stopTracking(ServerPlayer target) { trackedPlayers.remove(target.getUUID()); markedPlayers.remove(target.getUUID()); } - - public void clearAllMarked(ServerPlayer player) { - for (UUID playerId : markedPlayers) { - if (player.level().getPlayerByUUID(playerId) instanceof ServerPlayer target) { - player.connection.send(new ClientboundSetEntityMarkedPacket(target.getId(), Optional.empty())); - } - } - markedPlayers.clear(); - } } }