mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Rework special actor identification again.
This commit is contained in:
parent
63a22198aa
commit
9af7e9d948
5 changed files with 55 additions and 37 deletions
|
|
@ -121,7 +121,8 @@ public partial class ActorManager
|
||||||
if (idx is >= (ushort)SpecialActor.CharacterScreen and <= (ushort)SpecialActor.Portrait)
|
if (idx is >= (ushort)SpecialActor.CharacterScreen and <= (ushort)SpecialActor.Portrait)
|
||||||
return CreateIndividualUnchecked(IdentifierType.Special, ByteString.Empty, idx, ObjectKind.None, uint.MaxValue);
|
return CreateIndividualUnchecked(IdentifierType.Special, ByteString.Empty, idx, ObjectKind.None, uint.MaxValue);
|
||||||
|
|
||||||
switch ((ObjectKind)actor->ObjectKind)
|
var kind = (ObjectKind)actor->ObjectKind;
|
||||||
|
switch (kind)
|
||||||
{
|
{
|
||||||
case ObjectKind.Player:
|
case ObjectKind.Player:
|
||||||
{
|
{
|
||||||
|
|
@ -193,7 +194,6 @@ public partial class ActorManager
|
||||||
var dataId = GetCompanionId(actor, owner);
|
var dataId = GetCompanionId(actor, owner);
|
||||||
var name = new ByteString(owner->Name);
|
var name = new ByteString(owner->Name);
|
||||||
var homeWorld = ((Character*)owner)->HomeWorld;
|
var homeWorld = ((Character*)owner)->HomeWorld;
|
||||||
var kind = (ObjectKind)actor->ObjectKind;
|
|
||||||
return check
|
return check
|
||||||
? CreateOwned(name, homeWorld, kind, dataId)
|
? CreateOwned(name, homeWorld, kind, dataId)
|
||||||
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, kind, dataId);
|
: CreateIndividualUnchecked(IdentifierType.Owned, name, homeWorld, kind, dataId);
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
public (string, bool) GetCharacterCollection( string characterName, ushort worldId )
|
public (string, bool) GetCharacterCollection( string characterName, ushort worldId )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
return Penumbra.CollectionManager.Individuals.TryGetCollection( NameToIdentifier( characterName, worldId ), out var collection, out _ )
|
return Penumbra.CollectionManager.Individuals.TryGetCollection( NameToIdentifier( characterName, worldId ), out var collection )
|
||||||
? ( collection.Name, true )
|
? ( collection.Name, true )
|
||||||
: ( Penumbra.CollectionManager.Default.Name, false );
|
: ( Penumbra.CollectionManager.Default.Name, false );
|
||||||
}
|
}
|
||||||
|
|
@ -807,7 +807,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
var identifier = NameToIdentifier( characterName, worldId );
|
var identifier = NameToIdentifier( characterName, worldId );
|
||||||
var collection = Penumbra.TempMods.Collections.TryGetCollection( identifier, out var c, out _ )
|
var collection = Penumbra.TempMods.Collections.TryGetCollection( identifier, out var c )
|
||||||
? c
|
? c
|
||||||
: Penumbra.CollectionManager.Individual( identifier );
|
: Penumbra.CollectionManager.Individual( identifier );
|
||||||
var set = collection.MetaCache?.Manipulations.ToArray() ?? Array.Empty< MetaManipulation >();
|
var set = collection.MetaCache?.Manipulations.ToArray() ?? Array.Empty< MetaManipulation >();
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public partial class ModCollection
|
||||||
public readonly IndividualCollections Individuals = new(Penumbra.Actors);
|
public readonly IndividualCollections Individuals = new(Penumbra.Actors);
|
||||||
|
|
||||||
public ModCollection Individual( ActorIdentifier identifier )
|
public ModCollection Individual( ActorIdentifier identifier )
|
||||||
=> Individuals.TryGetCollection( identifier, out var c, out _ ) ? c : Default;
|
=> Individuals.TryGetCollection( identifier, out var c ) ? c : Default;
|
||||||
|
|
||||||
// Special Collections
|
// Special Collections
|
||||||
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues< CollectionType >().Length - 4];
|
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues< CollectionType >().Length - 4];
|
||||||
|
|
@ -64,7 +64,7 @@ public partial class ModCollection
|
||||||
CollectionType.Default => Default,
|
CollectionType.Default => Default,
|
||||||
CollectionType.Interface => Interface,
|
CollectionType.Interface => Interface,
|
||||||
CollectionType.Current => Current,
|
CollectionType.Current => Current,
|
||||||
CollectionType.Individual => identifier.IsValid ? Individuals.TryGetCollection( identifier, out var c, out _ ) ? c : null : null,
|
CollectionType.Individual => identifier.IsValid ? Individuals.TryGetCollection( identifier, out var c ) ? c : null : null,
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,8 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
||||||
public (string DisplayName, ModCollection Collection) this[ int index ]
|
public (string DisplayName, ModCollection Collection) this[ int index ]
|
||||||
=> ( _assignments[ index ].DisplayName, _assignments[ index ].Collection );
|
=> ( _assignments[ index ].DisplayName, _assignments[ index ].Collection );
|
||||||
|
|
||||||
public bool TryGetCollection( ActorIdentifier identifier, [NotNullWhen( true )] out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
public bool TryGetCollection( ActorIdentifier identifier, [NotNullWhen( true )] out ModCollection? collection )
|
||||||
{
|
{
|
||||||
specialIdentifier = ActorIdentifier.Invalid;
|
|
||||||
if( Count == 0 )
|
if( Count == 0 )
|
||||||
{
|
{
|
||||||
collection = null;
|
collection = null;
|
||||||
|
|
@ -72,35 +71,53 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case IdentifierType.Npc: return _individuals.TryGetValue( identifier, out collection );
|
case IdentifierType.Npc: return _individuals.TryGetValue( identifier, out collection );
|
||||||
case IdentifierType.Special:
|
case IdentifierType.Special: return CheckWorlds( ConvertSpecialIdentifier( identifier ), out collection );
|
||||||
switch( identifier.Special )
|
|
||||||
{
|
|
||||||
case SpecialActor.CharacterScreen when Penumbra.Config.UseCharacterCollectionInMainWindow:
|
|
||||||
case SpecialActor.FittingRoom when Penumbra.Config.UseCharacterCollectionInTryOn:
|
|
||||||
case SpecialActor.DyePreview when Penumbra.Config.UseCharacterCollectionInTryOn:
|
|
||||||
case SpecialActor.Portrait when Penumbra.Config.UseCharacterCollectionsInCards:
|
|
||||||
return CheckWorlds( specialIdentifier = _actorManager.GetCurrentPlayer(), out collection );
|
|
||||||
case SpecialActor.ExamineScreen:
|
|
||||||
{
|
|
||||||
return CheckWorlds( specialIdentifier = _actorManager.GetInspectPlayer(), out collection! )
|
|
||||||
|| CheckWorlds( specialIdentifier = _actorManager.GetCardPlayer(), out collection! )
|
|
||||||
|| CheckWorlds( specialIdentifier = _actorManager.GetGlamourPlayer(), out collection! );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collection = null;
|
collection = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
public ActorIdentifier ConvertSpecialIdentifier( ActorIdentifier identifier )
|
||||||
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection, out specialIdentifier );
|
{
|
||||||
|
if( identifier.Type != IdentifierType.Special )
|
||||||
|
{
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
switch( identifier.Special )
|
||||||
=> TryGetCollection( _actorManager.FromObject( gameObject, out _, false ), out collection, out specialIdentifier );
|
{
|
||||||
|
case SpecialActor.CharacterScreen when Penumbra.Config.UseCharacterCollectionInMainWindow:
|
||||||
|
case SpecialActor.FittingRoom when Penumbra.Config.UseCharacterCollectionInTryOn:
|
||||||
|
case SpecialActor.DyePreview when Penumbra.Config.UseCharacterCollectionInTryOn:
|
||||||
|
case SpecialActor.Portrait when Penumbra.Config.UseCharacterCollectionsInCards:
|
||||||
|
return _actorManager.GetCurrentPlayer();
|
||||||
|
case SpecialActor.ExamineScreen:
|
||||||
|
{
|
||||||
|
identifier = _actorManager.GetInspectPlayer();
|
||||||
|
if( identifier.IsValid )
|
||||||
|
{
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
identifier = _actorManager.GetCardPlayer();
|
||||||
|
if( identifier.IsValid )
|
||||||
|
{
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _actorManager.GetGlamourPlayer();
|
||||||
|
}
|
||||||
|
default: return identifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection )
|
||||||
|
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection );
|
||||||
|
|
||||||
|
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection )
|
||||||
|
=> TryGetCollection( _actorManager.FromObject( gameObject, out _, false ), out collection );
|
||||||
|
|
||||||
private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection )
|
private bool CheckWorlds( ActorIdentifier identifier, out ModCollection? collection )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,9 @@ public unsafe partial class PathResolver
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, false );
|
var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, false );
|
||||||
var collection = CollectionByIdentifier( identifier, out var specialIdentifier )
|
identifier = Penumbra.CollectionManager.Individuals.ConvertSpecialIdentifier( identifier );
|
||||||
?? CheckYourself( identifier.Type == IdentifierType.Special ? specialIdentifier : identifier, gameObject )
|
var collection = CollectionByIdentifier( identifier )
|
||||||
|
?? CheckYourself( identifier, gameObject )
|
||||||
?? CollectionByAttributes( gameObject )
|
?? CollectionByAttributes( gameObject )
|
||||||
?? CheckOwnedCollection( identifier, owner )
|
?? CheckOwnedCollection( identifier, owner )
|
||||||
?? Penumbra.CollectionManager.Default;
|
?? Penumbra.CollectionManager.Default;
|
||||||
|
|
@ -71,16 +72,16 @@ public unsafe partial class PathResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = Penumbra.Actors.GetCurrentPlayer();
|
var player = Penumbra.Actors.GetCurrentPlayer();
|
||||||
return CollectionByIdentifier( player, out _ )
|
return CollectionByIdentifier( player )
|
||||||
?? CheckYourself( player, gameObject )
|
?? CheckYourself( player, gameObject )
|
||||||
?? CollectionByAttributes( gameObject )
|
?? CollectionByAttributes( gameObject )
|
||||||
?? Penumbra.CollectionManager.Default;
|
?? Penumbra.CollectionManager.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check both temporary and permanent character collections. Temporary first.
|
// Check both temporary and permanent character collections. Temporary first.
|
||||||
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier, out ActorIdentifier specialIdentifier )
|
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier )
|
||||||
=> Penumbra.TempMods.Collections.TryGetCollection( identifier, out var collection, out specialIdentifier )
|
=> Penumbra.TempMods.Collections.TryGetCollection( identifier, out var collection )
|
||||||
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection, out specialIdentifier )
|
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection )
|
||||||
? collection
|
? collection
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
|
@ -143,7 +144,7 @@ public unsafe partial class PathResolver
|
||||||
{
|
{
|
||||||
var sheet = gameData.GetExcelSheet< ModelChara >()!;
|
var sheet = gameData.GetExcelSheet< ModelChara >()!;
|
||||||
var ret = new BitArray( ( int )sheet.RowCount, false );
|
var ret = new BitArray( ( int )sheet.RowCount, false );
|
||||||
foreach( var (row, idx) in sheet.WithIndex().Where( p => p.Value.Type == ( byte )CharacterBase.ModelType.Human ) )
|
foreach( var (_, idx) in sheet.WithIndex().Where( p => p.Value.Type == ( byte )CharacterBase.ModelType.Human ) )
|
||||||
{
|
{
|
||||||
ret[ idx ] = true;
|
ret[ idx ] = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue