mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Handle ownership in gpose / cutscenes better.
This commit is contained in:
parent
882a59c1bf
commit
2b6275fe67
3 changed files with 29 additions and 29 deletions
|
|
@ -109,8 +109,10 @@ public partial class ActorManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 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, bool check = true)
|
public unsafe ActorIdentifier FromObject(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* actor,
|
||||||
|
out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner, bool check = true)
|
||||||
{
|
{
|
||||||
|
owner = null;
|
||||||
if (actor == null)
|
if (actor == null)
|
||||||
return ActorIdentifier.Invalid;
|
return ActorIdentifier.Invalid;
|
||||||
|
|
||||||
|
|
@ -136,13 +138,13 @@ public partial class ActorManager
|
||||||
var nameId = actor->DataID == 952 ? 780 : ((Character*)actor)->NameID;
|
var nameId = actor->DataID == 952 ? 780 : ((Character*)actor)->NameID;
|
||||||
if (ownerId != 0xE0000000)
|
if (ownerId != 0xE0000000)
|
||||||
{
|
{
|
||||||
var owner = (Character*)HandleCutscene(
|
owner = HandleCutscene(
|
||||||
(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(_objects.SearchById(ownerId)?.Address ?? IntPtr.Zero));
|
(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(_objects.SearchById(ownerId)?.Address ?? IntPtr.Zero));
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
return ActorIdentifier.Invalid;
|
return ActorIdentifier.Invalid;
|
||||||
|
|
||||||
var name = new ByteString(owner->GameObject.Name);
|
var name = new ByteString(owner->Name);
|
||||||
var homeWorld = owner->HomeWorld;
|
var homeWorld = ((Character*)owner)->HomeWorld;
|
||||||
return check
|
return check
|
||||||
? CreateOwned(name, homeWorld, ObjectKind.BattleNpc, nameId)
|
? CreateOwned(name, homeWorld, ObjectKind.BattleNpc, nameId)
|
||||||
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, ObjectKind.BattleNpc, nameId);
|
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, ObjectKind.BattleNpc, nameId);
|
||||||
|
|
@ -183,16 +185,18 @@ public partial class ActorManager
|
||||||
case ObjectKind.Companion:
|
case ObjectKind.Companion:
|
||||||
case (ObjectKind)15: // TODO: CS Update
|
case (ObjectKind)15: // TODO: CS Update
|
||||||
{
|
{
|
||||||
var owner = (Character*)HandleCutscene(
|
owner = HandleCutscene(
|
||||||
(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_objects.GetObjectAddress(actor->ObjectIndex - 1));
|
(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)_objects.GetObjectAddress(actor->ObjectIndex - 1));
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
return ActorIdentifier.Invalid;
|
return ActorIdentifier.Invalid;
|
||||||
|
|
||||||
var dataId = GetCompanionId(actor, &owner->GameObject);
|
var dataId = GetCompanionId(actor, owner);
|
||||||
|
var name = new ByteString(owner->Name);
|
||||||
|
var homeWorld = ((Character*)owner)->HomeWorld;
|
||||||
|
var kind = (ObjectKind)actor->ObjectKind;
|
||||||
return check
|
return check
|
||||||
? CreateOwned(new ByteString(owner->GameObject.Name), owner->HomeWorld, (ObjectKind)actor->ObjectKind, dataId)
|
? CreateOwned(name, homeWorld, kind, dataId)
|
||||||
: CreateIndividualUnchecked(IdentifierType.Owned, new ByteString(owner->GameObject.Name), owner->HomeWorld,
|
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, kind, dataId);
|
||||||
(ObjectKind)actor->ObjectKind, dataId);
|
|
||||||
}
|
}
|
||||||
case ObjectKind.Retainer:
|
case ObjectKind.Retainer:
|
||||||
{
|
{
|
||||||
|
|
@ -225,8 +229,12 @@ public partial class ActorManager
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe ActorIdentifier FromObject(GameObject? actor, out FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* owner,
|
||||||
|
bool check = true)
|
||||||
|
=> FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero), out owner, check);
|
||||||
|
|
||||||
public unsafe ActorIdentifier FromObject(GameObject? actor, bool check = true)
|
public unsafe ActorIdentifier FromObject(GameObject? actor, bool check = true)
|
||||||
=> FromObject((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)(actor?.Address ?? IntPtr.Zero), check);
|
=> FromObject(actor, out _, 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
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,12 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
||||||
public bool TryGetCollection( ActorIdentifier identifier, [NotNullWhen( true )] out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
public bool TryGetCollection( ActorIdentifier identifier, [NotNullWhen( true )] out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
||||||
{
|
{
|
||||||
specialIdentifier = ActorIdentifier.Invalid;
|
specialIdentifier = ActorIdentifier.Invalid;
|
||||||
|
if( Count == 0 )
|
||||||
|
{
|
||||||
|
collection = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
switch( identifier.Type )
|
switch( identifier.Type )
|
||||||
{
|
{
|
||||||
case IdentifierType.Player: return CheckWorlds( identifier, out collection );
|
case IdentifierType.Player: return CheckWorlds( identifier, out collection );
|
||||||
|
|
@ -94,7 +100,7 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
||||||
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection, out specialIdentifier );
|
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection, out specialIdentifier );
|
||||||
|
|
||||||
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
||||||
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection, out specialIdentifier );
|
=> TryGetCollection( _actorManager.FromObject( gameObject, out _, false ), out collection, out specialIdentifier );
|
||||||
|
|
||||||
private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection )
|
private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@ public unsafe partial class PathResolver
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var identifier = Penumbra.Actors.FromObject( gameObject, false );
|
var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, false );
|
||||||
var collection = CollectionByIdentifier( identifier, out var specialIdentifier )
|
var collection = CollectionByIdentifier( identifier, out var specialIdentifier )
|
||||||
?? CheckYourself( identifier.Type == IdentifierType.Special ? specialIdentifier : identifier, gameObject )
|
?? CheckYourself( identifier.Type == IdentifierType.Special ? specialIdentifier : identifier, gameObject )
|
||||||
?? CollectionByAttributes( gameObject )
|
?? CollectionByAttributes( gameObject )
|
||||||
?? CheckOwnedCollection( identifier, gameObject )
|
?? CheckOwnedCollection( identifier, owner )
|
||||||
?? Penumbra.CollectionManager.Default;
|
?? Penumbra.CollectionManager.Default;
|
||||||
return IdentifiedCache.Set( collection, identifier, gameObject );
|
return IdentifiedCache.Set( collection, identifier, gameObject );
|
||||||
}
|
}
|
||||||
|
|
@ -124,23 +124,9 @@ public unsafe partial class PathResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the collection applying to the owner if it is available.
|
// Get the collection applying to the owner if it is available.
|
||||||
private static ModCollection? CheckOwnedCollection( ActorIdentifier identifier, GameObject* obj )
|
private static ModCollection? CheckOwnedCollection( ActorIdentifier identifier, GameObject* owner )
|
||||||
{
|
{
|
||||||
if( identifier.Type != IdentifierType.Owned || !Penumbra.Config.UseOwnerNameForCharacterCollection )
|
if( identifier.Type != IdentifierType.Owned || !Penumbra.Config.UseOwnerNameForCharacterCollection || owner == null )
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var owner = identifier.Kind switch
|
|
||||||
{
|
|
||||||
ObjectKind.BattleNpc when obj->OwnerID != 0xE0000000 => ( GameObject* )( Dalamud.Objects.SearchById( obj->OwnerID )?.Address ?? IntPtr.Zero ),
|
|
||||||
ObjectKind.MountType when obj->ObjectIndex % 2 == 1 => ( GameObject* )Dalamud.Objects.GetObjectAddress( obj->ObjectIndex - 1 ),
|
|
||||||
ObjectKind.Companion when obj->ObjectIndex % 2 == 1 => ( GameObject* )Dalamud.Objects.GetObjectAddress( obj->ObjectIndex - 1 ),
|
|
||||||
( ObjectKind )15 when obj->ObjectIndex % 2 == 1 => ( GameObject* )Dalamud.Objects.GetObjectAddress( obj->ObjectIndex - 1 ), // TODO: CS Update
|
|
||||||
_ => null,
|
|
||||||
};
|
|
||||||
|
|
||||||
if( owner == null )
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue