Add a small hack to interpret BattleNPC as Players in some cases for Anamnesis.

This commit is contained in:
Ottermandias 2022-12-08 21:32:51 +01:00
parent b65bef17b2
commit d0ed8abab8
6 changed files with 23 additions and 14 deletions

View file

@ -110,7 +110,7 @@ public partial class ActorManager
/// Compute an ActorIdentifier from a GameObject. If check is true, the values are checked for validity. /// Compute an ActorIdentifier from a GameObject. If check is true, the values are checked for validity.
/// </summary> /// </summary>
public unsafe ActorIdentifier FromObject(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor, public unsafe ActorIdentifier FromObject(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor,
out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, bool check = true) out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, bool allowPlayerNpc, bool check)
{ {
owner = null; owner = null;
if (actor == null) if (actor == null)
@ -151,6 +151,19 @@ public partial class ActorManager
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, ObjectKind.BattleNpc, nameId); : CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, ObjectKind.BattleNpc, nameId);
} }
// Hack to support Anamnesis changing ObjectKind for NPC faces.
if (nameId == 0 && allowPlayerNpc)
{
var name = new ByteString(actor->Name);
if (!name.IsEmpty)
{
var homeWorld = ((Character*)actor)->HomeWorld;
return check
? CreatePlayer(name, homeWorld)
: CreateIndividualUnchecked(IdentifierType.Player, name, homeWorld, ObjectKind.None, uint.MaxValue);
}
}
return check return check
? CreateNpc(ObjectKind.BattleNpc, nameId, actor->ObjectIndex) ? CreateNpc(ObjectKind.BattleNpc, nameId, actor->ObjectIndex)
: CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, actor->ObjectIndex, ObjectKind.BattleNpc, nameId); : CreateIndividualUnchecked(IdentifierType.Npc, ByteString.Empty, actor->ObjectIndex, ObjectKind.BattleNpc, nameId);
@ -230,11 +243,11 @@ public partial class ActorManager
} }
public unsafe ActorIdentifier FromObject(GameObject? actor, out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, public unsafe ActorIdentifier FromObject(GameObject? actor, out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner,
bool check = true) bool allowPlayerNpc, bool check)
=> FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero), out owner, check); => FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero), out owner, allowPlayerNpc, check);
public unsafe ActorIdentifier FromObject(GameObject? actor, bool check = true) public unsafe ActorIdentifier FromObject(GameObject? actor, bool allowPlayerNpc, bool check)
=> FromObject(actor, out _, check); => FromObject(actor, out _, allowPlayerNpc, check);
public ActorIdentifier CreateIndividual(IdentifierType type, ByteString name, ushort homeWorld, ObjectKind kind, uint dataId) public ActorIdentifier CreateIndividual(IdentifierType type, ByteString name, ushort homeWorld, ObjectKind kind, uint dataId)
=> type switch => type switch

View file

@ -677,7 +677,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return PenumbraApiEc.InvalidArgument; return PenumbraApiEc.InvalidArgument;
} }
var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ] ); var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ], false, false );
if( !identifier.IsValid ) if( !identifier.IsValid )
{ {
return PenumbraApiEc.InvalidArgument; return PenumbraApiEc.InvalidArgument;

View file

@ -114,10 +114,10 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
} }
public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection ) public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection )
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection ); => TryGetCollection( _actorManager.FromObject( gameObject, true, false ), out collection );
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection ) public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection )
=> TryGetCollection( _actorManager.FromObject( gameObject, out _, false ), out collection ); => TryGetCollection( _actorManager.FromObject( gameObject, out _, true, false ), out collection );
private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection ) private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection )
{ {

View file

@ -53,7 +53,7 @@ public unsafe partial class PathResolver
return IdentifiedCache.Set( collection2, ActorIdentifier.Invalid, gameObject ); return IdentifiedCache.Set( collection2, ActorIdentifier.Invalid, gameObject );
} }
var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, false ); var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, true, false );
identifier = Penumbra.CollectionManager.Individuals.ConvertSpecialIdentifier( identifier ); identifier = Penumbra.CollectionManager.Individuals.ConvertSpecialIdentifier( identifier );
var collection = CollectionByIdentifier( identifier ) var collection = CollectionByIdentifier( identifier )
?? CheckYourself( identifier, gameObject ) ?? CheckYourself( identifier, gameObject )

View file

@ -1,14 +1,10 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Dalamud.Data;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Lumina.Excel.GeneratedSheets;
using OtterGui;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader; using Penumbra.Interop.Loader;

View file

@ -192,7 +192,7 @@ public partial class ConfigWindow
{ {
ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" ); ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" );
ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" ); ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" );
var identifier = Penumbra.Actors.FromObject( obj, true ); var identifier = Penumbra.Actors.FromObject( obj, false, true );
ImGuiUtil.DrawTableColumn( Penumbra.Actors.ToString( identifier ) ); ImGuiUtil.DrawTableColumn( Penumbra.Actors.ToString( identifier ) );
var id = obj.ObjectKind == ObjectKind.BattleNpc ? $"{identifier.DataId} | {obj.DataId}" : identifier.DataId.ToString(); var id = obj.ObjectKind == ObjectKind.BattleNpc ? $"{identifier.DataId} | {obj.DataId}" : identifier.DataId.ToString();
ImGuiUtil.DrawTableColumn( id ); ImGuiUtil.DrawTableColumn( id );