mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-01 05:13:43 +01:00
Get rid off EQDP files
This commit is contained in:
parent
9ecc4ab46d
commit
600fd2ecd3
23 changed files with 192 additions and 246 deletions
|
|
@ -1,8 +1,5 @@
|
|||
using OtterGui;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
|
@ -11,108 +8,60 @@ namespace Penumbra.Collections.Cache;
|
|||
|
||||
public sealed class EqdpCache(MetaFileManager manager, ModCollection collection) : MetaCacheBase<EqdpIdentifier, EqdpEntry>(manager, collection)
|
||||
{
|
||||
private readonly ExpandedEqdpFile?[] _eqdpFiles = new ExpandedEqdpFile[CharacterUtilityData.EqdpIndices.Length]; // TODO: female Hrothgar
|
||||
private readonly Dictionary<(PrimaryId Id, GenderRace GenderRace, bool Accessory), EqdpEntry> _fullEntries = [];
|
||||
|
||||
public override void SetFiles()
|
||||
{
|
||||
for (var i = 0; i < CharacterUtilityData.EqdpIndices.Length; ++i)
|
||||
Manager.SetFile(_eqdpFiles[i], CharacterUtilityData.EqdpIndices[i]);
|
||||
}
|
||||
{ }
|
||||
|
||||
public void SetFile(MetaIndex index)
|
||||
{
|
||||
var i = CharacterUtilityData.EqdpIndices.IndexOf(index);
|
||||
if (i != -1)
|
||||
Manager.SetFile(_eqdpFiles[i], index);
|
||||
}
|
||||
|
||||
public void ResetFiles()
|
||||
{
|
||||
foreach (var t in CharacterUtilityData.EqdpIndices)
|
||||
Manager.SetFile(null, t);
|
||||
}
|
||||
public bool TryGetFullEntry(PrimaryId id, GenderRace genderRace, bool accessory, out EqdpEntry entry)
|
||||
=> _fullEntries.TryGetValue((id, genderRace, accessory), out entry);
|
||||
|
||||
protected override void IncorporateChangesInternal()
|
||||
{
|
||||
foreach (var (identifier, (_, entry)) in this)
|
||||
Apply(GetFile(identifier)!, identifier, entry);
|
||||
|
||||
Penumbra.Log.Verbose($"{Collection.AnonymizedName}: Loaded {Count} delayed EQDP manipulations.");
|
||||
}
|
||||
|
||||
public ExpandedEqdpFile? EqdpFile(GenderRace race, bool accessory)
|
||||
=> _eqdpFiles[Array.IndexOf(CharacterUtilityData.EqdpIndices, CharacterUtilityData.EqdpIdx(race, accessory))]; // TODO: female Hrothgar
|
||||
|
||||
public MetaList.MetaReverter? TemporarilySetFile(GenderRace genderRace, bool accessory)
|
||||
{
|
||||
var idx = CharacterUtilityData.EqdpIdx(genderRace, accessory);
|
||||
if (idx < 0)
|
||||
{
|
||||
Penumbra.Log.Warning($"Invalid Gender, Race or Accessory for EQDP file {genderRace}, {accessory}.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var i = CharacterUtilityData.EqdpIndices.IndexOf(idx);
|
||||
if (i < 0)
|
||||
{
|
||||
Penumbra.Log.Warning($"Invalid Gender, Race or Accessory for EQDP file {genderRace}, {accessory}.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return Manager.TemporarilySetFile(_eqdpFiles[i], idx);
|
||||
}
|
||||
{ }
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach (var file in _eqdpFiles.OfType<ExpandedEqdpFile>())
|
||||
{
|
||||
var relevant = CharacterUtility.RelevantIndices[file.Index.Value];
|
||||
file.Reset(Keys.Where(m => m.FileIndex() == relevant).Select(m => m.SetId));
|
||||
}
|
||||
|
||||
Clear();
|
||||
_fullEntries.Clear();
|
||||
}
|
||||
|
||||
protected override void ApplyModInternal(EqdpIdentifier identifier, EqdpEntry entry)
|
||||
{
|
||||
if (GetFile(identifier) is { } file)
|
||||
Apply(file, identifier, entry);
|
||||
var tuple = (identifier.SetId, identifier.GenderRace, identifier.Slot.IsAccessory());
|
||||
var mask = Eqdp.Mask(identifier.Slot);
|
||||
if (!_fullEntries.TryGetValue(tuple, out var currentEntry))
|
||||
currentEntry = ExpandedEqdpFile.GetDefault(Manager, identifier);
|
||||
|
||||
_fullEntries[tuple] = (currentEntry & ~mask) | (entry & mask);
|
||||
}
|
||||
|
||||
protected override void RevertModInternal(EqdpIdentifier identifier)
|
||||
{
|
||||
if (GetFile(identifier) is { } file)
|
||||
Apply(file, identifier, ExpandedEqdpFile.GetDefault(Manager, identifier));
|
||||
}
|
||||
var tuple = (identifier.SetId, identifier.GenderRace, identifier.Slot.IsAccessory());
|
||||
var mask = Eqdp.Mask(identifier.Slot);
|
||||
|
||||
public static bool Apply(ExpandedEqdpFile file, EqdpIdentifier identifier, EqdpEntry entry)
|
||||
{
|
||||
var origEntry = file[identifier.SetId];
|
||||
var mask = Eqdp.Mask(identifier.Slot);
|
||||
if ((origEntry & mask) == entry)
|
||||
return false;
|
||||
|
||||
file[identifier.SetId] = (origEntry & ~mask) | entry;
|
||||
return true;
|
||||
if (_fullEntries.TryGetValue(tuple, out var currentEntry))
|
||||
{
|
||||
var def = ExpandedEqdpFile.GetDefault(Manager, identifier);
|
||||
var newEntry = (currentEntry & ~mask) | (def & mask);
|
||||
if (currentEntry != newEntry)
|
||||
{
|
||||
_fullEntries[tuple] = newEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
var slots = tuple.Item3 ? EquipSlotExtensions.AccessorySlots : EquipSlotExtensions.EquipmentSlots;
|
||||
if (slots.All(s => !ContainsKey(identifier with { Slot = s })))
|
||||
_fullEntries.Remove(tuple);
|
||||
else
|
||||
_fullEntries[tuple] = newEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool _)
|
||||
{
|
||||
for (var i = 0; i < _eqdpFiles.Length; ++i)
|
||||
{
|
||||
_eqdpFiles[i]?.Dispose();
|
||||
_eqdpFiles[i] = null;
|
||||
}
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
private ExpandedEqdpFile? GetFile(EqdpIdentifier identifier)
|
||||
{
|
||||
if (!Manager.CharacterUtility.Ready)
|
||||
return null;
|
||||
|
||||
var index = Array.IndexOf(CharacterUtilityData.EqdpIndices, identifier.FileIndex());
|
||||
return _eqdpFiles[index] ??= new ExpandedEqdpFile(Manager, identifier.GenderRace, identifier.Slot.IsAccessory());
|
||||
_fullEntries.Clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
|
|
@ -115,48 +113,18 @@ public class MetaCache(MetaFileManager manager, ModCollection collection)
|
|||
~MetaCache()
|
||||
=> Dispose();
|
||||
|
||||
/// <summary> Set a single file. </summary>
|
||||
public void SetFile(MetaIndex metaIndex)
|
||||
{
|
||||
switch (metaIndex)
|
||||
{
|
||||
case MetaIndex.Eqp:
|
||||
break;
|
||||
case MetaIndex.Gmp:
|
||||
break;
|
||||
case MetaIndex.HumanCmp:
|
||||
Rsp.SetFiles();
|
||||
break;
|
||||
case MetaIndex.FaceEst:
|
||||
case MetaIndex.HairEst:
|
||||
case MetaIndex.HeadEst:
|
||||
case MetaIndex.BodyEst:
|
||||
break;
|
||||
default:
|
||||
Eqdp.SetFile(metaIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Set the currently relevant IMC files for the collection cache. </summary>
|
||||
public void SetImcFiles(bool fromFullCompute)
|
||||
=> Imc.SetFiles(fromFullCompute);
|
||||
|
||||
public MetaList.MetaReverter? TemporarilySetEqdpFile(GenderRace genderRace, bool accessory)
|
||||
=> Eqdp.TemporarilySetFile(genderRace, accessory);
|
||||
|
||||
/// <summary> Try to obtain a manipulated IMC file. </summary>
|
||||
public bool GetImcFile(Utf8GamePath path, [NotNullWhen(true)] out Meta.Files.ImcFile? file)
|
||||
=> Imc.GetFile(path, out file);
|
||||
|
||||
internal EqdpEntry GetEqdpEntry(GenderRace race, bool accessory, PrimaryId primaryId)
|
||||
{
|
||||
var eqdpFile = Eqdp.EqdpFile(race, accessory);
|
||||
if (eqdpFile != null)
|
||||
return primaryId.Id < eqdpFile.Count ? eqdpFile[primaryId] : default;
|
||||
|
||||
return Meta.Files.ExpandedEqdpFile.GetDefault(manager, race, accessory, primaryId);
|
||||
}
|
||||
=> Eqdp.TryGetFullEntry(primaryId, race, accessory, out var entry)
|
||||
? entry
|
||||
: Meta.Files.ExpandedEqdpFile.GetDefault(manager, race, accessory, primaryId);
|
||||
|
||||
internal EstEntry GetEstEntry(EstType type, GenderRace genderRace, PrimaryId primaryId)
|
||||
=> Est.GetEstEntry(new EstIdentifier(primaryId, type, genderRace));
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Collections.Cache;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
@ -68,35 +63,4 @@ public partial class ModCollection
|
|||
|
||||
internal SingleArray<ModConflicts> Conflicts(Mod mod)
|
||||
=> _cache?.Conflicts(mod) ?? new SingleArray<ModConflicts>();
|
||||
|
||||
public void SetFiles(CharacterUtility utility)
|
||||
{
|
||||
if (_cache == null)
|
||||
{
|
||||
utility.ResetAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
_cache.Meta.SetFiles();
|
||||
Penumbra.Log.Debug($"Set CharacterUtility resources for collection {Identifier}.");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMetaFile(CharacterUtility utility, MetaIndex idx)
|
||||
{
|
||||
if (_cache == null)
|
||||
utility.ResetResource(idx);
|
||||
else
|
||||
_cache.Meta.SetFile(idx);
|
||||
}
|
||||
|
||||
// Used for short periods of changed files.
|
||||
public MetaList.MetaReverter? TemporarilySetEqdpFile(CharacterUtility utility, GenderRace genderRace, bool accessory)
|
||||
{
|
||||
if (_cache != null)
|
||||
return _cache?.Meta.TemporarilySetEqdpFile(genderRace, accessory);
|
||||
|
||||
var idx = CharacterUtilityData.EqdpIdx(genderRace, accessory);
|
||||
return idx >= 0 ? utility.TemporarilyResetResource(idx) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue