diff --git a/Penumbra.GameData/Actors/ActorManager.Data.cs b/Penumbra.GameData/Actors/ActorManager.Data.cs index 7889f679..51e1811a 100644 --- a/Penumbra.GameData/Actors/ActorManager.Data.cs +++ b/Penumbra.GameData/Actors/ActorManager.Data.cs @@ -256,7 +256,7 @@ public sealed partial class ActorManager : IDisposable return false; } - id = FromObject(&other->GameObject, out _, false, true); + id = FromObject(&other->GameObject, out _, false, true, false); return true; } @@ -283,7 +283,7 @@ public sealed partial class ActorManager : IDisposable if (obj != null && obj->ObjectKind is (byte)ObjectKind.Player && Compare(gameObject, (Character*)obj)) - return FromObject(obj, out _, false, true); + return FromObject(obj, out _, false, true, false); } return ActorIdentifier.Invalid; diff --git a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs index daa07168..9f5f246f 100644 --- a/Penumbra.GameData/Actors/ActorManager.Identifiers.cs +++ b/Penumbra.GameData/Actors/ActorManager.Identifiers.cs @@ -244,7 +244,7 @@ public partial class ActorManager /// Compute an ActorIdentifier from a GameObject. If check is true, the values are checked for validity. /// public unsafe ActorIdentifier FromObject(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor, - out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, bool allowPlayerNpc, bool check) + out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, bool allowPlayerNpc, bool check, bool withoutIndex) { owner = null; if (actor == null) @@ -298,9 +298,10 @@ public partial class ActorManager } } + var index = withoutIndex ? ushort.MaxValue : actor->ObjectIndex; return check - ? CreateNpc(ObjectKind.BattleNpc, nameId, actor->ObjectIndex) - : CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, actor->ObjectIndex, ObjectKind.BattleNpc, nameId); + ? CreateNpc(ObjectKind.BattleNpc, nameId, index) + : CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, index, ObjectKind.BattleNpc, nameId); } case ObjectKind.EventNpc: { @@ -326,9 +327,10 @@ public partial class ActorManager } } + var index = withoutIndex ? ushort.MaxValue : actor->ObjectIndex; return check - ? CreateNpc(ObjectKind.EventNpc, dataId, actor->ObjectIndex) - : CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, actor->ObjectIndex, ObjectKind.EventNpc, dataId); + ? CreateNpc(ObjectKind.EventNpc, dataId, index) + : CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, index, ObjectKind.EventNpc, dataId); } case ObjectKind.MountType: case ObjectKind.Companion: @@ -357,7 +359,7 @@ public partial class ActorManager default: { var name = new ByteString(actor->Name); - var index = actor->ObjectIndex; + var index = withoutIndex ? ushort.MaxValue : actor->ObjectIndex; return CreateIndividualUnchecked(IdentifierType.UnkObject, name, index, ObjectKind.None, 0); } } @@ -379,12 +381,12 @@ public partial class ActorManager } public unsafe ActorIdentifier FromObject(GameObject? actor, out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, - bool allowPlayerNpc, bool check) + bool allowPlayerNpc, bool check, bool withoutIndex) => FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero), out owner, allowPlayerNpc, - check); + check, withoutIndex); - public unsafe ActorIdentifier FromObject(GameObject? actor, bool allowPlayerNpc, bool check) - => FromObject(actor, out _, allowPlayerNpc, check); + public unsafe ActorIdentifier FromObject(GameObject? actor, bool allowPlayerNpc, bool check, bool withoutIndex) + => FromObject(actor, out _, allowPlayerNpc, check, withoutIndex); public ActorIdentifier CreateIndividual(IdentifierType type, ByteString name, ushort homeWorld, ObjectKind kind, uint dataId) => type switch @@ -551,13 +553,13 @@ public partial class ActorManager => actor is >= ScreenActor.CharacterScreen and <= ScreenActor.Card8; /// Verify that the object index is a valid index for an NPC. - public static bool VerifyIndex(ushort index) + public bool VerifyIndex(ushort index) { return index switch { ushort.MaxValue => true, < 200 => index % 2 == 0, - > (ushort)ScreenActor.Card8 => index < 426, + > (ushort)ScreenActor.Card8 => index < _objects.Length, _ => false, }; } diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index be3a01ac..0df89f55 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -848,7 +848,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi return PenumbraApiEc.InvalidArgument; } - var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ], false, false ); + var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ], false, false, true ); if( !identifier.IsValid ) { return PenumbraApiEc.InvalidArgument; @@ -1042,7 +1042,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi } var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx ); - return Penumbra.Actors.FromObject( ptr, out _, false, true ); + return Penumbra.Actors.FromObject( ptr, out _, false, true, true ); } // Resolve a path given by string for a specific collection. diff --git a/Penumbra/Collections/IndividualCollections.Access.cs b/Penumbra/Collections/IndividualCollections.Access.cs index 713f8524..0b43baf3 100644 --- a/Penumbra/Collections/IndividualCollections.Access.cs +++ b/Penumbra/Collections/IndividualCollections.Access.cs @@ -143,10 +143,10 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ } public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection ) - => TryGetCollection( _actorManager.FromObject( gameObject, true, false ), out collection ); + => TryGetCollection( _actorManager.FromObject( gameObject, true, false, false ), out collection ); public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection ) - => TryGetCollection( _actorManager.FromObject( gameObject, out _, true, false ), out collection ); + => TryGetCollection( _actorManager.FromObject( gameObject, out _, true, false, false ), out collection ); private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection ) { diff --git a/Penumbra/Collections/ResolveData.cs b/Penumbra/Collections/ResolveData.cs index 90c56144..485f2c08 100644 --- a/Penumbra/Collections/ResolveData.cs +++ b/Penumbra/Collections/ResolveData.cs @@ -47,7 +47,7 @@ public readonly struct ResolveData try { - var id = Penumbra.Actors.FromObject( ( GameObject* )AssociatedGameObject, out _, false, true ); + var id = Penumbra.Actors.FromObject( ( GameObject* )AssociatedGameObject, out _, false, true, true ); if( id.IsValid ) { var name = id.ToString(); diff --git a/Penumbra/CommandHandler.cs b/Penumbra/CommandHandler.cs index 3779e512..0af75477 100644 --- a/Penumbra/CommandHandler.cs +++ b/Penumbra/CommandHandler.cs @@ -297,7 +297,7 @@ public class CommandHandler : IDisposable { if( ObjectReloader.GetName( split[ 2 ].ToLowerInvariant(), out var obj ) ) { - identifier = _actors.FromObject( obj, false, true ); + identifier = _actors.FromObject( obj, false, true, true ); if( !identifier.IsValid ) { Dalamud.Chat.Print( new SeStringBuilder().AddText( "The placeholder " ).AddGreen( split[ 2 ] ) diff --git a/Penumbra/Interop/Resolver/PathResolver.Identification.cs b/Penumbra/Interop/Resolver/PathResolver.Identification.cs index cbd91b4f..85839f24 100644 --- a/Penumbra/Interop/Resolver/PathResolver.Identification.cs +++ b/Penumbra/Interop/Resolver/PathResolver.Identification.cs @@ -56,7 +56,7 @@ public unsafe partial class PathResolver return IdentifiedCache.Set( collection2, ActorIdentifier.Invalid, gameObject ); } - var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, true, false ); + var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, true, false, false ); if( identifier.Type is IdentifierType.Special ) { ( identifier, var type ) = Penumbra.CollectionManager.Individuals.ConvertSpecialIdentifier( identifier ); diff --git a/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs b/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs index 660bb1d5..7f8e0f9a 100644 --- a/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs +++ b/Penumbra/UI/ConfigWindow.CollectionsTab.Individual.cs @@ -243,10 +243,10 @@ public partial class ConfigWindow var buttonWidth1 = new Vector2( 90 * ImGuiHelpers.GlobalScale, 0 ); var buttonWidth2 = new Vector2( 120 * ImGuiHelpers.GlobalScale, 0 ); - var assignWidth = new Vector2((_window._inputTextWidth.X - ImGui.GetStyle().ItemSpacing.X) / 2, 0); - var change = DrawNewCurrentPlayerCollection(assignWidth); + var assignWidth = new Vector2( ( _window._inputTextWidth.X - ImGui.GetStyle().ItemSpacing.X ) / 2, 0 ); + var change = DrawNewCurrentPlayerCollection( assignWidth ); ImGui.SameLine(); - change |= DrawNewTargetCollection(assignWidth); + change |= DrawNewTargetCollection( assignWidth ); change |= DrawNewPlayerCollection( buttonWidth1, width ); ImGui.SameLine(); @@ -263,7 +263,7 @@ public partial class ConfigWindow } } - private static bool DrawNewCurrentPlayerCollection(Vector2 width) + private static bool DrawNewCurrentPlayerCollection( Vector2 width ) { var player = Penumbra.Actors.GetCurrentPlayer(); var result = Penumbra.CollectionManager.Individuals.CanAdd( player ); @@ -285,10 +285,10 @@ public partial class ConfigWindow return false; } - private static bool DrawNewTargetCollection(Vector2 width) + private static bool DrawNewTargetCollection( Vector2 width ) { var target = Dalamud.Targets.Target; - var player = Penumbra.Actors.FromObject( target, false, true ); + var player = Penumbra.Actors.FromObject( target, false, true, true ); var result = Penumbra.CollectionManager.Individuals.CanAdd( player ); var tt = result switch { @@ -299,7 +299,7 @@ public partial class ConfigWindow }; if( ImGuiUtil.DrawDisabledButton( "Assign Current Target", width, tt, result != IndividualCollections.AddResult.Valid ) ) { - Penumbra.CollectionManager.Individuals.Add( new[] { player }, Penumbra.CollectionManager.Default ); + Penumbra.CollectionManager.Individuals.Add( Penumbra.CollectionManager.Individuals.GetGroup( player ), Penumbra.CollectionManager.Default ); return true; } diff --git a/Penumbra/UI/ConfigWindow.DebugTab.cs b/Penumbra/UI/ConfigWindow.DebugTab.cs index 39df2f3e..47abe7ec 100644 --- a/Penumbra/UI/ConfigWindow.DebugTab.cs +++ b/Penumbra/UI/ConfigWindow.DebugTab.cs @@ -215,7 +215,7 @@ public partial class ConfigWindow { ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" ); ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" ); - var identifier = Penumbra.Actors.FromObject( obj, false, true ); + var identifier = Penumbra.Actors.FromObject( obj, false, true, false ); ImGuiUtil.DrawTableColumn( Penumbra.Actors.ToString( identifier ) ); var id = obj.ObjectKind == ObjectKind.BattleNpc ? $"{identifier.DataId} | {obj.DataId}" : identifier.DataId.ToString(); ImGuiUtil.DrawTableColumn( id );