More renaming...

This commit is contained in:
Ottermandias 2023-03-23 20:42:34 +01:00
parent 7bad131542
commit f38a252295
55 changed files with 423 additions and 407 deletions

View file

@ -3,7 +3,7 @@ using Lumina.Data;
using Newtonsoft.Json;
using OtterGui;
using Penumbra.Collections;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
@ -17,7 +17,7 @@ using System.Runtime.CompilerServices;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using Penumbra.Api.Enums;
using Penumbra.GameData.Actors;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Services;

View file

@ -13,6 +13,7 @@ using Penumbra.Interop;
using Penumbra.Interop.Services;
using Penumbra.Services;
using Penumbra.Util;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
namespace Penumbra.Collections;

View file

@ -9,9 +9,11 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using Penumbra.Interop;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
namespace Penumbra.Collections;
@ -151,7 +153,7 @@ public partial class ModCollection
}
}
public void SetMetaFile(Interop.Structs.CharacterUtility.Index idx)
public void SetMetaFile(MetaIndex idx)
{
if (_cache == null)
Penumbra.CharacterUtility.ResetResource(idx);
@ -160,23 +162,23 @@ public partial class ModCollection
}
// Used for short periods of changed files.
public CharacterUtility.List.MetaReverter TemporarilySetEqdpFile(GenderRace genderRace, bool accessory)
public CharacterUtility.MetaList.MetaReverter TemporarilySetEqdpFile(GenderRace genderRace, bool accessory)
=> _cache?.MetaManipulations.TemporarilySetEqdpFile(genderRace, accessory)
?? Penumbra.CharacterUtility.TemporarilyResetResource(Interop.Structs.CharacterUtility.EqdpIdx(genderRace, accessory));
?? Penumbra.CharacterUtility.TemporarilyResetResource(Interop.Structs.CharacterUtilityData.EqdpIdx(genderRace, accessory));
public CharacterUtility.List.MetaReverter TemporarilySetEqpFile()
public CharacterUtility.MetaList.MetaReverter TemporarilySetEqpFile()
=> _cache?.MetaManipulations.TemporarilySetEqpFile()
?? Penumbra.CharacterUtility.TemporarilyResetResource(Interop.Structs.CharacterUtility.Index.Eqp);
?? Penumbra.CharacterUtility.TemporarilyResetResource(MetaIndex.Eqp);
public CharacterUtility.List.MetaReverter TemporarilySetGmpFile()
public CharacterUtility.MetaList.MetaReverter TemporarilySetGmpFile()
=> _cache?.MetaManipulations.TemporarilySetGmpFile()
?? Penumbra.CharacterUtility.TemporarilyResetResource(Interop.Structs.CharacterUtility.Index.Gmp);
?? Penumbra.CharacterUtility.TemporarilyResetResource(MetaIndex.Gmp);
public CharacterUtility.List.MetaReverter TemporarilySetCmpFile()
public CharacterUtility.MetaList.MetaReverter TemporarilySetCmpFile()
=> _cache?.MetaManipulations.TemporarilySetCmpFile()
?? Penumbra.CharacterUtility.TemporarilyResetResource(Interop.Structs.CharacterUtility.Index.HumanCmp);
?? Penumbra.CharacterUtility.TemporarilyResetResource(MetaIndex.HumanCmp);
public CharacterUtility.List.MetaReverter TemporarilySetEstFile(EstManipulation.EstType type)
public CharacterUtility.MetaList.MetaReverter TemporarilySetEstFile(EstManipulation.EstType type)
=> _cache?.MetaManipulations.TemporarilySetEstFile(type)
?? Penumbra.CharacterUtility.TemporarilyResetResource((Interop.Structs.CharacterUtility.Index)type);
?? Penumbra.CharacterUtility.TemporarilyResetResource((MetaIndex)type);
}

View file

@ -9,6 +9,7 @@ using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.GameData.Actors;
using Penumbra.Interop;
using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI;

View file

@ -1,66 +0,0 @@
using System;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.String.Classes;
namespace Penumbra.Interop;
public unsafe partial class CharacterUtility
{
public sealed class DecalReverter : IDisposable
{
public static readonly Utf8GamePath DecalPath =
Utf8GamePath.FromSpan("chara/common/texture/decal_equip/_stigma.tex"u8, out var p) ? p : Utf8GamePath.Empty;
public static readonly Utf8GamePath TransparentPath =
Utf8GamePath.FromSpan("chara/common/texture/transparent.tex"u8, out var p) ? p : Utf8GamePath.Empty;
private readonly Structs.TextureResourceHandle* _decal;
private readonly Structs.TextureResourceHandle* _transparent;
public DecalReverter( ResourceService resources, ModCollection? collection, bool doDecal )
{
var ptr = Penumbra.CharacterUtility.Address;
_decal = null;
_transparent = null;
if( doDecal )
{
var decalPath = collection?.ResolvePath( DecalPath )?.InternalName ?? DecalPath.Path;
var decalHandle = resources.GetResource( ResourceCategory.Chara, ResourceType.Tex, decalPath );
_decal = ( Structs.TextureResourceHandle* )decalHandle;
if( _decal != null )
{
ptr->DecalTexResource = _decal;
}
}
else
{
var transparentPath = collection?.ResolvePath( TransparentPath )?.InternalName ?? TransparentPath.Path;
var transparentHandle = resources.GetResource(ResourceCategory.Chara, ResourceType.Tex, transparentPath);
_transparent = ( Structs.TextureResourceHandle* )transparentHandle;
if( _transparent != null )
{
ptr->TransparentTexResource = _transparent;
}
}
}
public void Dispose()
{
var ptr = Penumbra.CharacterUtility.Address;
if( _decal != null )
{
ptr->DecalTexResource = ( Structs.TextureResourceHandle* )Penumbra.CharacterUtility._defaultDecalResource;
--_decal->Handle.RefCount;
}
if( _transparent != null )
{
ptr->TransparentTexResource = ( Structs.TextureResourceHandle* )Penumbra.CharacterUtility._defaultTransparentResource;
--_transparent->Handle.RefCount;
}
}
}
}

View file

@ -1,166 +0,0 @@
using System;
using System.Collections.Generic;
namespace Penumbra.Interop;
public unsafe partial class CharacterUtility
{
public class List : IDisposable
{
private readonly LinkedList< MetaReverter > _entries = new();
public readonly InternalIndex Index;
public readonly Structs.CharacterUtility.Index GlobalIndex;
public IReadOnlyCollection< MetaReverter > Entries
=> _entries;
private IntPtr _defaultResourceData = IntPtr.Zero;
private int _defaultResourceSize = 0;
public bool Ready { get; private set; } = false;
public List( InternalIndex index )
{
Index = index;
GlobalIndex = RelevantIndices[ index.Value ];
}
public void SetDefaultResource( IntPtr data, int size )
{
if( !Ready )
{
_defaultResourceData = data;
_defaultResourceSize = size;
Ready = _defaultResourceData != IntPtr.Zero && size != 0;
if( _entries.Count > 0 )
{
var first = _entries.First!.Value;
SetResource( first.Data, first.Length );
}
}
}
public (IntPtr Address, int Size) DefaultResource
=> ( _defaultResourceData, _defaultResourceSize );
public MetaReverter TemporarilySetResource( IntPtr data, int length )
{
Penumbra.Log.Verbose( $"Temporarily set resource {GlobalIndex} to 0x{( ulong )data:X} ({length} bytes)." );
var reverter = new MetaReverter( this, data, length );
_entries.AddFirst( reverter );
SetResourceInternal( data, length );
return reverter;
}
public MetaReverter TemporarilyResetResource()
{
Penumbra.Log.Verbose(
$"Temporarily reset resource {GlobalIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes)." );
var reverter = new MetaReverter( this );
_entries.AddFirst( reverter );
ResetResourceInternal();
return reverter;
}
public void SetResource( IntPtr data, int length )
{
Penumbra.Log.Verbose( $"Set resource {GlobalIndex} to 0x{( ulong )data:X} ({length} bytes)." );
SetResourceInternal( data, length );
}
public void ResetResource()
{
Penumbra.Log.Verbose( $"Reset resource {GlobalIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes)." );
ResetResourceInternal();
}
// Set the currently stored data of this resource to new values.
private void SetResourceInternal( IntPtr data, int length )
{
if( Ready )
{
var resource = Penumbra.CharacterUtility.Address->Resource( GlobalIndex );
resource->SetData( data, length );
}
}
// Reset the currently stored data of this resource to its default values.
private void ResetResourceInternal()
=> SetResourceInternal( _defaultResourceData, _defaultResourceSize );
private void SetResourceToDefaultCollection()
=> Penumbra.CollectionManager.Default.SetMetaFile( GlobalIndex );
public void Dispose()
{
if( _entries.Count > 0 )
{
foreach( var entry in _entries )
{
entry.Disposed = true;
}
_entries.Clear();
}
ResetResourceInternal();
}
public sealed class MetaReverter : IDisposable
{
public readonly List List;
public readonly IntPtr Data;
public readonly int Length;
public readonly bool Resetter;
public bool Disposed;
public MetaReverter( List list, IntPtr data, int length )
{
List = list;
Data = data;
Length = length;
}
public MetaReverter( List list )
{
List = list;
Data = IntPtr.Zero;
Length = 0;
Resetter = true;
}
public void Dispose()
{
if( !Disposed )
{
var list = List._entries;
var wasCurrent = ReferenceEquals( this, list.First?.Value );
list.Remove( this );
if( !wasCurrent )
{
return;
}
if( list.Count == 0 )
{
List.SetResourceToDefaultCollection();
}
else
{
var next = list.First!.Value;
if( next.Resetter )
{
List.ResetResourceInternal();
}
else
{
List.SetResourceInternal( next.Data, next.Length );
}
}
Disposed = true;
}
}
}
}
}

View file

@ -12,7 +12,7 @@ using Penumbra.String.Classes;
using Penumbra.Util;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public unsafe class AnimationHookService : IDisposable
{

View file

@ -17,7 +17,7 @@ using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public unsafe class CollectionResolver
{

View file

@ -7,7 +7,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character;
using Penumbra.GameData.Actors;
using Penumbra.Interop.Services;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public class CutsceneService : IDisposable
{

View file

@ -14,7 +14,7 @@ using Penumbra.Interop.Services;
using Penumbra.String.Classes;
using Object = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.Object;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public class DrawObjectState : IDisposable, IReadOnlyDictionary<nint, (nint, bool)>
{

View file

@ -8,7 +8,7 @@ using OtterGui.Classes;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Services;
using Penumbra.Services;
using Penumbra.String.Classes;
@ -16,7 +16,7 @@ using Penumbra.Util;
using ObjectType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.ObjectType;
using static Penumbra.GameData.Enums.GenderRace;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
// State: 6.35
// GetSlotEqpData seems to be the only function using the EQP table.
@ -45,23 +45,25 @@ public unsafe class MetaState : IDisposable
[Signature(Sigs.HumanVTable, ScanType = ScanType.StaticAddress)]
private readonly nint* _humanVTable = null!;
private readonly CommunicatorService _communicator;
private readonly PerformanceTracker _performance;
private readonly CollectionResolver _collectionResolver;
private readonly ResourceService _resources;
private readonly GameEventManager _gameEventManager;
private readonly CommunicatorService _communicator;
private readonly PerformanceTracker _performance;
private readonly CollectionResolver _collectionResolver;
private readonly ResourceService _resources;
private readonly GameEventManager _gameEventManager;
private readonly Services.CharacterUtility _characterUtility;
private ResolveData _lastCreatedCollection = ResolveData.Invalid;
private DisposableContainer _characterBaseCreateMetaChanges = DisposableContainer.Empty;
public MetaState(PerformanceTracker performance, CommunicatorService communicator, CollectionResolver collectionResolver,
ResourceService resources, GameEventManager gameEventManager)
ResourceService resources, GameEventManager gameEventManager, Services.CharacterUtility characterUtility)
{
_performance = performance;
_communicator = communicator;
_collectionResolver = collectionResolver;
_resources = resources;
_gameEventManager = gameEventManager;
_characterUtility = characterUtility;
SignatureHelper.Initialise(this);
_onModelLoadCompleteHook = Hook<OnModelLoadCompleteDelegate>.FromAddress(_humanVTable[58], OnModelLoadCompleteDetour);
_getEqpIndirectHook.Enable();
@ -86,7 +88,7 @@ public unsafe class MetaState : IDisposable
resolveData = ResolveData.Invalid;
return false;
}
}
public static DisposableContainer ResolveEqdpData(ModCollection collection, GenderRace race, bool equipment, bool accessory)
{
@ -104,7 +106,7 @@ public unsafe class MetaState : IDisposable
}
public static GenderRace GetHumanGenderRace(nint human)
=> (GenderRace)((Human*)human)->RaceSexId;
=> (GenderRace)((Human*)human)->RaceSexId;
public void Dispose()
{
@ -125,7 +127,7 @@ public unsafe class MetaState : IDisposable
_communicator.CreatingCharacterBase.Invoke(_lastCreatedCollection.AssociatedGameObject,
_lastCreatedCollection.ModCollection.Name, (nint)(&modelCharaId), customize, equipData);
var decal = new CharacterUtility.DecalReverter(_resources, _lastCreatedCollection.ModCollection, UsesDecal(modelCharaId, equipData));
var decal = new DecalReverter(_characterUtility, _resources, _lastCreatedCollection.ModCollection, UsesDecal(modelCharaId, equipData));
var cmp = _lastCreatedCollection.ModCollection.TemporarilySetCmpFile();
_characterBaseCreateMetaChanges.Dispose(); // Should always be empty.
_characterBaseCreateMetaChanges = new DisposableContainer(decal, cmp);
@ -252,7 +254,7 @@ public unsafe class MetaState : IDisposable
var resolveData = _collectionResolver.IdentifyCollection((DrawObject*)human, true);
using var cmp = resolveData.ModCollection.TemporarilySetCmpFile();
using var decals =
new CharacterUtility.DecalReverter(_resources, resolveData.ModCollection, UsesDecal(0, data));
new DecalReverter(_characterUtility, _resources, resolveData.ModCollection, UsesDecal(0, data));
var ret = _changeCustomize.Original(human, data, skipEquipment);
_inChangeCustomize = false;
return ret;

View file

@ -4,13 +4,13 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Api;
using Penumbra.Collections;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Util;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public class PathResolver : IDisposable
{

View file

@ -7,7 +7,7 @@ using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.String;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public unsafe class PathState : IDisposable
{

View file

@ -6,7 +6,7 @@ using OtterGui.Classes;
using Penumbra.Collections;
using Penumbra.Meta.Manipulations;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
public unsafe class ResolvePathHooks : IDisposable
{

View file

@ -8,14 +8,14 @@ using Dalamud.Utility.Signatures;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Util;
namespace Penumbra.Interop.Resolver;
namespace Penumbra.Interop.PathResolving;
/// <summary>
/// Materials and avfx do contain their own paths to textures and shader packages or atex respectively.

View file

@ -7,7 +7,7 @@ using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.String.Functions;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
/// <summary>
/// To allow XIV to load files of arbitrary path length,

View file

@ -8,7 +8,7 @@ using Penumbra.GameData;
using Penumbra.Interop.Structs;
using Penumbra.Util;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
public unsafe class FileReadService : IDisposable
{

View file

@ -8,7 +8,7 @@ using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
public unsafe class ResourceLoader : IDisposable
{

View file

@ -8,7 +8,7 @@ using FFXIVClientStructs.STD;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
public unsafe class ResourceManagerService
{

View file

@ -9,7 +9,7 @@ using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Util;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
public unsafe class ResourceService : IDisposable
{

View file

@ -7,7 +7,7 @@ using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
namespace Penumbra.Interop.ResourceLoading;
public unsafe class TexMdlService
{

View file

@ -6,7 +6,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Penumbra.GameData;
using Penumbra.GameData.Actors;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.PathResolving;
using Penumbra.Services;
namespace Penumbra.Interop.ResourceTree;

View file

@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using Penumbra.Interop.Structs;
namespace Penumbra.Interop.Services;
public unsafe partial class CharacterUtility
{
public class MetaList : IDisposable
{
private readonly LinkedList<MetaReverter> _entries = new();
public readonly InternalIndex Index;
public readonly MetaIndex GlobalMetaIndex;
public IReadOnlyCollection<MetaReverter> Entries
=> _entries;
private nint _defaultResourceData = nint.Zero;
private int _defaultResourceSize = 0;
public bool Ready { get; private set; } = false;
public MetaList(InternalIndex index)
{
Index = index;
GlobalMetaIndex = RelevantIndices[index.Value];
}
public void SetDefaultResource(nint data, int size)
{
if (Ready)
return;
_defaultResourceData = data;
_defaultResourceSize = size;
Ready = _defaultResourceData != nint.Zero && size != 0;
if (_entries.Count <= 0)
return;
var first = _entries.First!.Value;
SetResource(first.Data, first.Length);
}
public (nint Address, int Size) DefaultResource
=> (_defaultResourceData, _defaultResourceSize);
public MetaReverter TemporarilySetResource(nint data, int length)
{
#if false
Penumbra.Log.Verbose($"Temporarily set resource {GlobalMetaIndex} to 0x{(ulong)data:X} ({length} bytes).");
#endif
var reverter = new MetaReverter(this, data, length);
_entries.AddFirst(reverter);
SetResourceInternal(data, length);
return reverter;
}
public MetaReverter TemporarilyResetResource()
{
#if false
Penumbra.Log.Verbose(
$"Temporarily reset resource {GlobalMetaIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes).");
#endif
var reverter = new MetaReverter(this);
_entries.AddFirst(reverter);
ResetResourceInternal();
return reverter;
}
public void SetResource(nint data, int length)
{
#if false
Penumbra.Log.Verbose($"Set resource {GlobalMetaIndex} to 0x{(ulong)data:X} ({length} bytes).");
#endif
SetResourceInternal(data, length);
}
public void ResetResource()
{
#if false
Penumbra.Log.Verbose($"Reset resource {GlobalMetaIndex} to default at 0x{_defaultResourceData:X} ({_defaultResourceSize} bytes).");
#endif
ResetResourceInternal();
}
// Set the currently stored data of this resource to new values.
private void SetResourceInternal(nint data, int length)
{
if (!Ready)
return;
var resource = Penumbra.CharacterUtility.Address->Resource(GlobalMetaIndex);
resource->SetData(data, length);
}
// Reset the currently stored data of this resource to its default values.
private void ResetResourceInternal()
=> SetResourceInternal(_defaultResourceData, _defaultResourceSize);
private void SetResourceToDefaultCollection()
=> Penumbra.CollectionManager.Default.SetMetaFile(GlobalMetaIndex);
public void Dispose()
{
if (_entries.Count > 0)
{
foreach (var entry in _entries)
entry.Disposed = true;
_entries.Clear();
}
ResetResourceInternal();
}
public sealed class MetaReverter : IDisposable
{
public readonly MetaList MetaList;
public readonly nint Data;
public readonly int Length;
public readonly bool Resetter;
public bool Disposed;
public MetaReverter(MetaList metaList, nint data, int length)
{
MetaList = metaList;
Data = data;
Length = length;
}
public MetaReverter(MetaList metaList)
{
MetaList = metaList;
Data = nint.Zero;
Length = 0;
Resetter = true;
}
public void Dispose()
{
if (Disposed)
return;
var list = MetaList._entries;
var wasCurrent = ReferenceEquals(this, list.First?.Value);
list.Remove(this);
if (!wasCurrent)
return;
if (list.Count == 0)
{
MetaList.SetResourceToDefaultCollection();
}
else
{
var next = list.First!.Value;
if (next.Resetter)
MetaList.ResetResourceInternal();
else
MetaList.SetResourceInternal(next.Data, next.Length);
}
Disposed = true;
}
}
}
}

View file

@ -6,7 +6,7 @@ using Dalamud.Utility.Signatures;
using Penumbra.GameData;
using Penumbra.Interop.Structs;
namespace Penumbra.Interop;
namespace Penumbra.Interop.Services;
public unsafe partial class CharacterUtility : IDisposable
{
@ -16,7 +16,7 @@ public unsafe partial class CharacterUtility : IDisposable
[Signature(Sigs.CharacterUtility, ScanType = ScanType.StaticAddress)]
private readonly CharacterUtilityData** _characterUtilityAddress = null;
/// <summary> Only required for migration anymore. </summary>
/// <summary> Only required for migration anymore. </summary>
public delegate void LoadResources(CharacterUtilityData* address);
[Signature(Sigs.LoadCharacterResources)]
@ -30,12 +30,12 @@ public unsafe partial class CharacterUtility : IDisposable
public bool Ready { get; private set; }
public event Action LoadingFinished;
public IntPtr DefaultTransparentResource { get; private set; }
public IntPtr DefaultDecalResource { get; private set; }
public nint DefaultTransparentResource { get; private set; }
public nint DefaultDecalResource { get; private set; }
/// <summary>
/// <summary>
/// The relevant indices depend on which meta manipulations we allow for.
/// The defines are set in the project configuration.
/// The defines are set in the project configuration.
/// </summary>
public static readonly MetaIndex[]
RelevantIndices = Enum.GetValues<MetaIndex>();
@ -45,14 +45,14 @@ public unsafe partial class CharacterUtility : IDisposable
.Select(i => new InternalIndex(Array.IndexOf(RelevantIndices, (MetaIndex)i)))
.ToArray();
private readonly List[] _lists = Enumerable.Range(0, RelevantIndices.Length)
.Select(idx => new List(new InternalIndex(idx)))
private readonly MetaList[] _lists = Enumerable.Range(0, RelevantIndices.Length)
.Select(idx => new MetaList(new InternalIndex(idx)))
.ToArray();
public IReadOnlyList<List> Lists
public IReadOnlyList<MetaList> Lists
=> _lists;
public (IntPtr Address, int Size) DefaultResource(InternalIndex idx)
public (nint Address, int Size) DefaultResource(InternalIndex idx)
=> _lists[idx.Value].DefaultResource;
private readonly Framework _framework;
@ -67,7 +67,7 @@ public unsafe partial class CharacterUtility : IDisposable
_framework.Update += LoadDefaultResources;
}
/// <summary> We store the default data of the resources so we can always restore them. </summary>
/// <summary> We store the default data of the resources so we can always restore them. </summary>
private void LoadDefaultResources(object _)
{
if (Address == null)
@ -86,16 +86,16 @@ public unsafe partial class CharacterUtility : IDisposable
anyMissing |= !_lists[i].Ready;
}
if (DefaultTransparentResource == IntPtr.Zero)
if (DefaultTransparentResource == nint.Zero)
{
DefaultTransparentResource = (IntPtr)Address->TransparentTexResource;
anyMissing |= DefaultTransparentResource == IntPtr.Zero;
DefaultTransparentResource = (nint)Address->TransparentTexResource;
anyMissing |= DefaultTransparentResource == nint.Zero;
}
if (DefaultDecalResource == IntPtr.Zero)
if (DefaultDecalResource == nint.Zero)
{
DefaultDecalResource = (IntPtr)Address->DecalTexResource;
anyMissing |= DefaultDecalResource == IntPtr.Zero;
DefaultDecalResource = (nint)Address->DecalTexResource;
anyMissing |= DefaultDecalResource == nint.Zero;
}
if (anyMissing)
@ -106,7 +106,7 @@ public unsafe partial class CharacterUtility : IDisposable
LoadingFinished.Invoke();
}
public void SetResource(MetaIndex resourceIdx, IntPtr data, int length)
public void SetResource(MetaIndex resourceIdx, nint data, int length)
{
var idx = ReverseIndices[(int)resourceIdx];
var list = _lists[idx.Value];
@ -120,14 +120,14 @@ public unsafe partial class CharacterUtility : IDisposable
list.ResetResource();
}
public List.MetaReverter TemporarilySetResource(MetaIndex resourceIdx, IntPtr data, int length)
public MetaList.MetaReverter TemporarilySetResource(MetaIndex resourceIdx, nint data, int length)
{
var idx = ReverseIndices[(int)resourceIdx];
var list = _lists[idx.Value];
return list.TemporarilySetResource(data, length);
}
public List.MetaReverter TemporarilyResetResource(MetaIndex resourceIdx)
public MetaList.MetaReverter TemporarilyResetResource(MetaIndex resourceIdx)
{
var idx = ReverseIndices[(int)resourceIdx];
var list = _lists[idx.Value];

View file

@ -0,0 +1,61 @@
using System;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.Enums;
using Penumbra.Interop.ResourceLoading;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Services;
public sealed unsafe class DecalReverter : IDisposable
{
public static readonly Utf8GamePath DecalPath =
Utf8GamePath.FromSpan("chara/common/texture/decal_equip/_stigma.tex"u8, out var p) ? p : Utf8GamePath.Empty;
public static readonly Utf8GamePath TransparentPath =
Utf8GamePath.FromSpan("chara/common/texture/transparent.tex"u8, out var p) ? p : Utf8GamePath.Empty;
private readonly CharacterUtility _utility;
private readonly Structs.TextureResourceHandle* _decal;
private readonly Structs.TextureResourceHandle* _transparent;
public DecalReverter(CharacterUtility utility, ResourceService resources, ModCollection? collection, bool doDecal)
{
_utility = utility;
var ptr = _utility.Address;
_decal = null;
_transparent = null;
if (doDecal)
{
var decalPath = collection?.ResolvePath(DecalPath)?.InternalName ?? DecalPath.Path;
var decalHandle = resources.GetResource(ResourceCategory.Chara, ResourceType.Tex, decalPath);
_decal = (Structs.TextureResourceHandle*)decalHandle;
if (_decal != null)
ptr->DecalTexResource = _decal;
}
else
{
var transparentPath = collection?.ResolvePath(TransparentPath)?.InternalName ?? TransparentPath.Path;
var transparentHandle = resources.GetResource(ResourceCategory.Chara, ResourceType.Tex, transparentPath);
_transparent = (Structs.TextureResourceHandle*)transparentHandle;
if (_transparent != null)
ptr->TransparentTexResource = _transparent;
}
}
public void Dispose()
{
var ptr = _utility.Address;
if (_decal != null)
{
ptr->DecalTexResource = (Structs.TextureResourceHandle*)_utility.DefaultDecalResource;
--_decal->Handle.RefCount;
}
if (_transparent != null)
{
ptr->TransparentTexResource = (Structs.TextureResourceHandle*)_utility.DefaultTransparentResource;
--_transparent->Handle.RefCount;
}
}
}

View file

@ -14,7 +14,7 @@ using Penumbra.GameData.Actors;
using Penumbra.Interop.Structs;
using Penumbra.Services;
namespace Penumbra.Interop;
namespace Penumbra.Interop.Services;
public unsafe partial class RedrawService
{

View file

@ -3,6 +3,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.Structs;
using System.Collections.Generic;
using Penumbra.Interop.Services;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -11,8 +12,8 @@ namespace Penumbra.Meta.Files;
// We only support manipulating the racial scaling parameters at the moment.
public sealed unsafe class CmpFile : MetaBaseFile
{
public static readonly Interop.CharacterUtility.InternalIndex InternalIndex =
Interop.CharacterUtility.ReverseIndices[ ( int )CharacterUtility.Index.HumanCmp ];
public static readonly CharacterUtility.InternalIndex InternalIndex =
CharacterUtility.ReverseIndices[ ( int )MetaIndex.HumanCmp ];
private const int RacialScalingStart = 0x2A800;
@ -34,7 +35,7 @@ public sealed unsafe class CmpFile : MetaBaseFile
}
public CmpFile()
: base( CharacterUtility.Index.HumanCmp )
: base( MetaIndex.HumanCmp )
{
AllocateData( DefaultData.Length );
Reset();

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
@ -96,7 +97,7 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile
}
public ExpandedEqdpFile( GenderRace raceCode, bool accessory )
: base( CharacterUtility.EqdpIdx( raceCode, accessory ) )
: base( CharacterUtilityData.EqdpIdx( raceCode, accessory ) )
{
var def = ( byte* )DefaultData.Data;
var blockSize = *( ushort* )( def + IdentifierSize );
@ -114,7 +115,7 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile
public EqdpEntry GetDefault( int setIdx )
=> GetDefault( Index, setIdx );
public static EqdpEntry GetDefault( Interop.CharacterUtility.InternalIndex idx, int setIdx )
public static EqdpEntry GetDefault( CharacterUtility.InternalIndex idx, int setIdx )
=> GetDefault( ( byte* )Penumbra.CharacterUtility.DefaultResource( idx ).Address, setIdx );
public static EqdpEntry GetDefault( byte* data, int setIdx )
@ -139,5 +140,5 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile
}
public static EqdpEntry GetDefault( GenderRace raceCode, bool accessory, int setIdx )
=> GetDefault( Interop.CharacterUtility.ReverseIndices[ ( int )CharacterUtility.EqdpIdx( raceCode, accessory ) ], setIdx );
=> GetDefault( CharacterUtility.ReverseIndices[ ( int )CharacterUtilityData.EqdpIdx( raceCode, accessory ) ], setIdx );
}

View file

@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using Penumbra.GameData.Structs;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
@ -75,13 +76,13 @@ public unsafe class ExpandedEqpGmpBase : MetaBaseFile
}
public ExpandedEqpGmpBase( bool gmp )
: base( gmp ? CharacterUtility.Index.Gmp : CharacterUtility.Index.Eqp )
: base( gmp ? MetaIndex.Gmp : MetaIndex.Eqp )
{
AllocateData( MaxSize );
Reset();
}
protected static ulong GetDefaultInternal( Interop.CharacterUtility.InternalIndex fileIndex, int setIdx, ulong def )
protected static ulong GetDefaultInternal( CharacterUtility.InternalIndex fileIndex, int setIdx, ulong def )
{
var data = ( byte* )Penumbra.CharacterUtility.DefaultResource(fileIndex).Address;
if( setIdx == 0 )
@ -111,8 +112,8 @@ public unsafe class ExpandedEqpGmpBase : MetaBaseFile
public sealed class ExpandedEqpFile : ExpandedEqpGmpBase, IEnumerable<EqpEntry>
{
public static readonly Interop.CharacterUtility.InternalIndex InternalIndex =
Interop.CharacterUtility.ReverseIndices[ (int) CharacterUtility.Index.Eqp ];
public static readonly CharacterUtility.InternalIndex InternalIndex =
CharacterUtility.ReverseIndices[ (int) MetaIndex.Eqp ];
public ExpandedEqpFile()
: base( false )
@ -158,8 +159,8 @@ public sealed class ExpandedEqpFile : ExpandedEqpGmpBase, IEnumerable<EqpEntry>
public sealed class ExpandedGmpFile : ExpandedEqpGmpBase, IEnumerable<GmpEntry>
{
public static readonly Interop.CharacterUtility.InternalIndex InternalIndex =
Interop.CharacterUtility.ReverseIndices[( int )CharacterUtility.Index.Gmp];
public static readonly CharacterUtility.InternalIndex InternalIndex =
CharacterUtility.ReverseIndices[( int )MetaIndex.Gmp];
public ExpandedGmpFile()
: base( true )

View file

@ -1,6 +1,7 @@
using System;
using System.Runtime.InteropServices;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Functions;
@ -175,7 +176,7 @@ public sealed unsafe class EstFile : MetaBaseFile
}
public EstFile( EstManipulation.EstType estType )
: base( ( CharacterUtility.Index )estType )
: base( ( MetaIndex )estType )
{
var length = DefaultData.Length;
AllocateData( length + IncreaseSize );
@ -185,7 +186,7 @@ public sealed unsafe class EstFile : MetaBaseFile
public ushort GetDefault( GenderRace genderRace, ushort setId )
=> GetDefault( Index, genderRace, setId );
public static ushort GetDefault( Interop.CharacterUtility.InternalIndex index, GenderRace genderRace, ushort setId )
public static ushort GetDefault( CharacterUtility.InternalIndex index, GenderRace genderRace, ushort setId )
{
var data = ( byte* )Penumbra.CharacterUtility.DefaultResource( index ).Address;
var count = *( int* )data;
@ -199,9 +200,9 @@ public sealed unsafe class EstFile : MetaBaseFile
return *( ushort* )( data + 4 + count * EntryDescSize + idx * EntrySize );
}
public static ushort GetDefault( CharacterUtility.Index index, GenderRace genderRace, ushort setId )
=> GetDefault( Interop.CharacterUtility.ReverseIndices[ ( int )index ], genderRace, setId );
public static ushort GetDefault( MetaIndex metaIndex, GenderRace genderRace, ushort setId )
=> GetDefault( CharacterUtility.ReverseIndices[ ( int )metaIndex ], genderRace, setId );
public static ushort GetDefault( EstManipulation.EstType estType, GenderRace genderRace, ushort setId )
=> GetDefault( ( CharacterUtility.Index )estType, genderRace, setId );
=> GetDefault( ( MetaIndex )estType, genderRace, setId );
}

View file

@ -1,4 +1,5 @@
using System;
using Penumbra.Interop.Structs;
namespace Penumbra.Meta.Files;
@ -64,6 +65,6 @@ public unsafe class EvpFile : MetaBaseFile
}
public EvpFile()
: base( ( Interop.Structs.CharacterUtility.Index )1 ) // TODO: Name
: base( ( MetaIndex )1 ) // TODO: Name
{ }
}

View file

@ -1,7 +1,8 @@
using System;
using Dalamud.Memory;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
namespace Penumbra.Meta.Files;
@ -11,7 +12,7 @@ public unsafe class MetaBaseFile : IDisposable
public int Length { get; private set; }
public CharacterUtility.InternalIndex Index { get; }
public MetaBaseFile( Interop.Structs.CharacterUtility.Index idx )
public MetaBaseFile( MetaIndex idx )
=> Index = CharacterUtility.ReverseIndices[ ( int )idx ];
protected (IntPtr Data, int Length) DefaultData

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using OtterGui.Filesystem;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -13,13 +14,13 @@ public partial class MetaManager
private readonly List< RspManipulation > _cmpManipulations = new();
public void SetCmpFiles()
=> SetFile( _cmpFile, CharacterUtility.Index.HumanCmp );
=> SetFile( _cmpFile, MetaIndex.HumanCmp );
public static void ResetCmpFiles()
=> SetFile( null, CharacterUtility.Index.HumanCmp );
=> SetFile( null, MetaIndex.HumanCmp );
public Interop.CharacterUtility.List.MetaReverter TemporarilySetCmpFile()
=> TemporarilySetFile( _cmpFile, CharacterUtility.Index.HumanCmp );
public CharacterUtility.MetaList.MetaReverter TemporarilySetCmpFile()
=> TemporarilySetFile( _cmpFile, MetaIndex.HumanCmp );
public void ResetCmp()
{

View file

@ -4,6 +4,7 @@ using System.Linq;
using OtterGui;
using OtterGui.Filesystem;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -12,24 +13,24 @@ namespace Penumbra.Meta.Manager;
public partial class MetaManager
{
private readonly ExpandedEqdpFile?[] _eqdpFiles = new ExpandedEqdpFile[CharacterUtility.EqdpIndices.Length]; // TODO: female Hrothgar
private readonly ExpandedEqdpFile?[] _eqdpFiles = new ExpandedEqdpFile[CharacterUtilityData.EqdpIndices.Length]; // TODO: female Hrothgar
private readonly List< EqdpManipulation > _eqdpManipulations = new();
public void SetEqdpFiles()
{
for( var i = 0; i < CharacterUtility.EqdpIndices.Length; ++i )
for( var i = 0; i < CharacterUtilityData.EqdpIndices.Length; ++i )
{
SetFile( _eqdpFiles[ i ], CharacterUtility.EqdpIndices[ i ] );
SetFile( _eqdpFiles[ i ], CharacterUtilityData.EqdpIndices[ i ] );
}
}
public Interop.CharacterUtility.List.MetaReverter? TemporarilySetEqdpFile( GenderRace genderRace, bool accessory )
public CharacterUtility.MetaList.MetaReverter? TemporarilySetEqdpFile( GenderRace genderRace, bool accessory )
{
var idx = CharacterUtility.EqdpIdx( genderRace, accessory );
var idx = CharacterUtilityData.EqdpIdx( genderRace, accessory );
if( ( int )idx != -1 )
{
var i = CharacterUtility.EqdpIndices.IndexOf( idx );
var i = CharacterUtilityData.EqdpIndices.IndexOf( idx );
if( i != -1 )
{
return TemporarilySetFile( _eqdpFiles[ i ], idx );
@ -41,7 +42,7 @@ public partial class MetaManager
public static void ResetEqdpFiles()
{
foreach( var idx in CharacterUtility.EqdpIndices )
foreach( var idx in CharacterUtilityData.EqdpIndices )
{
SetFile( null, idx );
}
@ -51,7 +52,7 @@ public partial class MetaManager
{
foreach( var file in _eqdpFiles.OfType< ExpandedEqdpFile >() )
{
var relevant = Interop.CharacterUtility.RelevantIndices[ file.Index.Value ];
var relevant = CharacterUtility.RelevantIndices[ file.Index.Value ];
file.Reset( _eqdpManipulations.Where( m => m.FileIndex() == relevant ).Select( m => ( int )m.SetId ) );
}
@ -61,7 +62,7 @@ public partial class MetaManager
public bool ApplyMod( EqdpManipulation manip )
{
_eqdpManipulations.AddOrReplace( manip );
var file = _eqdpFiles[ Array.IndexOf( CharacterUtility.EqdpIndices, manip.FileIndex() ) ] ??=
var file = _eqdpFiles[ Array.IndexOf( CharacterUtilityData.EqdpIndices, manip.FileIndex() ) ] ??=
new ExpandedEqdpFile( Names.CombinedRace( manip.Gender, manip.Race ), manip.Slot.IsAccessory() ); // TODO: female Hrothgar
return manip.Apply( file );
}
@ -71,7 +72,7 @@ public partial class MetaManager
if( _eqdpManipulations.Remove( manip ) )
{
var def = ExpandedEqdpFile.GetDefault( Names.CombinedRace( manip.Gender, manip.Race ), manip.Slot.IsAccessory(), manip.SetId );
var file = _eqdpFiles[ Array.IndexOf( CharacterUtility.EqdpIndices, manip.FileIndex() ) ]!;
var file = _eqdpFiles[ Array.IndexOf( CharacterUtilityData.EqdpIndices, manip.FileIndex() ) ]!;
manip = new EqdpManipulation( def, manip.Slot, manip.Gender, manip.Race, manip.SetId );
return manip.Apply( file );
}
@ -81,7 +82,7 @@ public partial class MetaManager
public ExpandedEqdpFile? EqdpFile( GenderRace race, bool accessory )
=> _eqdpFiles
[ Array.IndexOf( CharacterUtility.EqdpIndices, CharacterUtility.EqdpIdx( race, accessory ) ) ]; // TODO: female Hrothgar
[ Array.IndexOf( CharacterUtilityData.EqdpIndices, CharacterUtilityData.EqdpIdx( race, accessory ) ) ]; // TODO: female Hrothgar
public void DisposeEqdp()
{

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using OtterGui.Filesystem;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -13,13 +14,13 @@ public partial class MetaManager
private readonly List< EqpManipulation > _eqpManipulations = new();
public void SetEqpFiles()
=> SetFile( _eqpFile, CharacterUtility.Index.Eqp );
=> SetFile( _eqpFile, MetaIndex.Eqp );
public static void ResetEqpFiles()
=> SetFile( null, CharacterUtility.Index.Eqp );
=> SetFile( null, MetaIndex.Eqp );
public Interop.CharacterUtility.List.MetaReverter TemporarilySetEqpFile()
=> TemporarilySetFile( _eqpFile, CharacterUtility.Index.Eqp );
public CharacterUtility.MetaList.MetaReverter TemporarilySetEqpFile()
=> TemporarilySetFile( _eqpFile, MetaIndex.Eqp );
public void ResetEqp()
{

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using OtterGui.Filesystem;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -19,28 +20,28 @@ public partial class MetaManager
public void SetEstFiles()
{
SetFile( _estFaceFile, CharacterUtility.Index.FaceEst );
SetFile( _estHairFile, CharacterUtility.Index.HairEst );
SetFile( _estBodyFile, CharacterUtility.Index.BodyEst );
SetFile( _estHeadFile, CharacterUtility.Index.HeadEst );
SetFile( _estFaceFile, MetaIndex.FaceEst );
SetFile( _estHairFile, MetaIndex.HairEst );
SetFile( _estBodyFile, MetaIndex.BodyEst );
SetFile( _estHeadFile, MetaIndex.HeadEst );
}
public static void ResetEstFiles()
{
SetFile( null, CharacterUtility.Index.FaceEst );
SetFile( null, CharacterUtility.Index.HairEst );
SetFile( null, CharacterUtility.Index.BodyEst );
SetFile( null, CharacterUtility.Index.HeadEst );
SetFile( null, MetaIndex.FaceEst );
SetFile( null, MetaIndex.HairEst );
SetFile( null, MetaIndex.BodyEst );
SetFile( null, MetaIndex.HeadEst );
}
public Interop.CharacterUtility.List.MetaReverter? TemporarilySetEstFile(EstManipulation.EstType type)
public CharacterUtility.MetaList.MetaReverter? TemporarilySetEstFile(EstManipulation.EstType type)
{
var (file, idx) = type switch
{
EstManipulation.EstType.Face => ( _estFaceFile, CharacterUtility.Index.FaceEst ),
EstManipulation.EstType.Hair => ( _estHairFile, CharacterUtility.Index.HairEst ),
EstManipulation.EstType.Body => ( _estBodyFile, CharacterUtility.Index.BodyEst ),
EstManipulation.EstType.Head => ( _estHeadFile, CharacterUtility.Index.HeadEst ),
EstManipulation.EstType.Face => ( _estFaceFile, MetaIndex.FaceEst ),
EstManipulation.EstType.Hair => ( _estHairFile, MetaIndex.HairEst ),
EstManipulation.EstType.Body => ( _estBodyFile, MetaIndex.BodyEst ),
EstManipulation.EstType.Head => ( _estHeadFile, MetaIndex.HeadEst ),
_ => ( null, 0 ),
};

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using OtterGui.Filesystem;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -13,13 +14,13 @@ public partial class MetaManager
private readonly List< GmpManipulation > _gmpManipulations = new();
public void SetGmpFiles()
=> SetFile( _gmpFile, CharacterUtility.Index.Gmp );
=> SetFile( _gmpFile, MetaIndex.Gmp );
public static void ResetGmpFiles()
=> SetFile( null, CharacterUtility.Index.Gmp );
=> SetFile( null, MetaIndex.Gmp );
public Interop.CharacterUtility.List.MetaReverter TemporarilySetGmpFile()
=> TemporarilySetFile( _gmpFile, CharacterUtility.Index.Gmp );
public CharacterUtility.MetaList.MetaReverter TemporarilySetGmpFile()
=> TemporarilySetFile( _gmpFile, MetaIndex.Gmp );
public void ResetGmp()
{

View file

@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using OtterGui;
using Penumbra.Collections;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
@ -162,36 +163,36 @@ public partial class MetaManager : IDisposable, IEnumerable< KeyValuePair< MetaM
Penumbra.Log.Debug( $"{_collection.AnonymizedName}: Loaded {loaded} delayed meta manipulations." );
}
public void SetFile( CharacterUtility.Index index )
public void SetFile( MetaIndex metaIndex )
{
switch( index )
switch( metaIndex )
{
case CharacterUtility.Index.Eqp:
SetFile( _eqpFile, index );
case MetaIndex.Eqp:
SetFile( _eqpFile, metaIndex );
break;
case CharacterUtility.Index.Gmp:
SetFile( _gmpFile, index );
case MetaIndex.Gmp:
SetFile( _gmpFile, metaIndex );
break;
case CharacterUtility.Index.HumanCmp:
SetFile( _cmpFile, index );
case MetaIndex.HumanCmp:
SetFile( _cmpFile, metaIndex );
break;
case CharacterUtility.Index.FaceEst:
SetFile( _estFaceFile, index );
case MetaIndex.FaceEst:
SetFile( _estFaceFile, metaIndex );
break;
case CharacterUtility.Index.HairEst:
SetFile( _estHairFile, index );
case MetaIndex.HairEst:
SetFile( _estHairFile, metaIndex );
break;
case CharacterUtility.Index.HeadEst:
SetFile( _estHeadFile, index );
case MetaIndex.HeadEst:
SetFile( _estHeadFile, metaIndex );
break;
case CharacterUtility.Index.BodyEst:
SetFile( _estBodyFile, index );
case MetaIndex.BodyEst:
SetFile( _estBodyFile, metaIndex );
break;
default:
var i = CharacterUtility.EqdpIndices.IndexOf( index );
var i = CharacterUtilityData.EqdpIndices.IndexOf( metaIndex );
if( i != -1 )
{
SetFile( _eqdpFiles[ i ], index );
SetFile( _eqdpFiles[ i ], metaIndex );
}
break;
@ -199,21 +200,21 @@ public partial class MetaManager : IDisposable, IEnumerable< KeyValuePair< MetaM
}
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
private static unsafe void SetFile( MetaBaseFile? file, CharacterUtility.Index index )
private static unsafe void SetFile( MetaBaseFile? file, MetaIndex metaIndex )
{
if( file == null )
{
Penumbra.CharacterUtility.ResetResource( index );
Penumbra.CharacterUtility.ResetResource( metaIndex );
}
else
{
Penumbra.CharacterUtility.SetResource( index, ( IntPtr )file.Data, file.Length );
Penumbra.CharacterUtility.SetResource( metaIndex, ( IntPtr )file.Data, file.Length );
}
}
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
private static unsafe Interop.CharacterUtility.List.MetaReverter TemporarilySetFile( MetaBaseFile? file, CharacterUtility.Index index )
private static unsafe CharacterUtility.MetaList.MetaReverter TemporarilySetFile( MetaBaseFile? file, MetaIndex metaIndex )
=> file == null
? Penumbra.CharacterUtility.TemporarilyResetResource( index )
: Penumbra.CharacterUtility.TemporarilySetResource( index, ( IntPtr )file.Data, file.Length );
? Penumbra.CharacterUtility.TemporarilyResetResource( metaIndex )
: Penumbra.CharacterUtility.TemporarilySetResource( metaIndex, ( IntPtr )file.Data, file.Length );
}

View file

@ -81,8 +81,8 @@ public readonly struct EqdpManipulation : IMetaManipulation< EqdpManipulation >
return set != 0 ? set : Slot.CompareTo( other.Slot );
}
public CharacterUtility.Index FileIndex()
=> CharacterUtility.EqdpIdx( Names.CombinedRace( Gender, Race ), Slot.IsAccessory() );
public MetaIndex FileIndex()
=> CharacterUtilityData.EqdpIdx( Names.CombinedRace( Gender, Race ), Slot.IsAccessory() );
public bool Apply( ExpandedEqdpFile file )
{

View file

@ -52,8 +52,8 @@ public readonly struct EqpManipulation : IMetaManipulation< EqpManipulation >
return set != 0 ? set : Slot.CompareTo( other.Slot );
}
public CharacterUtility.Index FileIndex()
=> CharacterUtility.Index.Eqp;
public MetaIndex FileIndex()
=> MetaIndex.Eqp;
public bool Apply( ExpandedEqpFile file )
{

View file

@ -13,10 +13,10 @@ public readonly struct EstManipulation : IMetaManipulation< EstManipulation >
{
public enum EstType : byte
{
Hair = CharacterUtility.Index.HairEst,
Face = CharacterUtility.Index.FaceEst,
Body = CharacterUtility.Index.BodyEst,
Head = CharacterUtility.Index.HeadEst,
Hair = MetaIndex.HairEst,
Face = MetaIndex.FaceEst,
Body = MetaIndex.BodyEst,
Head = MetaIndex.HeadEst,
}
public static string ToName( EstType type )
@ -89,8 +89,8 @@ public readonly struct EstManipulation : IMetaManipulation< EstManipulation >
return s != 0 ? s : SetId.CompareTo( other.SetId );
}
public CharacterUtility.Index FileIndex()
=> ( CharacterUtility.Index )Slot;
public MetaIndex FileIndex()
=> ( MetaIndex )Slot;
public bool Apply( EstFile file )
{

View file

@ -37,8 +37,8 @@ public readonly struct GmpManipulation : IMetaManipulation< GmpManipulation >
public int CompareTo( GmpManipulation other )
=> SetId.CompareTo( other.SetId );
public CharacterUtility.Index FileIndex()
=> CharacterUtility.Index.Gmp;
public MetaIndex FileIndex()
=> MetaIndex.Gmp;
public bool Apply( ExpandedGmpFile file )
{

View file

@ -142,8 +142,8 @@ public readonly struct ImcManipulation : IMetaManipulation< ImcManipulation >
return b != 0 ? b : Variant.CompareTo( other.Variant );
}
public CharacterUtility.Index FileIndex()
=> ( CharacterUtility.Index )( -1 );
public MetaIndex FileIndex()
=> ( MetaIndex )( -1 );
public Utf8GamePath GamePath()
{

View file

@ -9,7 +9,7 @@ namespace Penumbra.Meta.Manipulations;
public interface IMetaManipulation
{
public CharacterUtility.Index FileIndex();
public MetaIndex FileIndex();
}
public interface IMetaManipulation< T >

View file

@ -49,8 +49,8 @@ public readonly struct RspManipulation : IMetaManipulation< RspManipulation >
return s != 0 ? s : Attribute.CompareTo( other.Attribute );
}
public CharacterUtility.Index FileIndex()
=> CharacterUtility.Index.HumanCmp;
public MetaIndex FileIndex()
=> MetaIndex.HumanCmp;
public bool Apply( CmpFile file )
{

View file

@ -59,7 +59,7 @@ public static class EquipmentSwap
case Gender.FemaleNpc when skipFemale: continue;
}
if( CharacterUtility.EqdpIdx( gr, true ) < 0 )
if( CharacterUtilityData.EqdpIdx( gr, true ) < 0 )
{
continue;
}
@ -147,7 +147,7 @@ public static class EquipmentSwap
case Gender.FemaleNpc when skipFemale: continue;
}
if( CharacterUtility.EqdpIdx( gr, isAccessory ) < 0 )
if( CharacterUtilityData.EqdpIdx( gr, isAccessory ) < 0 )
{
continue;
}

View file

@ -22,10 +22,10 @@ using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Data;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.PathResolving;
using Penumbra.Mods;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using DalamudUtil = Dalamud.Utility.Util;
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
using Penumbra.Services;

View file

@ -9,8 +9,8 @@ using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Data;
using Penumbra.Interop;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.ResourceTree;
using Penumbra.Interop.Services;
using Penumbra.Mods;
@ -20,6 +20,7 @@ using Penumbra.UI.AdvancedWindow;
using Penumbra.UI.ModsTab;
using Penumbra.UI.Tabs;
using Penumbra.Util;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using ModFileSystemSelector = Penumbra.UI.ModsTab.ModFileSystemSelector;
namespace Penumbra;

View file

@ -7,7 +7,7 @@ using Dalamud.Plugin;
using Penumbra.GameData;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Data;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.PathResolving;
using Penumbra.Util;
namespace Penumbra.Services;

View file

@ -199,7 +199,7 @@ public partial class ModEditWindow
editor.MetaEditor.Eqdp.Select(m => (MetaManipulation)m));
ImGui.TableNextColumn();
var raceCode = Names.CombinedRace(_new.Gender, _new.Race);
var validRaceCode = CharacterUtility.EqdpIdx(raceCode, false) >= 0;
var validRaceCode = CharacterUtilityData.EqdpIdx(raceCode, false) >= 0;
var canAdd = validRaceCode && editor.MetaEditor.CanAdd(_new);
var tt = canAdd ? "Stage this edit." :
validRaceCode ? "This entry is already edited." : "This combination of race and gender can not be used.";

View file

@ -11,7 +11,7 @@ using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Collections;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;

View file

@ -14,8 +14,8 @@ using Penumbra.Api;
using Penumbra.Collections;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Files;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.Structs;
using Penumbra.Mods;
using Penumbra.Services;
@ -23,7 +23,7 @@ using Penumbra.String;
using Penumbra.Util;
using static OtterGui.Raii.ImRaii;
using CharacterBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
@ -467,7 +467,7 @@ public class DebugTab : ITab
foreach (var list in _characterUtility.Lists)
{
ImGuiUtil.DrawTableColumn(list.GlobalIndex.ToString());
ImGuiUtil.DrawTableColumn(list.GlobalMetaIndex.ToString());
ImGuiUtil.DrawTableColumn(list.Entries.Count.ToString());
ImGuiUtil.DrawTableColumn(string.Join(", ", list.Entries.Select(e => $"0x{e.Data:X}")));
}

View file

@ -10,6 +10,7 @@ using Dalamud.Interface;
using OtterGui.Widgets;
using Penumbra.Api.Enums;
using Penumbra.Interop;
using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.ModsTab;

View file

@ -11,7 +11,7 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Interop.Loader;
using Penumbra.Interop.ResourceLoading;
using Penumbra.String.Classes;
namespace Penumbra.UI.Tabs;

View file

@ -14,6 +14,7 @@ using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
using ModFileSystemSelector = Penumbra.UI.ModsTab.ModFileSystemSelector;
namespace Penumbra.UI.Tabs;