From 1e18996dcfc086eb45c94d3e940130b9761ff62b Mon Sep 17 00:00:00 2001 From: BoroBongo Date: Mon, 15 Jun 2026 21:02:06 +0100 Subject: [PATCH] feat: move culled NPCs to their routine waypoint on schedule change NpcRoutineService.CalculateCurrentRoutine now calls NotifyNpcRoutineChanged when the active routine slot changes, moving the culling sphere (and unloaded GO) to the new waypoint so off-screen NPCs progress their daily schedule. RecalculateAllNpcRoutines() iterates every NPC container and can be called after a time skip to synchronise all culled NPCs at once. --- .../Domain/Culling/NpcMeshCullingDomain.cs | 6 ++++++ .../Services/Culling/NpcMeshCullingService.cs | 5 +++++ .../Scripts/Services/Npc/NpcRoutineService.cs | 20 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/Assets/Gothic-Core/Scripts/Domain/Culling/NpcMeshCullingDomain.cs b/Assets/Gothic-Core/Scripts/Domain/Culling/NpcMeshCullingDomain.cs index 6bc6a9c0e..88a5164b9 100644 --- a/Assets/Gothic-Core/Scripts/Domain/Culling/NpcMeshCullingDomain.cs +++ b/Assets/Gothic-Core/Scripts/Domain/Culling/NpcMeshCullingDomain.cs @@ -163,5 +163,11 @@ private void UpdatePosition(int sphereKey, Vector3 position) { _spheres[sphereKey].position = position; } + + public IEnumerable GetAllNpcContainers() + { + for (var i = 0; i < _count; i++) + yield return _loaders[i].Container; + } } } diff --git a/Assets/Gothic-Core/Scripts/Services/Culling/NpcMeshCullingService.cs b/Assets/Gothic-Core/Scripts/Services/Culling/NpcMeshCullingService.cs index 6f3f7fbc1..c448d7908 100644 --- a/Assets/Gothic-Core/Scripts/Services/Culling/NpcMeshCullingService.cs +++ b/Assets/Gothic-Core/Scripts/Services/Culling/NpcMeshCullingService.cs @@ -35,5 +35,10 @@ public List GetVisibleNpcs() { return _npcDomain.GetVisibleNpcs(); } + + public IEnumerable GetAllNpcContainers() + { + return _npcDomain.GetAllNpcContainers(); + } } } diff --git a/Assets/Gothic-Core/Scripts/Services/Npc/NpcRoutineService.cs b/Assets/Gothic-Core/Scripts/Services/Npc/NpcRoutineService.cs index 882f5d6c5..9dd6dcf98 100644 --- a/Assets/Gothic-Core/Scripts/Services/Npc/NpcRoutineService.cs +++ b/Assets/Gothic-Core/Scripts/Services/Npc/NpcRoutineService.cs @@ -2,6 +2,7 @@ using Gothic.Core.Extensions; using Gothic.Core.Logging; using Gothic.Core.Models.Npc; +using Gothic.Core.Services.Culling; using Gothic.Core.Services.World; using MyBox; using Reflex.Attributes; @@ -15,6 +16,7 @@ public class NpcRoutineService { [Inject] private readonly GameStateService _gameStateService; [Inject] private readonly GameTimeService _gameTimeService; + [Inject] private readonly NpcMeshCullingService _npcMeshCullingService; private DaedalusVm _vm => _gameStateService.GothicVm; @@ -109,7 +111,25 @@ private bool CalculateCurrentRoutine(NpcInstance npc) } npcProps.RoutineCurrent = newRoutine; + if (changed) + _npcMeshCullingService.NotifyNpcRoutineChanged(npc.GetUserData()); + return changed; } + + /// + /// Re-evaluates the time-based routine for all NPCs. Culled NPCs whose routine changed + /// will have their culling sphere moved to the new waypoint via NotifyNpcRoutineChanged. + /// Call this after a time skip so off-screen NPCs appear at their correct schedule position. + /// + public void RecalculateAllNpcRoutines() + { + foreach (var container in _npcMeshCullingService.GetAllNpcContainers()) + { + if (container?.Props?.Routines == null || container.Props.Routines.Count == 0) + continue; + CalculateCurrentRoutine(container.Instance); + } + } } }