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
This commit is contained in:
RisaDev
2024-04-11 01:34:53 +03:00
parent 076460fbdd
commit 933eb27b5e
3 changed files with 24 additions and 31 deletions

View File

@@ -111,8 +111,10 @@ public unsafe sealed class ArmatureManager : IDisposable
foreach (var kvPair in Armatures.ToList()) foreach (var kvPair in Armatures.ToList())
{ {
var armature = kvPair.Value; 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) && 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"); _logger.Debug($"Removing armature {armature} because {kvPair.Key.IncognitoDebug()} is gone");
RemoveArmature(armature, ArmatureChanged.DeletionReason.Gone); RemoveArmature(armature, ArmatureChanged.DeletionReason.Gone);
@@ -124,27 +126,12 @@ public unsafe sealed class ArmatureManager : IDisposable
armature.IsVisible = armature.LastSeen.AddSeconds(1) >= currentTime; 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) foreach (var obj in _objectManager.Identifiers)
{ {
var actorIdentifier = obj.Key.CreatePermanent(); var actorIdentifier = obj.Key.CreatePermanent();
if (!Armatures.ContainsKey(actorIdentifier)) if (!Armatures.ContainsKey(actorIdentifier))
{ {
var activeProfile = GetProfileForActor(actorIdentifier); var activeProfile = _profileManager.GetEnabledProfilesByActor(actorIdentifier).FirstOrDefault();
if (activeProfile == null) if (activeProfile == null)
continue; continue;
@@ -166,7 +153,7 @@ public unsafe sealed class ArmatureManager : IDisposable
_logger.Debug($"Armature {armature} is pending profile/bone rebind, rebinding..."); _logger.Debug($"Armature {armature} is pending profile/bone rebind, rebinding...");
armature.IsPendingProfileRebind = false; armature.IsPendingProfileRebind = false;
var activeProfile = GetProfileForActor(actorIdentifier); var activeProfile = _profileManager.GetEnabledProfilesByActor(actorIdentifier).FirstOrDefault();
Profile? oldProfile = armature.Profile; Profile? oldProfile = armature.Profile;
if (activeProfile != armature.Profile) if (activeProfile != armature.Profile)
{ {
@@ -555,7 +542,11 @@ public unsafe sealed class ArmatureManager : IDisposable
{ {
foreach(var kvPair in Armatures) 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; yield return kvPair.Value;
} }
} }

View File

@@ -25,6 +25,7 @@ using CustomizePlus.Profiles.Enums;
using CustomizePlus.Profiles.Exceptions; using CustomizePlus.Profiles.Exceptions;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
using System.Runtime.Serialization;
namespace CustomizePlus.Profiles; namespace CustomizePlus.Profiles;
@@ -487,17 +488,21 @@ public class ProfileManager : IDisposable
if (name.IsNullOrWhitespace()) if (name.IsNullOrWhitespace())
yield break; yield break;
if (_templateEditorManager.IsEditorActive && _templateEditorManager.EditorProfile.Enabled) bool IsProfileAppliesToCurrentActor(Profile profile)
{ {
if (ProfileAppliesTo(_templateEditorManager.EditorProfile, name)) return profile.CharacterName.Text == name &&
{ (!profile.LimitLookupToOwnedObjects ||
yield return _templateEditorManager.EditorProfile; (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) foreach (var profile in Profiles)
{ {
if (ProfileAppliesTo(profile, name) && profile.Enabled) if (IsProfileAppliesToCurrentActor(profile) && profile.Enabled)
yield return profile; yield return profile;
} }
@@ -520,11 +525,6 @@ public class ProfileManager : IDisposable
yield return _templateEditorManager.EditorProfile; yield return _templateEditorManager.EditorProfile;
} }
/// <summary>
/// Returns whether or not profile applies to the object with the indicated name.
/// </summary>
public bool ProfileAppliesTo(Profile profile, string objectName) => !string.IsNullOrWhiteSpace(objectName) && objectName == profile.CharacterName.Text;
private void SaveProfile(Profile profile) private void SaveProfile(Profile profile)
{ {
//disallow saving special profiles //disallow saving special profiles

View File

@@ -96,7 +96,7 @@ public class StateMonitoringTab
continue; continue;
ImGui.Text($"ActorIdentifier"); ImGui.Text($"ActorIdentifier");
ImGui.Text($"PlayerName: {kvPair.Key.PlayerName}"); ImGui.Text($"PlayerName: {kvPair.Key.PlayerName.ToString()}");
ImGui.Text($"HomeWorld: {kvPair.Key.HomeWorld}"); ImGui.Text($"HomeWorld: {kvPair.Key.HomeWorld}");
ImGui.Text($"Retainer: {kvPair.Key.Retainer}"); ImGui.Text($"Retainer: {kvPair.Key.Retainer}");
ImGui.Text($"Kind: {kvPair.Key.Kind}"); ImGui.Text($"Kind: {kvPair.Key.Kind}");
@@ -106,6 +106,8 @@ public class StateMonitoringTab
ImGui.Text($"Special: {kvPair.Key.Special.ToString()}"); ImGui.Text($"Special: {kvPair.Key.Special.ToString()}");
ImGui.Text($"ToName: {kvPair.Key.ToName()}"); ImGui.Text($"ToName: {kvPair.Key.ToName()}");
ImGui.Text($"ToNameWithoutOwnerName: {kvPair.Key.ToNameWithoutOwnerName()}"); 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();
ImGui.Spacing(); ImGui.Spacing();