From c6d6cc4810cf075638cc60f0f4ed690eeda5ff7c Mon Sep 17 00:00:00 2001 From: xaine Date: Wed, 15 Apr 2026 17:02:57 +0100 Subject: [PATCH 1/5] Fix stop emoting prompt showing for all players on idle emotes Added pc.AmOwner check in CoHandleIdleEmote to match CoHandleContinuousEmote behavior --- EmotesMod/Modules/Components/EmoteBehaviour.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EmotesMod/Modules/Components/EmoteBehaviour.cs b/EmotesMod/Modules/Components/EmoteBehaviour.cs index 3ad51f8..9479866 100644 --- a/EmotesMod/Modules/Components/EmoteBehaviour.cs +++ b/EmotesMod/Modules/Components/EmoteBehaviour.cs @@ -24,7 +24,7 @@ public void PlayEmote() public IEnumerator CoHandleIdleEmote(bool loop) { - HudManagerPatches.EmoteCanvas.transform.GetChild(1).gameObject.SetActive(true); + if (pc.AmOwner) HudManagerPatches.EmoteCanvas.transform.GetChild(1).gameObject.SetActive(true); pc.cosmetics.gameObject.SetActive(false); if (loop) { @@ -40,7 +40,7 @@ public IEnumerator CoHandleIdleEmote(bool loop) pc.cosmetics.gameObject.SetActive(true); currentEmote = null!; pc.MyPhysics.Animations.PlayIdleAnimation(); - HudManagerPatches.EmoteCanvas.transform.GetChild(1).gameObject.SetActive(false); + if (pc.AmOwner) HudManagerPatches.EmoteCanvas.transform.GetChild(1).gameObject.SetActive(false); yield break; } From ff3ccacf5369412dec943e781c8a2fbeb665a5b5 Mon Sep 17 00:00:00 2001 From: xaine Date: Wed, 15 Apr 2026 17:05:13 +0100 Subject: [PATCH 2/5] Fix NullReferenceException when stopping a looped idle emote Check currentEmote in the loop condition to avoid accessing it after StopEmote sets it to null --- EmotesMod/Modules/Components/EmoteBehaviour.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EmotesMod/Modules/Components/EmoteBehaviour.cs b/EmotesMod/Modules/Components/EmoteBehaviour.cs index 9479866..bbdd734 100644 --- a/EmotesMod/Modules/Components/EmoteBehaviour.cs +++ b/EmotesMod/Modules/Components/EmoteBehaviour.cs @@ -29,7 +29,7 @@ public IEnumerator CoHandleIdleEmote(bool loop) if (loop) { Vector2 originalPos = pc.GetTruePosition(); - while (originalPos == pc.GetTruePosition()) + while (currentEmote && originalPos == pc.GetTruePosition()) { pc.MyPhysics.Animations.Animator.Play(currentEmote.anim.Value); yield return new WaitForSeconds(currentEmote.anim.Value.length); From b70558943f1279f0a6e0544a3fdc4f4913ccb99c Mon Sep 17 00:00:00 2001 From: xaine Date: Wed, 15 Apr 2026 18:57:20 +0100 Subject: [PATCH 3/5] Fix emote canvas instantiation freezing player movement Lazy-instantiate the emote canvas on first use instead of during HudManager.Start to prevent freezing player movement. Use a property getter with null/destroyed check to ensure auto-initialization on any access. --- EmotesMod/Patches/HudManagerPatches.cs | 65 +++++++++++++---------- EmotesMod/Patches/PlayerControlPatches.cs | 7 +-- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/EmotesMod/Patches/HudManagerPatches.cs b/EmotesMod/Patches/HudManagerPatches.cs index 5617b04..037c10f 100644 --- a/EmotesMod/Patches/HudManagerPatches.cs +++ b/EmotesMod/Patches/HudManagerPatches.cs @@ -1,9 +1,7 @@ using System; using EmotesMod.Modules.Components; using HarmonyLib; -using Rewired; using UnityEngine; -using UnityEngine.Events; using UnityEngine.UI; using Object = UnityEngine.Object; @@ -12,56 +10,67 @@ namespace EmotesMod.Patches; [HarmonyPatch] public class HudManagerPatches { - public static GameObject EmoteCanvas; - + private static GameObject _emoteCanvas; + + public static GameObject EmoteCanvas + { + get + { + if (_emoteCanvas.IsDestroyedOrNull()) LazyInstantiateHud(); + + return _emoteCanvas; + } + } + [HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] [HarmonyPostfix] public static void HudManager_Update_Postfix(HudManager __instance) { - if (EmoteCanvas == null) return; - - if (/*ReInput.players.GetPlayer(0).GetButtonDown(InputPatches.OpenEmoteWheelBind.id)*/ Input.GetKeyDown(KeyCode.E) && Input.GetKey(KeyCode.LeftControl) && PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead) + if ( /*ReInput.players.GetPlayer(0).GetButtonDown(InputPatches.OpenEmoteWheelBind.id)*/ + Input.GetKeyDown(KeyCode.E) && Input.GetKey(KeyCode.LeftControl) && PlayerControl.LocalPlayer && + !PlayerControl.LocalPlayer.Data.IsDead) { var wheel = EmoteCanvas.transform.GetChild(0).gameObject; wheel.SetActive(!wheel.activeSelf); } - if (/*ReInput.players.GetPlayer(0).GetButtonDown(InputPatches.StopEmotingBind.id)*/ Input.GetKeyDown(KeyCode.X)&& PlayerControl.LocalPlayer.GetComponent().currentEmote) - { + if ( /*ReInput.players.GetPlayer(0).GetButtonDown(InputPatches.StopEmotingBind.id)*/ + Input.GetKeyDown(KeyCode.X) && PlayerControl.LocalPlayer.GetComponent().currentEmote) PlayerControl.LocalPlayer.RpcStopEmote(); - } } - + [HarmonyPatch(typeof(HudManager), nameof(HudManager.Start))] [HarmonyPostfix] public static void HudManager_Start_Postfix(HudManager __instance) { - EmoteCanvas = Object.Instantiate(Assets.EmoteCanvas); - EmoteCanvas.transform.GetChild(0).gameObject.SetActive(false); - EmoteCanvas.transform.GetChild(1).gameObject.SetActive(false); - EmoteCanvas.transform.GetChild(1).GetChild(1).GetComponent