Penumbra/Penumbra/Mods/Editor/ModMetaEditor.cs
2024-12-31 15:40:25 +01:00

199 lines
6.3 KiB
C#

using System.Collections.Frozen;
using OtterGui.Services;
using Penumbra.Collections.Cache;
using Penumbra.Meta;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods.Manager.OptionEditor;
using Penumbra.Mods.SubMods;
namespace Penumbra.Mods.Editor;
public class ModMetaEditor(
ModGroupEditor groupEditor,
MetaFileManager metaFileManager) : MetaDictionary, IService
{
public sealed class OtherOptionData : HashSet<string>
{
public int TotalCount;
public void Add(string name, int count)
{
if (count > 0)
Add(name);
TotalCount += count;
}
public new void Clear()
{
TotalCount = 0;
base.Clear();
}
}
public readonly FrozenDictionary<MetaManipulationType, OtherOptionData> OtherData =
Enum.GetValues<MetaManipulationType>().ToFrozenDictionary(t => t, _ => new OtherOptionData());
public bool Changes { get; set; }
public new void Clear()
{
Changes = Count > 0;
base.Clear();
}
public void Load(Mod mod, IModDataContainer currentOption)
{
foreach (var type in Enum.GetValues<MetaManipulationType>())
OtherData[type].Clear();
foreach (var option in mod.AllDataContainers)
{
if (option == currentOption)
continue;
var name = option.GetFullName();
OtherData[MetaManipulationType.Imc].Add(name, option.Manipulations.GetCount(MetaManipulationType.Imc));
OtherData[MetaManipulationType.Eqp].Add(name, option.Manipulations.GetCount(MetaManipulationType.Eqp));
OtherData[MetaManipulationType.Eqdp].Add(name, option.Manipulations.GetCount(MetaManipulationType.Eqdp));
OtherData[MetaManipulationType.Gmp].Add(name, option.Manipulations.GetCount(MetaManipulationType.Gmp));
OtherData[MetaManipulationType.Est].Add(name, option.Manipulations.GetCount(MetaManipulationType.Est));
OtherData[MetaManipulationType.Rsp].Add(name, option.Manipulations.GetCount(MetaManipulationType.Rsp));
OtherData[MetaManipulationType.Atch].Add(name, option.Manipulations.GetCount(MetaManipulationType.Atch));
OtherData[MetaManipulationType.GlobalEqp].Add(name, option.Manipulations.GetCount(MetaManipulationType.GlobalEqp));
}
Clear();
UnionWith(currentOption.Manipulations);
Changes = false;
}
public static bool DeleteDefaultValues(MetaFileManager metaFileManager, MetaDictionary dict)
{
var clone = dict.Clone();
dict.ClearForDefault();
var count = 0;
foreach (var value in clone.GlobalEqp)
dict.TryAdd(value);
foreach (var (key, value) in clone.Imc)
{
var defaultEntry = ImcChecker.GetDefaultEntry(key, false);
if (!defaultEntry.Entry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Eqp)
{
var defaultEntry = new EqpEntryInternal(ExpandedEqpFile.GetDefault(metaFileManager, key.SetId), key.Slot);
if (!defaultEntry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Eqdp)
{
var defaultEntry = new EqdpEntryInternal(ExpandedEqdpFile.GetDefault(metaFileManager, key), key.Slot);
if (!defaultEntry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Est)
{
var defaultEntry = EstFile.GetDefault(metaFileManager, key);
if (!defaultEntry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Gmp)
{
var defaultEntry = ExpandedGmpFile.GetDefault(metaFileManager, key);
if (!defaultEntry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Rsp)
{
var defaultEntry = CmpFile.GetDefault(metaFileManager, key.SubRace, key.Attribute);
if (!defaultEntry.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
foreach (var (key, value) in clone.Atch)
{
var defaultEntry = AtchCache.GetDefault(metaFileManager, key);
if (!defaultEntry.HasValue)
continue;
if (!defaultEntry.Value.Equals(value))
{
dict.TryAdd(key, value);
}
else
{
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
++count;
}
}
if (count == 0)
return false;
Penumbra.Log.Debug($"Deleted {count} default-valued meta-entries from a mod option.");
return true;
}
public void DeleteDefaultValues()
=> Changes = DeleteDefaultValues(metaFileManager, this);
public void Apply(IModDataContainer container)
{
if (!Changes)
return;
groupEditor.SetManipulations(container, this);
Changes = false;
}
}