From a74a8e3a4c49f59de0de2b63d3f74d8a5d228381 Mon Sep 17 00:00:00 2001 From: einfachButzi Date: Thu, 12 Nov 2026 01:24:27 +0100 Subject: [PATCH] Fix replay arrow movement and visibility Record arrow positions and velocity every tick so replay hull visibility follows arrows leaving schematics. Record despawns and clear tracked arrows when the fight ends. Fixes #524 --- .../fightsystem/listener/Recording.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java index ecd333ec..1252665a 100644 --- a/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java +++ b/FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/listener/Recording.java @@ -58,7 +58,9 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.*; import org.bukkit.inventory.ItemStack; +import java.util.HashSet; import java.util.Random; +import java.util.Set; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; @@ -69,6 +71,7 @@ public class Recording implements Listener { private static final int AIR = 0; private static final Random random = new Random(); + private final Set arrows = new HashSet<>(); public static ItemStack disarmNull(ItemStack stack) { if (stack == null) return new ItemStack(Material.AIR); @@ -109,6 +112,8 @@ public class Recording implements Listener { public void disable() { Fight.teams().forEach(Recording.this::despawnTeam); despawnTNT(); + arrows.forEach(GlobalRecorder.getInstance()::entityDespawns); + arrows.clear(); } }.register(); new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) { @@ -133,6 +138,15 @@ public class Recording implements Listener { if (FightState.getFightState() == FightState.SPECTATE || !GlobalRecorder.getInstance().recording()) return; iterateOverEntities(primedTnt::isInstance, this::trackEntity); + // Arrow movement also updates replay visibility when crossing a schematic's hull. + arrows.removeIf(arrow -> { + if (!arrow.isValid()) { + GlobalRecorder.getInstance().entityDespawns(arrow); + return true; + } + trackEntity(arrow); + return false; + }); }, 1, 1); } @@ -255,6 +269,9 @@ public class Recording implements Listener { GlobalRecorder.getInstance().fireballSpawn(e.getEntity()); } else if (e.getEntityType() == EntityType.ARROW) { GlobalRecorder.getInstance().arrowSpawn(e.getEntity()); + if (GlobalRecorder.getInstance().recording()) { + arrows.add(e.getEntity()); + } } }