From 933eb27b5ee1c4421989b46849ba78b5e2d7ffbc Mon Sep 17 00:00:00 2001 From: RisaDev <151885272+RisaDev@users.noreply.github.com> Date: Thu, 11 Apr 2024 01:34:53 +0300 Subject: [PATCH] Special actor fixes Remove special actor armatures without waiting (fixes incorrect profile when changing examined character without closing the window) Fix for special actor armatures not reflecting changes in active profiles Slight refactoring --- .../Armatures/Services/ArmatureManager.cs | 29 +++++++------------ CustomizePlus/Profiles/ProfileManager.cs | 22 +++++++------- .../Tabs/Debug/StateMonitoringTab.cs | 4 ++- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/CustomizePlus/Armatures/Services/ArmatureManager.cs b/CustomizePlus/Armatures/Services/ArmatureManager.cs index 7f44526..47eecfd 100644 --- a/CustomizePlus/Armatures/Services/ArmatureManager.cs +++ b/CustomizePlus/Armatures/Services/ArmatureManager.cs @@ -111,8 +111,10 @@ public unsafe sealed class ArmatureManager : IDisposable foreach (var kvPair in Armatures.ToList()) { var armature = kvPair.Value; + //Only remove armatures which haven't been seen for a while + //But remove armatures of special actors (like examine screen) right away if (!_objectManager.ContainsKey(kvPair.Value.ActorIdentifier) && - armature.LastSeen <= armatureExpirationDateTime) //Only remove armatures which haven't been seen for a while + (armature.LastSeen <= armatureExpirationDateTime || armature.ActorIdentifier.Type == IdentifierType.Special)) { _logger.Debug($"Removing armature {armature} because {kvPair.Key.IncognitoDebug()} is gone"); RemoveArmature(armature, ArmatureChanged.DeletionReason.Gone); @@ -124,27 +126,12 @@ public unsafe sealed class ArmatureManager : IDisposable armature.IsVisible = armature.LastSeen.AddSeconds(1) >= currentTime; } - Profile? GetProfileForActor(ActorIdentifier identifier) - { - foreach (var profile in _profileManager.GetEnabledProfilesByActor(identifier)) - { - if (profile.LimitLookupToOwnedObjects && - (identifier.Type != IdentifierType.Owned || - identifier.PlayerName != _objectManager.PlayerData.Identifier.PlayerName)) - continue; - - return profile; - } - - return null; - } - foreach (var obj in _objectManager.Identifiers) { var actorIdentifier = obj.Key.CreatePermanent(); if (!Armatures.ContainsKey(actorIdentifier)) { - var activeProfile = GetProfileForActor(actorIdentifier); + var activeProfile = _profileManager.GetEnabledProfilesByActor(actorIdentifier).FirstOrDefault(); if (activeProfile == null) continue; @@ -166,7 +153,7 @@ public unsafe sealed class ArmatureManager : IDisposable _logger.Debug($"Armature {armature} is pending profile/bone rebind, rebinding..."); armature.IsPendingProfileRebind = false; - var activeProfile = GetProfileForActor(actorIdentifier); + var activeProfile = _profileManager.GetEnabledProfilesByActor(actorIdentifier).FirstOrDefault(); Profile? oldProfile = armature.Profile; if (activeProfile != armature.Profile) { @@ -555,7 +542,11 @@ public unsafe sealed class ArmatureManager : IDisposable { foreach(var kvPair in Armatures) { - if(kvPair.Key.ToNameWithoutOwnerName() == characterName) + var actorIdentifier = kvPair.Key; + if (actorIdentifier.Type == IdentifierType.Special) + actorIdentifier = actorIdentifier.GetTrueActorForSpecialType(); + + if(actorIdentifier.ToNameWithoutOwnerName() == characterName) yield return kvPair.Value; } } diff --git a/CustomizePlus/Profiles/ProfileManager.cs b/CustomizePlus/Profiles/ProfileManager.cs index db2b976..839c98e 100644 --- a/CustomizePlus/Profiles/ProfileManager.cs +++ b/CustomizePlus/Profiles/ProfileManager.cs @@ -25,6 +25,7 @@ using CustomizePlus.Profiles.Enums; using CustomizePlus.Profiles.Exceptions; using Penumbra.GameData.Enums; using Penumbra.GameData.Interop; +using System.Runtime.Serialization; namespace CustomizePlus.Profiles; @@ -487,17 +488,21 @@ public class ProfileManager : IDisposable if (name.IsNullOrWhitespace()) yield break; - if (_templateEditorManager.IsEditorActive && _templateEditorManager.EditorProfile.Enabled) + bool IsProfileAppliesToCurrentActor(Profile profile) { - if (ProfileAppliesTo(_templateEditorManager.EditorProfile, name)) - { - yield return _templateEditorManager.EditorProfile; - } + return profile.CharacterName.Text == name && + (!profile.LimitLookupToOwnedObjects || + (actorIdentifier.Type == IdentifierType.Owned && + actorIdentifier.PlayerName != _actorManager.GetCurrentPlayer().PlayerName)); } + + if (_templateEditorManager.IsEditorActive && _templateEditorManager.EditorProfile.Enabled && IsProfileAppliesToCurrentActor(_templateEditorManager.EditorProfile)) + yield return _templateEditorManager.EditorProfile; + foreach (var profile in Profiles) { - if (ProfileAppliesTo(profile, name) && profile.Enabled) + if (IsProfileAppliesToCurrentActor(profile) && profile.Enabled) yield return profile; } @@ -520,11 +525,6 @@ public class ProfileManager : IDisposable yield return _templateEditorManager.EditorProfile; } - /// - /// Returns whether or not profile applies to the object with the indicated name. - /// - public bool ProfileAppliesTo(Profile profile, string objectName) => !string.IsNullOrWhiteSpace(objectName) && objectName == profile.CharacterName.Text; - private void SaveProfile(Profile profile) { //disallow saving special profiles diff --git a/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs b/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs index 620a559..eb36e40 100644 --- a/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs +++ b/CustomizePlus/UI/Windows/MainWindow/Tabs/Debug/StateMonitoringTab.cs @@ -96,7 +96,7 @@ public class StateMonitoringTab continue; ImGui.Text($"ActorIdentifier"); - ImGui.Text($"PlayerName: {kvPair.Key.PlayerName}"); + ImGui.Text($"PlayerName: {kvPair.Key.PlayerName.ToString()}"); ImGui.Text($"HomeWorld: {kvPair.Key.HomeWorld}"); ImGui.Text($"Retainer: {kvPair.Key.Retainer}"); ImGui.Text($"Kind: {kvPair.Key.Kind}"); @@ -106,6 +106,8 @@ public class StateMonitoringTab ImGui.Text($"Special: {kvPair.Key.Special.ToString()}"); ImGui.Text($"ToName: {kvPair.Key.ToName()}"); ImGui.Text($"ToNameWithoutOwnerName: {kvPair.Key.ToNameWithoutOwnerName()}"); + if(kvPair.Key.Type == Penumbra.GameData.Enums.IdentifierType.Special) + ImGui.Text($"True actor: {kvPair.Key.GetTrueActorForSpecialType().ToName()}"); ImGui.Spacing(); ImGui.Spacing();