From c2ac745d72a79d721d2eb42d8476f5a97960be45 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 1 Mar 2023 23:11:05 +0100 Subject: [PATCH] Fix an issue with retainer assignments using ownership wrongly for mannequins. --- Penumbra.GameData/Actors/ActorIdentifier.cs | 8 ++++++++ .../Actors/ActorManager.Identifiers.cs | 18 ++++++++++-------- .../IndividualCollections.Access.cs | 2 +- Penumbra/Collections/IndividualCollections.cs | 2 +- .../UI/Classes/ModEditWindow.FileEditor.cs | 2 +- Penumbra/UI/Classes/ModEditWindow.cs | 2 +- .../ConfigWindow.CollectionsTab.Individual.cs | 2 +- 7 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Penumbra.GameData/Actors/ActorIdentifier.cs b/Penumbra.GameData/Actors/ActorIdentifier.cs index 26565dea..81199fc6 100644 --- a/Penumbra.GameData/Actors/ActorIdentifier.cs +++ b/Penumbra.GameData/Actors/ActorIdentifier.cs @@ -14,11 +14,19 @@ public readonly struct ActorIdentifier : IEquatable public static readonly ActorIdentifier Invalid = new(IdentifierType.Invalid, 0, 0, 0, ByteString.Empty); + public enum RetainerType : ushort + { + Both = 0, + Bell = 1, + Mannequin = 2, + } + // @formatter:off [FieldOffset( 0 )] public readonly IdentifierType Type; // All [FieldOffset( 1 )] public readonly ObjectKind Kind; // Npc, Owned [FieldOffset( 2 )] public readonly ushort HomeWorld; // Player, Owned [FieldOffset( 2 )] public readonly ushort Index; // NPC + [FieldOffset( 2 )] public readonly RetainerType Retainer; // Retainer [FieldOffset( 2 )] public readonly ScreenActor Special; // Special [FieldOffset( 4 )] public readonly uint DataId; // Owned, NPC [FieldOffset( 8 )] public readonly ByteString PlayerName; // Player, Owned diff --git a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs index 15c12714..daa07168 100644 --- a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs +++ b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs @@ -33,7 +33,7 @@ public partial class ActorManager case IdentifierType.Retainer: { var name = ByteString.FromStringUnsafe(data[nameof(ActorIdentifier.PlayerName)]?.ToObject(), false); - return CreateRetainer(name); + return CreateRetainer(name, 0); } case IdentifierType.Owned: { @@ -318,8 +318,9 @@ public partial class ActorManager if (!actualName.Equals(retainerName)) { var ident = check - ? CreateRetainer(retainerName) - : CreateIndividualUnchecked(IdentifierType.Retainer, retainerName, actor->ObjectIndex, ObjectKind.EventNpc, dataId); + ? CreateRetainer(retainerName, ActorIdentifier.RetainerType.Mannequin) + : CreateIndividualUnchecked(IdentifierType.Retainer, retainerName, (ushort)ActorIdentifier.RetainerType.Mannequin, + ObjectKind.EventNpc, dataId); if (ident.IsValid) return ident; } @@ -349,8 +350,9 @@ public partial class ActorManager { var name = new ByteString(actor->Name); return check - ? CreateRetainer(name) - : CreateIndividualUnchecked(IdentifierType.Retainer, name, 0, ObjectKind.None, uint.MaxValue); + ? CreateRetainer(name, ActorIdentifier.RetainerType.Bell) + : CreateIndividualUnchecked(IdentifierType.Retainer, name, (ushort)ActorIdentifier.RetainerType.Bell, ObjectKind.None, + uint.MaxValue); } default: { @@ -388,7 +390,7 @@ public partial class ActorManager => type switch { IdentifierType.Player => CreatePlayer(name, homeWorld), - IdentifierType.Retainer => CreateRetainer(name), + IdentifierType.Retainer => CreateRetainer(name, (ActorIdentifier.RetainerType)homeWorld), IdentifierType.Owned => CreateOwned(name, homeWorld, kind, dataId), IdentifierType.Special => CreateSpecial((ScreenActor)homeWorld), IdentifierType.Npc => CreateNpc(kind, dataId, homeWorld), @@ -410,12 +412,12 @@ public partial class ActorManager return new ActorIdentifier(IdentifierType.Player, ObjectKind.Player, homeWorld, 0, name); } - public ActorIdentifier CreateRetainer(ByteString name) + public ActorIdentifier CreateRetainer(ByteString name, ActorIdentifier.RetainerType type) { if (!VerifyRetainerName(name.Span)) return ActorIdentifier.Invalid; - return new ActorIdentifier(IdentifierType.Retainer, ObjectKind.Retainer, 0, 0, name); + return new ActorIdentifier(IdentifierType.Retainer, ObjectKind.Retainer, (ushort)type, 0, name); } public ActorIdentifier CreateSpecial(ScreenActor actor) diff --git a/Penumbra/Collections/IndividualCollections.Access.cs b/Penumbra/Collections/IndividualCollections.Access.cs index 83f32b18..713f8524 100644 --- a/Penumbra/Collections/IndividualCollections.Access.cs +++ b/Penumbra/Collections/IndividualCollections.Access.cs @@ -41,7 +41,7 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ return true; } - if( Penumbra.Config.UseOwnerNameForCharacterCollection ) + if( identifier.Retainer is not ActorIdentifier.RetainerType.Mannequin && Penumbra.Config.UseOwnerNameForCharacterCollection ) { return CheckWorlds( _actorManager.GetCurrentPlayer(), out collection ); } diff --git a/Penumbra/Collections/IndividualCollections.cs b/Penumbra/Collections/IndividualCollections.cs index bca5b4a2..61ea2c0e 100644 --- a/Penumbra/Collections/IndividualCollections.cs +++ b/Penumbra/Collections/IndividualCollections.cs @@ -70,7 +70,7 @@ public sealed partial class IndividualCollections return AddResult.Invalid; } - identifiers = new[] { _actorManager.CreateRetainer( retainerName ) }; + identifiers = new[] { _actorManager.CreateRetainer( retainerName, 0 ) }; break; case IdentifierType.Owned: if( !ByteString.FromString( name, out var ownerName ) ) diff --git a/Penumbra/UI/Classes/ModEditWindow.FileEditor.cs b/Penumbra/UI/Classes/ModEditWindow.FileEditor.cs index d3a91f86..19630beb 100644 --- a/Penumbra/UI/Classes/ModEditWindow.FileEditor.cs +++ b/Penumbra/UI/Classes/ModEditWindow.FileEditor.cs @@ -175,7 +175,7 @@ public partial class ModEditWindow } private static T? DefaultParseFile( byte[] bytes ) - => Activator.CreateInstance( typeof( T ), BindingFlags.CreateInstance | BindingFlags.OptionalParamBinding, bytes ) as T; + => Activator.CreateInstance( typeof( T ), bytes ) as T; private void UpdateCurrentFile( Mod.Editor.FileRegistry path ) { diff --git a/Penumbra/UI/Classes/ModEditWindow.cs b/Penumbra/UI/Classes/ModEditWindow.cs index 2c43cca0..3fe48126 100644 --- a/Penumbra/UI/Classes/ModEditWindow.cs +++ b/Penumbra/UI/Classes/ModEditWindow.cs @@ -584,7 +584,7 @@ public partial class ModEditWindow : Window, IDisposable () => _editor?.ShpkFiles ?? Array.Empty< Editor.FileRegistry >(), DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty, - bytes => new ShpkTab( bytes ) ); + null ); _center = new CombinedTexture( _left, _right ); } diff --git a/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs b/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs index 2e3a7194..660bb1d5 100644 --- a/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs +++ b/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs @@ -322,7 +322,7 @@ public partial class ConfigWindow IndividualCollections.AddResult.AlreadySet => AlreadyAssigned, _ => string.Empty, }; - _newRetainerTooltip = Penumbra.CollectionManager.Individuals.CanAdd( IdentifierType.Retainer, _newCharacterName, _worldCombo.CurrentSelection.Key, ObjectKind.None, + _newRetainerTooltip = Penumbra.CollectionManager.Individuals.CanAdd( IdentifierType.Retainer, _newCharacterName, 0, ObjectKind.None, Array.Empty< uint >(), out _newRetainerIdentifiers ) switch { _ when _newCharacterName.Length == 0 => NewRetainerTooltipEmpty,