mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +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)
|
||||
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:
|
||||
{
|
||||
|
|
@ -193,7 +194,6 @@ public partial class ActorManager
|
|||
var dataId = GetCompanionId(actor, owner);
|
||||
var name = new ByteString(owner->Name);
|
||||
var homeWorld = ((Character*)owner)->HomeWorld;
|
||||
var kind = (ObjectKind)actor->ObjectKind;
|
||||
return check
|
||||
? CreateOwned(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 )
|
||||
{
|
||||
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 )
|
||||
: ( Penumbra.CollectionManager.Default.Name, false );
|
||||
}
|
||||
|
|
@ -807,7 +807,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
{
|
||||
CheckInitialized();
|
||||
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
|
||||
: Penumbra.CollectionManager.Individual( identifier );
|
||||
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 ModCollection Individual( ActorIdentifier identifier )
|
||||
=> Individuals.TryGetCollection( identifier, out var c, out _ ) ? c : Default;
|
||||
=> Individuals.TryGetCollection( identifier, out var c ) ? c : Default;
|
||||
|
||||
// Special Collections
|
||||
private readonly ModCollection?[] _specialCollections = new ModCollection?[Enum.GetValues< CollectionType >().Length - 4];
|
||||
|
|
@ -64,7 +64,7 @@ public partial class ModCollection
|
|||
CollectionType.Default => Default,
|
||||
CollectionType.Interface => Interface,
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
|||
public (string DisplayName, ModCollection Collection) this[ int index ]
|
||||
=> ( _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 )
|
||||
{
|
||||
collection = null;
|
||||
|
|
@ -72,35 +71,53 @@ public sealed partial class IndividualCollections : IReadOnlyList< (string Displ
|
|||
|
||||
return false;
|
||||
}
|
||||
case IdentifierType.Npc: return _individuals.TryGetValue( identifier, out collection );
|
||||
case IdentifierType.Special:
|
||||
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;
|
||||
case IdentifierType.Npc: return _individuals.TryGetValue( identifier, out collection );
|
||||
case IdentifierType.Special: return CheckWorlds( ConvertSpecialIdentifier( identifier ), out collection );
|
||||
}
|
||||
|
||||
collection = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetCollection( GameObject? gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
||||
=> TryGetCollection( _actorManager.FromObject( gameObject, false ), out collection, out specialIdentifier );
|
||||
public ActorIdentifier ConvertSpecialIdentifier( ActorIdentifier identifier )
|
||||
{
|
||||
if( identifier.Type != IdentifierType.Special )
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public unsafe bool TryGetCollection( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection, out ActorIdentifier specialIdentifier )
|
||||
=> TryGetCollection( _actorManager.FromObject( gameObject, out _, false ), out collection, out specialIdentifier );
|
||||
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 _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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,8 +44,9 @@ public unsafe partial class PathResolver
|
|||
else
|
||||
{
|
||||
var identifier = Penumbra.Actors.FromObject( gameObject, out var owner, false );
|
||||
var collection = CollectionByIdentifier( identifier, out var specialIdentifier )
|
||||
?? CheckYourself( identifier.Type == IdentifierType.Special ? specialIdentifier : identifier, gameObject )
|
||||
identifier = Penumbra.CollectionManager.Individuals.ConvertSpecialIdentifier( identifier );
|
||||
var collection = CollectionByIdentifier( identifier )
|
||||
?? CheckYourself( identifier, gameObject )
|
||||
?? CollectionByAttributes( gameObject )
|
||||
?? CheckOwnedCollection( identifier, owner )
|
||||
?? Penumbra.CollectionManager.Default;
|
||||
|
|
@ -71,16 +72,16 @@ public unsafe partial class PathResolver
|
|||
}
|
||||
|
||||
var player = Penumbra.Actors.GetCurrentPlayer();
|
||||
return CollectionByIdentifier( player, out _ )
|
||||
return CollectionByIdentifier( player )
|
||||
?? CheckYourself( player, gameObject )
|
||||
?? CollectionByAttributes( gameObject )
|
||||
?? Penumbra.CollectionManager.Default;
|
||||
}
|
||||
|
||||
// Check both temporary and permanent character collections. Temporary first.
|
||||
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier, out ActorIdentifier specialIdentifier )
|
||||
=> Penumbra.TempMods.Collections.TryGetCollection( identifier, out var collection, out specialIdentifier )
|
||||
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection, out specialIdentifier )
|
||||
private static ModCollection? CollectionByIdentifier( ActorIdentifier identifier )
|
||||
=> Penumbra.TempMods.Collections.TryGetCollection( identifier, out var collection )
|
||||
|| Penumbra.CollectionManager.Individuals.TryGetCollection( identifier, out collection )
|
||||
? collection
|
||||
: null;
|
||||
|
||||
|
|
@ -143,7 +144,7 @@ public unsafe partial class PathResolver
|
|||
{
|
||||
var sheet = gameData.GetExcelSheet< ModelChara >()!;
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue