From b1e203a9fd3b7e3d7aa42386f35887c1276c9fef Mon Sep 17 00:00:00 2001 From: Extremelyd1 <10898310+Extremelyd1@users.noreply.github.com> Date: Sat, 29 Jun 2024 21:00:57 +0200 Subject: [PATCH] Fix duplicate enemies, rigidbody sync issues --- HKMP/Game/Client/Entity/Entity.cs | 24 +++++++++++++++++++++- HKMP/Game/Client/Entity/EntityManager.cs | 7 +++++-- HKMP/Game/Client/Entity/EntityProcessor.cs | 6 +++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/HKMP/Game/Client/Entity/Entity.cs b/HKMP/Game/Client/Entity/Entity.cs index 07a9280..8a031b7 100644 --- a/HKMP/Game/Client/Entity/Entity.cs +++ b/HKMP/Game/Client/Entity/Entity.cs @@ -804,13 +804,18 @@ public void MakeHost() { component.IsControlled = false; } + Logger.Debug(" Client object null, enabling host object and returning"); return; } if (_hasParent) { + Logger.Debug(" Entity has parent, only setting local transform"); + Object.Host.transform.localPosition = _lastPosition = Object.Client.transform.localPosition; Object.Host.transform.localScale = _lastScale = Object.Client.transform.localScale; } else { + Logger.Debug(" Entity has no parent, calculating transform"); + var clientPos = Object.Client.transform.localPosition; var parentPos = Vector3.zero; if (Object.Host.transform.parent != null) { @@ -851,6 +856,17 @@ public void MakeHost() { Object.Client.SetActive(false); Object.Host.SetActive(clientActive); + Logger.Debug($" Set Active of host object to: {clientActive}, disabling client object"); + + // We need to set the isKinematic property of rigid bodies to ensure physics work again after enabling + // the host object. In Hornet 1 this is necessary because another state sets this property normally in the + // fight. See the "Wake" or "Refight Ready" state of the "Control" FSM on Hornet 1 + var rigidBody = Object.Host.GetComponent(); + if (rigidBody != null) { + Logger.Debug(" Resetting isKinematic of Rigidbody to ensure physics work for host object"); + rigidBody.isKinematic = false; + } + _lastIsActive = _hasParent ? Object.Host.activeSelf : Object.Host.activeInHierarchy; _isControlled = false; @@ -865,15 +881,19 @@ public void MakeHost() { var clientAnimation = currentClip.name; var wrapMode = currentClip.wrapMode; - Logger.Debug($"MakeHost ({Id}, {Type}) animation: {clientAnimation}, {wrapMode}"); + Logger.Debug($" Animator and current clip present, updating animation: {clientAnimation}, {wrapMode}"); LateUpdateAnimation(_animator.Host, clientAnimation, wrapMode); } } + Logger.Debug(" Restoring FSMs from snapshots"); + for (var fsmIndex = 0; fsmIndex < _fsms.Host.Count; fsmIndex++) { var fsm = _fsms.Host[fsmIndex]; + Logger.Debug($" Restoring FSM: {fsm.Fsm.Name}"); + // Force initialize the host FSM, since it might have been disabled before initializing EntityInitializer.InitializeFsm(fsm); @@ -912,6 +932,8 @@ public void MakeHost() { var oldActions = state.Actions; var newActions = oldActions.Where(ActionRegistry.IsActionContinuous).ToArray(); + Logger.Debug($" Only using actions: {string.Join(", ", newActions.Select(a => a.GetType().ToString()))}"); + // Replace the actions, set the state and reset the actions again state.Actions = newActions; fsm.SetState(snapshot.CurrentState); diff --git a/HKMP/Game/Client/Entity/EntityManager.cs b/HKMP/Game/Client/Entity/EntityManager.cs index e0940f9..a874b48 100644 --- a/HKMP/Game/Client/Entity/EntityManager.cs +++ b/HKMP/Game/Client/Entity/EntityManager.cs @@ -137,6 +137,7 @@ public void SpawnEntity(ushort id, EntityType spawningType, EntityType spawnedTy var processor = new EntityProcessor { GameObject = spawnedObject, IsSceneHost = IsSceneHost, + IsSceneHostDetermined = IsSceneHostDetermined, LateLoad = true, SpawnedId = id }.Process(); @@ -238,6 +239,7 @@ private bool OnGameObjectSpawned(EntitySpawnDetails details) { var processor = new EntityProcessor { GameObject = details.GameObject, IsSceneHost = IsSceneHost, + IsSceneHostDetermined = IsSceneHostDetermined, LateLoad = true }.Process(); @@ -329,13 +331,13 @@ private void OnSceneChanged(Scene oldScene, Scene newScene) { return; } + IsSceneHostDetermined = false; + FindEntitiesInScene(newScene, false); // Since we have tried finding entities in the scene, we also check whether there are un-applied updates for // those entities CheckReceivedUpdates(); - - IsSceneHostDetermined = false; } /// @@ -447,6 +449,7 @@ private void FindEntitiesInScene(Scene scene, bool lateLoad) { new EntityProcessor { GameObject = obj, IsSceneHost = IsSceneHost, + IsSceneHostDetermined = IsSceneHostDetermined, LateLoad = lateLoad }.Process(); } diff --git a/HKMP/Game/Client/Entity/EntityProcessor.cs b/HKMP/Game/Client/Entity/EntityProcessor.cs index 6053f72..4a1af57 100644 --- a/HKMP/Game/Client/Entity/EntityProcessor.cs +++ b/HKMP/Game/Client/Entity/EntityProcessor.cs @@ -38,6 +38,10 @@ internal class EntityProcessor { /// public bool IsSceneHost { get; init; } /// + /// Whether the scene host is determined for this scene locally. + /// + public bool IsSceneHostDetermined { get; init; } + /// /// Whether the processing of this entity should happen under the assumption that was a late load of the /// game object. /// @@ -188,7 +192,7 @@ private void Process( } } - if (LateLoad) { + if (LateLoad && IsSceneHostDetermined) { if (IsSceneHost) { // Since this is a late load it needs to be initialized as host if we are the scene host entity.InitializeHost();