diff --git a/QSB/Animation/Player/AnimationSync.cs b/QSB/Animation/Player/AnimationSync.cs index 39b99a02..a96b0266 100644 --- a/QSB/Animation/Player/AnimationSync.cs +++ b/QSB/Animation/Player/AnimationSync.cs @@ -15,6 +15,14 @@ namespace QSB.Animation.Player; [UsedInUnityProject] public class AnimationSync : PlayerSyncObject { + public static int DropHeldItem = Animator.StringToHash("DropHeldItem"); + public static int HoldLantern = Animator.StringToHash("HoldLantern"); + public static int HoldSharedStone = Animator.StringToHash("HoldSharedStone"); + public static int HoldScroll = Animator.StringToHash("HoldScroll"); + public static int HoldWarpCore = Animator.StringToHash("HoldWarpCore"); + public static int HoldAdvWarpCore = Animator.StringToHash("HoldAdvWarpCore"); + public static int HoldItem = Animator.StringToHash("HoldItem"); + private RuntimeAnimatorController _suitedAnimController; private AnimatorOverrideController _unsuitedAnimController; private GameObject _suitedGraphics; @@ -209,4 +217,20 @@ public class AnimationSync : PlayerSyncObject Mirror.RebuildFloatParams(); NetworkAnimator.Invoke("Awake"); } + + public void PickUpItem(int animHash) + { + VisibleAnimator.SetTrigger(animHash); + VisibleAnimator.SetLayerWeight(2, 1); + InvisibleAnimator.SetTrigger(animHash); + InvisibleAnimator.SetLayerWeight(2, 1); + } + + public void DropItem() + { + VisibleAnimator.SetTrigger(DropHeldItem); + VisibleAnimator.SetLayerWeight(2, 1); + InvisibleAnimator.SetTrigger(DropHeldItem); + InvisibleAnimator.SetLayerWeight(2, 1); + } } diff --git a/QSB/Animation/Player/AnimatorMirror.cs b/QSB/Animation/Player/AnimatorMirror.cs index 736d5b2e..fcfbe2d1 100644 --- a/QSB/Animation/Player/AnimatorMirror.cs +++ b/QSB/Animation/Player/AnimatorMirror.cs @@ -15,7 +15,7 @@ public class AnimatorMirror : MonoBehaviour private Animator _to; private NetworkAnimator _networkAnimator; - private readonly Dictionary _floatParams = new(); + private readonly Dictionary _floatParams = new(); /// /// Initializes the Animator Mirror @@ -82,36 +82,38 @@ public class AnimatorMirror : MonoBehaviour switch (fromParam.type) { case AnimatorControllerParameterType.Float: - _floatParams[fromParam.name].Target = _from.GetFloat(fromParam.name); + _floatParams[fromParam.nameHash].Target = _from.GetFloat(fromParam.nameHash); break; case AnimatorControllerParameterType.Int: - _to.SetInteger(fromParam.name, _from.GetInteger(fromParam.name)); + _to.SetInteger(fromParam.nameHash, _from.GetInteger(fromParam.nameHash)); break; case AnimatorControllerParameterType.Bool: - _to.SetBool(fromParam.name, _from.GetBool(fromParam.name)); + _to.SetBool(fromParam.nameHash, _from.GetBool(fromParam.nameHash)); break; case AnimatorControllerParameterType.Trigger: - if (_from.GetBool(fromParam.name) && !_to.GetBool(fromParam.name)) + if (_from.GetBool(fromParam.nameHash) && !_to.GetBool(fromParam.nameHash)) { if (_networkAnimator != null) { - _networkAnimator.SetTrigger(fromParam.name); + DebugLog.DebugWrite($"Set {fromParam.name} on netanim"); + _networkAnimator.SetTrigger(fromParam.nameHash); } - _to.SetTrigger(fromParam.name); + _to.SetTrigger(fromParam.nameHash); } - if (!_from.GetBool(fromParam.name) && _to.GetBool(fromParam.name)) + if (!_from.GetBool(fromParam.nameHash) && _to.GetBool(fromParam.nameHash)) { if (_networkAnimator != null) { - _networkAnimator.ResetTrigger(fromParam.name); + DebugLog.DebugWrite($"Reset {fromParam.name} on netanim"); + _networkAnimator.ResetTrigger(fromParam.nameHash); } - _to.ResetTrigger(fromParam.name); + _to.ResetTrigger(fromParam.nameHash); } break; @@ -142,7 +144,7 @@ public class AnimatorMirror : MonoBehaviour _floatParams.Clear(); foreach (var param in _from.parameters.Where(p => p.type == AnimatorControllerParameterType.Float)) { - _floatParams.Add(param.name, new AnimFloatParam()); + _floatParams.Add(param.nameHash, new AnimFloatParam()); } } } diff --git a/QSB/Animation/Player/Patches/PlayerAnimControllerPatches.cs b/QSB/Animation/Player/Patches/PlayerAnimControllerPatches.cs new file mode 100644 index 00000000..c35239c4 --- /dev/null +++ b/QSB/Animation/Player/Patches/PlayerAnimControllerPatches.cs @@ -0,0 +1,63 @@ +using HarmonyLib; +using QSB.Patches; + +namespace QSB.Animation.Player.Patches; + +[HarmonyPatch(typeof(PlayerAnimController))] +public class PlayerAnimControllerPatches : QSBPatch +{ + public override QSBPatchTypes Type => QSBPatchTypes.OnModStart; + + /* + * These patches preserve layer weights between animatorcontroller changes. + * No idea if this is intended Unity behaviour, + * but when changing the controller the layer weights get + * reset back to 0 - even if their default is not 0. + */ + + [HarmonyPrefix] + [HarmonyPatch(nameof(PlayerAnimController.OnPutOnSuit))] + public static bool OnPutOnSuit(PlayerAnimController __instance) + { + var layerCount = __instance._animator.layerCount; + var layerWeights = new float[layerCount]; + for (var i = 0; i < layerCount; i++) + { + layerWeights[i] = __instance._animator.GetLayerWeight(i); + } + + __instance._animator.runtimeAnimatorController = __instance._baseAnimController; + __instance._unsuitedGroup.SetActive(false); + __instance._suitedGroup.SetActive(!PlayerState.InMapView()); + + for (var i = 0; i < layerCount; i++) + { + __instance._animator.SetLayerWeight(i, layerWeights[i]); + } + + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(PlayerAnimController.OnRemoveSuit))] + public static bool OnRemoveSuit(PlayerAnimController __instance) + { + var layerCount = __instance._animator.layerCount; + var layerWeights = new float[layerCount]; + for (var i = 0; i < layerCount; i++) + { + layerWeights[i] = __instance._animator.GetLayerWeight(i); + } + + __instance._animator.runtimeAnimatorController = __instance._unsuitedAnimOverride; + __instance._unsuitedGroup.SetActive(!PlayerState.InMapView()); + __instance._suitedGroup.SetActive(false); + + for (var i = 0; i < layerCount; i++) + { + __instance._animator.SetLayerWeight(i, layerWeights[i]); + } + + return false; + } +} diff --git a/QSB/AssetBundles/qsb_network b/QSB/AssetBundles/qsb_network index 01f3fc70..f8dd887e 100644 Binary files a/QSB/AssetBundles/qsb_network and b/QSB/AssetBundles/qsb_network differ diff --git a/QSB/AssetBundles/qsb_network_big b/QSB/AssetBundles/qsb_network_big index 5236cf8f..e48b6e8d 100644 Binary files a/QSB/AssetBundles/qsb_network_big and b/QSB/AssetBundles/qsb_network_big differ diff --git a/QSB/CampfireSync/Messages/BurnSlideReelMessage.cs b/QSB/CampfireSync/Messages/BurnSlideReelMessage.cs index 7354ba44..9ececd79 100644 --- a/QSB/CampfireSync/Messages/BurnSlideReelMessage.cs +++ b/QSB/CampfireSync/Messages/BurnSlideReelMessage.cs @@ -1,4 +1,5 @@ -using QSB.CampfireSync.WorldObjects; +using QSB.Animation.Player; +using QSB.CampfireSync.WorldObjects; using QSB.ItemSync.WorldObjects.Items; using QSB.Messaging; using QSB.Player; @@ -23,7 +24,7 @@ public class BurnSlideReelMessage : QSBWorldObjectMessage campfire._burnedSlideReelSocket, campfire._sector, null); fromPlayer.HeldItem = null; - fromPlayer.AnimationSync.VisibleAnimator.SetTrigger("DropHeldItem"); + fromPlayer.AnimationSync.DropItem(); WorldObject.AttachedObject.Burn(); campfire.SetDropSlideReelMode(false); campfire._hasBurnedSlideReel = true; diff --git a/QSB/ItemSync/Messages/DropItemMessage.cs b/QSB/ItemSync/Messages/DropItemMessage.cs index 6bc88a75..514e83a4 100644 --- a/QSB/ItemSync/Messages/DropItemMessage.cs +++ b/QSB/ItemSync/Messages/DropItemMessage.cs @@ -1,4 +1,5 @@ -using QSB.ItemSync.WorldObjects; +using QSB.Animation.Player; +using QSB.ItemSync.WorldObjects; using QSB.ItemSync.WorldObjects.Items; using QSB.Messaging; using QSB.Player; @@ -69,6 +70,6 @@ public class DropItemMessage : QSBWorldObjectMessage switch (itemType) { case ItemType.Scroll: - player.AnimationSync.VisibleAnimator.SetTrigger("HoldScroll"); + player.AnimationSync.PickUpItem(AnimationSync.HoldScroll); break; case ItemType.WarpCore: if (((QSBWarpCoreItem)WorldObject).IsVesselCoreType()) { - player.AnimationSync.VisibleAnimator.SetTrigger("HoldAdvWarpCore"); + player.AnimationSync.PickUpItem(AnimationSync.HoldAdvWarpCore); } else { - player.AnimationSync.VisibleAnimator.SetTrigger("HoldWarpCore"); + player.AnimationSync.PickUpItem(AnimationSync.HoldWarpCore); } break; case ItemType.SharedStone: - player.AnimationSync.VisibleAnimator.SetTrigger("HoldSharedStone"); + player.AnimationSync.PickUpItem(AnimationSync.HoldSharedStone); break; case ItemType.ConversationStone: - player.AnimationSync.VisibleAnimator.SetTrigger("HoldItem"); + player.AnimationSync.PickUpItem(AnimationSync.HoldItem); break; case ItemType.Lantern: - player.AnimationSync.VisibleAnimator.SetTrigger("HoldLantern"); + player.AnimationSync.PickUpItem(AnimationSync.HoldLantern); break; case ItemType.SlideReel: case ItemType.DreamLantern: diff --git a/QSB/ItemSync/Messages/SocketItemMessage.cs b/QSB/ItemSync/Messages/SocketItemMessage.cs index 0d5e8753..71465c80 100644 --- a/QSB/ItemSync/Messages/SocketItemMessage.cs +++ b/QSB/ItemSync/Messages/SocketItemMessage.cs @@ -1,4 +1,5 @@ -using QSB.ItemSync.WorldObjects.Items; +using QSB.Animation.Player; +using QSB.ItemSync.WorldObjects.Items; using QSB.ItemSync.WorldObjects.Sockets; using QSB.Messaging; using QSB.Player; @@ -29,7 +30,7 @@ public class SocketItemMessage : QSBWorldObjectMessage