Fix errors due to Luna update, fix warnings.

This commit is contained in:
Ottermandias 2026-02-07 23:26:20 +01:00
parent afa804394f
commit 3a23bceb6d
42 changed files with 266 additions and 219 deletions

2
Luna

@ -1 +1 @@
Subproject commit a03f00b93d5efd04fab90e780c821d83127b2b52 Subproject commit 1f00860cbb38fecacde99e55461dbc251cb40f24

View file

@ -128,7 +128,7 @@ public class ModsIpcTester : Luna.IUiService, IDisposable
if (Im.SmallButton("Delete"u8)) if (Im.SmallButton("Delete"u8))
_lastDeleteEc = new DeleteMod(_pi).Invoke(_modDirectory, _modName); _lastDeleteEc = new DeleteMod(_pi).Invoke(_modDirectory, _modName);
Im.Line.Same(); Im.Line.Same();
Im.Text(_lastDeleteEc.ToString()); Im.Text($"{_lastDeleteEc}");
} }
using (IpcTester.DrawIntro(GetChangedItems.LabelU8, "Get Changed Items"u8)) using (IpcTester.DrawIntro(GetChangedItems.LabelU8, "Get Changed Items"u8))

View file

@ -36,7 +36,7 @@ public static partial class ChangedItemModeExtensions
=> new(value.Tooltip()); => new(value.Tooltip());
public override IEnumerable<ChangedItemMode> GetBaseItems() public override IEnumerable<ChangedItemMode> GetBaseItems()
=> Enum.GetValues<ChangedItemMode>(); => ChangedItemMode.Values;
} }
public static bool DrawCombo(ReadOnlySpan<byte> label, ChangedItemMode value, float width, Action<ChangedItemMode> setter) public static bool DrawCombo(ReadOnlySpan<byte> label, ChangedItemMode value, float width, Action<ChangedItemMode> setter)

View file

@ -1,4 +1,5 @@
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using ImSharp;
using Luna; using Luna;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -16,7 +17,7 @@ public class ActiveCollectionData : IService
public ModCollection Default { get; internal set; } = ModCollection.Empty; public ModCollection Default { get; internal set; } = ModCollection.Empty;
public ModCollection Interface { get; internal set; } = ModCollection.Empty; public ModCollection Interface { get; internal set; } = ModCollection.Empty;
public readonly ModCollection?[] SpecialCollections = new ModCollection?[Enum.GetValues<Api.Enums.ApiCollectionType>().Length - 3]; public readonly ModCollection?[] SpecialCollections = new ModCollection?[Api.Enums.ApiCollectionType.Values.Count - 3];
} }
public class ActiveCollections : ISavable, IDisposable, IService public class ActiveCollections : ISavable, IDisposable, IService
@ -528,7 +529,7 @@ public class ActiveCollections : ISavable, IDisposable, IService
return string.Empty; return string.Empty;
var racial = false; var racial = false;
foreach (var race in Enum.GetValues<SubRace>().Skip(1)) foreach (var race in SubRace.Values.Skip(1))
{ {
var m = ByType(CollectionTypeExtensions.FromParts(race, Gender.Male, false)); var m = ByType(CollectionTypeExtensions.FromParts(race, Gender.Male, false));
if (m != null && m != yourself) if (m != null && m != yourself)

View file

@ -111,7 +111,7 @@ public static class CollectionTypeExtensions
public static bool CanBeRemoved(this CollectionType collectionType) public static bool CanBeRemoved(this CollectionType collectionType)
=> collectionType.IsSpecial() || collectionType is CollectionType.Individual; => collectionType.IsSpecial() || collectionType is CollectionType.Individual;
public static readonly (CollectionType, StringU8, StringU8)[] Special = Enum.GetValues<CollectionType>() public static readonly (CollectionType, StringU8, StringU8)[] Special = CollectionType.Values
.Where(IsSpecial) .Where(IsSpecial)
.Select(s => (s, new StringU8(s.ToName()), new StringU8(s.ToDescription()))) .Select(s => (s, new StringU8(s.ToName()), new StringU8(s.ToDescription())))
.ToArray(); .ToArray();
@ -331,7 +331,7 @@ public static class CollectionTypeExtensions
return true; return true;
} }
foreach (var t in Enum.GetValues<CollectionType>()) foreach (var t in CollectionType.Values)
{ {
if (t is CollectionType.Inactive or CollectionType.Temporary) if (t is CollectionType.Inactive or CollectionType.Temporary)
continue; continue;

View file

@ -1,5 +1,6 @@
using Dalamud.Configuration; using Dalamud.Configuration;
using Dalamud.Interface.ImGuiNotification; using Dalamud.Interface.ImGuiNotification;
using ImSharp;
using Luna; using Luna;
using Luna.Generators; using Luna.Generators;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -143,7 +144,7 @@ public partial class Configuration : IPluginConfiguration, ISavable, IService
public bool HdrRenderTargets { get; set; } = true; public bool HdrRenderTargets { get; set; } = true;
public Dictionary<ColorId, uint> Colors { get; set; } public Dictionary<ColorId, uint> Colors { get; set; }
= Enum.GetValues<ColorId>().ToDictionary(c => c, c => c.Data().DefaultColor); = ColorId.Values.ToDictionary(c => c, c => c.Data().DefaultColor);
/// <summary> /// <summary>
/// Load the current configuration. /// Load the current configuration.

View file

@ -1,4 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using ImSharp;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Functions; using Penumbra.String.Functions;
@ -90,8 +91,8 @@ public enum ResourceCategoryFlag : ushort
public static class ResourceExtensions public static class ResourceExtensions
{ {
public static readonly ResourceTypeFlag AllResourceTypes = Enum.GetValues<ResourceTypeFlag>().Aggregate((v, f) => v | f); public static readonly ResourceTypeFlag AllResourceTypes = ResourceTypeFlag.Values.Aggregate((v, f) => v | f);
public static readonly ResourceCategoryFlag AllResourceCategories = Enum.GetValues<ResourceCategoryFlag>().Aggregate((v, f) => v | f); public static readonly ResourceCategoryFlag AllResourceCategories = ResourceCategoryFlag.Values.Aggregate((v, f) => v | f);
public static ResourceTypeFlag ToFlag(this ResourceType type) public static ResourceTypeFlag ToFlag(this ResourceType type)
=> type switch => type switch

View file

@ -226,7 +226,7 @@ public partial class CombinedTexture
private sealed class CombineOperationCombo() : SimpleFilterCombo<CombineOp>(SimpleFilterType.None) private sealed class CombineOperationCombo() : SimpleFilterCombo<CombineOp>(SimpleFilterType.None)
{ {
private static readonly CombineOp[] UserValues = Enum.GetValues<CombineOp>().Where(c => (int)c >= 0).ToArray(); private static readonly CombineOp[] UserValues = CombineOp.Values.Where(c => (int)c >= 0).ToArray();
public override StringU8 DisplayString(in CombineOp value) public override StringU8 DisplayString(in CombineOp value)
=> new(value.ToLabelU8()); => new(value.ToLabelU8());
@ -243,7 +243,7 @@ public partial class CombinedTexture
private sealed class ResizeOperationCombo() : SimpleFilterCombo<ResizeOp>(SimpleFilterType.None) private sealed class ResizeOperationCombo() : SimpleFilterCombo<ResizeOp>(SimpleFilterType.None)
{ {
private static readonly ResizeOp[] UserValues = Enum.GetValues<ResizeOp>().Where(c => (int)c >= 0).ToArray(); private static readonly ResizeOp[] UserValues = ResizeOp.Values.Where(c => (int)c >= 0).ToArray();
public override StringU8 DisplayString(in ResizeOp value) public override StringU8 DisplayString(in ResizeOp value)
=> new(value.ToLabelU8()); => new(value.ToLabelU8());
@ -282,11 +282,11 @@ public partial class CombinedTexture
using (Im.Disabled(_combineOp != CombineOp.CopyChannels)) using (Im.Disabled(_combineOp != CombineOp.CopyChannels))
{ {
Im.Text("Copy"u8); Im.Text("Copy"u8);
foreach (var channel in Enum.GetValues<Channels>()) foreach (var channel in Channels.Values)
{ {
Im.Line.Same(); Im.Line.Same();
var copy = (_copyChannels & channel) != 0; var copy = (_copyChannels & channel) is not 0;
if (Im.Checkbox(channel.ToString(), ref copy)) if (Im.Checkbox($"{channel}", ref copy))
{ {
_copyChannels = copy ? _copyChannels | channel : _copyChannels & ~channel; _copyChannels = copy ? _copyChannels | channel : _copyChannels & ~channel;
ret = true; ret = true;

View file

@ -25,7 +25,9 @@ public unsafe class AtchCallerHook1 : FastHook<AtchCallerHook1.Delegate>, IDispo
private void Detour(DrawObjectData* data, uint slot, nint unk, Model playerModel) private void Detour(DrawObjectData* data, uint slot, nint unk, Model playerModel)
{ {
var collection = playerModel.Valid ? _collectionResolver.IdentifyCollection(playerModel.AsDrawObject, true) : _collectionResolver.DefaultCollection; var collection = playerModel.Valid
? _collectionResolver.IdentifyCollection(playerModel.AsDrawObject, true)
: _collectionResolver.DefaultCollection;
_metaState.AtchCollection.Push(collection); _metaState.AtchCollection.Push(collection);
Task.Result.Original(data, slot, unk, playerModel); Task.Result.Original(data, slot, unk, playerModel);
_metaState.AtchCollection.Pop(); _metaState.AtchCollection.Pop();
@ -33,6 +35,9 @@ public unsafe class AtchCallerHook1 : FastHook<AtchCallerHook1.Delegate>, IDispo
$"[AtchCaller1] Invoked on 0x{(ulong)data:X} with {slot}, {unk:X}, 0x{playerModel.Address:X}, identified to {collection.ModCollection.Identity.AnonymizedName}."); $"[AtchCaller1] Invoked on 0x{(ulong)data:X} with {slot}, {unk:X}, 0x{playerModel.Address:X}, identified to {collection.ModCollection.Identity.AnonymizedName}.");
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -33,6 +33,9 @@ public unsafe class AtchCallerHook2 : FastHook<AtchCallerHook2.Delegate>, IDispo
$"[AtchCaller2] Invoked on 0x{(ulong)data:X} with {slot}, {unk:X}, 0x{playerModel.Address:X}, {unk2}, identified to {collection.ModCollection.Identity.AnonymizedName}."); $"[AtchCaller2] Invoked on 0x{(ulong)data:X} with {slot}, {unk:X}, 0x{playerModel.Address:X}, {unk2}, identified to {collection.ModCollection.Identity.AnonymizedName}.");
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -32,6 +32,9 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
$"[GetEqdpAccessoryEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}."); $"[GetEqdpAccessoryEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}.");
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -31,6 +31,9 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
$"[GetEqdpEquipEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}."); $"[GetEqdpEquipEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}.");
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -36,6 +36,9 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
Penumbra.Log.Excessive($"[GetEqpFlags] Invoked on 0x{(nint)utility:X} with 0x{(ulong)armor:X}, returned 0x{(ulong)*flags:X16}."); Penumbra.Log.Excessive($"[GetEqpFlags] Invoked on 0x{(nint)utility:X} with 0x{(ulong)armor:X}, returned 0x{(ulong)*flags:X16}.");
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -58,6 +58,9 @@ public unsafe class EstHook : FastHook<EstHook.Delegate>, IDisposable
return new EstIdentifier(i, 0, gr); return new EstIdentifier(i, 0, gr);
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -36,6 +36,9 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
return ret; return ret;
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -68,6 +68,9 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
return ret; return ret;
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -78,6 +78,9 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
return scale; return scale;
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -72,6 +72,9 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
return scale; return scale;
} }
public void Dispose() public override void Dispose()
=> _metaState.Config.ModsEnabled -= Set; {
_metaState.Config.ModsEnabled -= Set;
base.Dispose();
}
} }

View file

@ -2,10 +2,10 @@ using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Resource; using FFXIVClientStructs.FFXIV.Client.System.Resource;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using FFXIVClientStructs.Interop;
using FFXIVClientStructs.STD; using FFXIVClientStructs.STD;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData; using Penumbra.GameData;
using ImSharp;
namespace Penumbra.Interop.Hooks.ResourceLoading; namespace Penumbra.Interop.Hooks.ResourceLoading;
@ -22,10 +22,10 @@ public unsafe class ResourceManagerService : Luna.IRequiredService
public ResourceHandle* FindResource(ResourceCategory cat, ResourceType ext, uint crc32) public ResourceHandle* FindResource(ResourceCategory cat, ResourceType ext, uint crc32)
{ {
ref var manager = ref *ResourceManager; ref var manager = ref *ResourceManager;
var catIdx = (uint)cat >> 0x18; var catIdx = (uint)cat >> 0x18;
cat = (ResourceCategory)(ushort)cat; cat = (ResourceCategory)(ushort)cat;
ref var category = ref manager.ResourceGraph->Containers[(int)cat]; ref var category = ref manager.ResourceGraph->Containers[(int)cat];
var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext); var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext);
if (extMap == null) if (extMap == null)
return null; return null;
@ -33,15 +33,17 @@ public unsafe class ResourceManagerService : Luna.IRequiredService
return ret == null ? null : ret->Value; return ret == null ? null : ret->Value;
} }
public delegate void ExtMapAction(ResourceCategory category, StdMap<uint, Pointer<StdMap<uint, Pointer<ResourceHandle>>>>* graph, int idx); public delegate void ExtMapAction(ResourceCategory category,
public delegate void ResourceMapAction(uint ext, StdMap<uint, Pointer<ResourceHandle>>* graph); StdMap<uint, FFXIVClientStructs.Interop.Pointer<StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>>>* graph, int idx);
public delegate void ResourceMapAction(uint ext, StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>* graph);
public delegate void ResourceAction(uint crc32, ResourceHandle* graph); public delegate void ResourceAction(uint crc32, ResourceHandle* graph);
/// <summary> Iterate through the entire graph calling an action on every ExtMap. </summary> /// <summary> Iterate through the entire graph calling an action on every ExtMap. </summary>
public void IterateGraphs(ExtMapAction action) public void IterateGraphs(ExtMapAction action)
{ {
ref var manager = ref *ResourceManager; ref var manager = ref *ResourceManager;
foreach (var resourceType in Enum.GetValues<ResourceCategory>().SkipLast(1)) foreach (var resourceType in ResourceCategory.Values.SkipLast(1))
{ {
ref var graph = ref manager.ResourceGraph->Containers[(int)resourceType]; ref var graph = ref manager.ResourceGraph->Containers[(int)resourceType];
for (var i = 0; i < 20; ++i) for (var i = 0; i < 20; ++i)
@ -54,11 +56,13 @@ public unsafe class ResourceManagerService : Luna.IRequiredService
} }
/// <summary> Iterate through a specific ExtMap calling an action on every resource map. </summary> /// <summary> Iterate through a specific ExtMap calling an action on every resource map. </summary>
public void IterateExtMap(StdMap<uint, Pointer<StdMap<uint, Pointer<ResourceHandle>>>>* map, ResourceMapAction action) public void IterateExtMap(
StdMap<uint, FFXIVClientStructs.Interop.Pointer<StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>>>* map,
ResourceMapAction action)
=> IterateMap(map, (ext, m) => action(ext, m.Value)); => IterateMap(map, (ext, m) => action(ext, m.Value));
/// <summary> Iterate through a specific resource map calling an action on every resource. </summary> /// <summary> Iterate through a specific resource map calling an action on every resource. </summary>
public void IterateResourceMap(StdMap<uint, Pointer<ResourceHandle>>* map, ResourceAction action) public void IterateResourceMap(StdMap<uint, FFXIVClientStructs.Interop.Pointer<ResourceHandle>>* map, ResourceAction action)
=> IterateMap(map, (crc, r) => action(crc, r.Value)); => IterateMap(map, (crc, r) => action(crc, r.Value));
/// <summary> Iterate through the entire graph calling an action on every resource. </summary> /// <summary> Iterate through the entire graph calling an action on every resource. </summary>

View file

@ -1,11 +1,11 @@
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using ImSharp;
using Penumbra.GameData.Interop; using Penumbra.GameData.Interop;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.PathResolving; using Penumbra.Interop.PathResolving;
using Penumbra.String; using Penumbra.String;
using static Penumbra.Interop.Structs.StructExtensions;
using Model = Penumbra.GameData.Interop.Model; using Model = Penumbra.GameData.Interop.Model;
namespace Penumbra.Interop.MaterialPreview; namespace Penumbra.Interop.MaterialPreview;
@ -54,7 +54,7 @@ public readonly record struct MaterialInfo(ObjectIndex ObjectIndex, DrawObjectTy
? m ? m
: CiByteString.Empty; : CiByteString.Empty;
var result = new List<MaterialInfo>(Enum.GetValues<DrawObjectType>().Length); var result = new List<MaterialInfo>(DrawObjectType.Values.Count);
foreach (var objectPtr in gameObjects) foreach (var objectPtr in gameObjects)
{ {
var gameObject = (Character*)objectPtr; var gameObject = (Character*)objectPtr;
@ -63,7 +63,7 @@ public readonly record struct MaterialInfo(ObjectIndex ObjectIndex, DrawObjectTy
var index = (ObjectIndex)gameObject->GameObject.ObjectIndex; var index = (ObjectIndex)gameObject->GameObject.ObjectIndex;
foreach (var type in Enum.GetValues<DrawObjectType>()) foreach (var type in DrawObjectType.Values)
{ {
var drawObject = GetDrawObject(type, objectPtr); var drawObject = GetDrawObject(type, objectPtr);
if (!drawObject.Valid) if (!drawObject.Valid)

View file

@ -1,5 +1,6 @@
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using ImSharp;
using Penumbra.Communication; using Penumbra.Communication;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
@ -41,8 +42,7 @@ public unsafe class CharacterUtility : IDisposable, Luna.IRequiredService
/// The relevant indices depend on which meta manipulations we allow for. /// 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> /// </summary>
public static readonly MetaIndex[] public static readonly MetaIndex[] RelevantIndices = MetaIndex.Values.ToArray();
RelevantIndices = Enum.GetValues<MetaIndex>();
public static readonly InternalIndex[] ReverseIndices public static readonly InternalIndex[] ReverseIndices
= Enumerable.Range(0, CharacterUtilityData.TotalNumResources) = Enumerable.Range(0, CharacterUtilityData.TotalNumResources)

View file

@ -1,3 +1,4 @@
using ImSharp;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
namespace Penumbra.Interop.Structs; namespace Penumbra.Interop.Structs;
@ -18,7 +19,7 @@ public unsafe struct CharacterUtilityData
public const int IndexSphereDArrayTex = 96; public const int IndexSphereDArrayTex = 96;
public static readonly MetaIndex[] EqdpIndices = Enum.GetNames<MetaIndex>() public static readonly MetaIndex[] EqdpIndices = Enum.GetNames<MetaIndex>()
.Zip(Enum.GetValues<MetaIndex>()) .Zip(MetaIndex.Values)
.Where(n => n.First.StartsWith("Eqdp")) .Where(n => n.First.StartsWith("Eqdp"))
.Select(n => n.Second).ToArray(); .Select(n => n.Second).ToArray();

View file

@ -1,4 +1,5 @@
using System.Collections.Frozen; using System.Collections.Frozen;
using ImSharp;
using Luna; using Luna;
using Penumbra.Collections.Cache; using Penumbra.Collections.Cache;
using Penumbra.Meta; using Penumbra.Meta;
@ -34,7 +35,7 @@ public class ModMetaEditor(
} }
public readonly FrozenDictionary<MetaManipulationType, OtherOptionData> OtherData = public readonly FrozenDictionary<MetaManipulationType, OtherOptionData> OtherData =
Enum.GetValues<MetaManipulationType>().ToFrozenDictionary(t => t, _ => new OtherOptionData()); MetaManipulationType.Values.ToFrozenDictionary(t => t, _ => new OtherOptionData());
public bool Changes { get; set; } public bool Changes { get; set; }
@ -46,7 +47,7 @@ public class ModMetaEditor(
public void Load(Mod mod, IModDataContainer currentOption) public void Load(Mod mod, IModDataContainer currentOption)
{ {
foreach (var type in Enum.GetValues<MetaManipulationType>()) foreach (var type in MetaManipulationType.Values)
OtherData[type].Clear(); OtherData[type].Clear();
foreach (var option in mod.AllDataContainers) foreach (var option in mod.AllDataContainers)

View file

@ -1,3 +1,4 @@
using ImSharp;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -45,13 +46,13 @@ public static class EquipmentSwap
var mtrlVariantTo = imcEntry.MaterialId; var mtrlVariantTo = imcEntry.MaterialId;
var skipFemale = false; var skipFemale = false;
var skipMale = false; var skipMale = false;
foreach (var gr in Enum.GetValues<GenderRace>()) foreach (var gr in GenderRace.Values)
{ {
switch (gr.Split().Item1) switch (gr.Split().Item1)
{ {
case Gender.Male when skipMale: continue; case Gender.Male when skipMale:
case Gender.Female when skipFemale: continue; case Gender.Female when skipFemale:
case Gender.MaleNpc when skipMale: continue; case Gender.MaleNpc when skipMale:
case Gender.FemaleNpc when skipFemale: continue; case Gender.FemaleNpc when skipFemale: continue;
} }
@ -137,13 +138,13 @@ public static class EquipmentSwap
var skipFemale = false; var skipFemale = false;
var skipMale = false; var skipMale = false;
foreach (var gr in Enum.GetValues<GenderRace>()) foreach (var gr in GenderRace.Values)
{ {
switch (gr.Split().Item1) switch (gr.Split().Item1)
{ {
case Gender.Male when skipMale: continue; case Gender.Male when skipMale:
case Gender.Female when skipFemale: continue; case Gender.Female when skipFemale:
case Gender.MaleNpc when skipMale: continue; case Gender.MaleNpc when skipMale:
case Gender.FemaleNpc when skipFemale: continue; case Gender.FemaleNpc when skipFemale: continue;
} }

View file

@ -1,3 +1,4 @@
using ImSharp;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
@ -31,7 +32,7 @@ public readonly struct ModMeta(Mod mod) : ISavable
{ {
var features = mod.RequiredFeatures; var features = mod.RequiredFeatures;
var array = new JArray(); var array = new JArray();
foreach (var flag in Enum.GetValues<FeatureFlags>()) foreach (var flag in FeatureFlags.Values)
{ {
if ((features & flag) is not FeatureFlags.None) if ((features & flag) is not FeatureFlags.None)
array.Add(flag.ToString()); array.Add(flag.ToString());

View file

@ -1,3 +1,4 @@
using ImSharp;
using Luna; using Luna;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -37,7 +38,7 @@ public class ConfigMigrationService(SaveService saveService, BackupService backu
private static void AddColors(Configuration config, bool forceSave) private static void AddColors(Configuration config, bool forceSave)
{ {
var save = false; var save = false;
foreach (var color in Enum.GetValues<ColorId>()) foreach (var color in ColorId.Values)
save |= config.Colors.TryAdd(color, color.Data().DefaultColor); save |= config.Colors.TryAdd(color, color.Data().DefaultColor);
if (save || forceSave) if (save || forceSave)

View file

@ -241,6 +241,6 @@ public class StainService : IService
public sealed class StainCombo(DictStain stainData) : FilterComboColors public sealed class StainCombo(DictStain stainData) : FilterComboColors
{ {
protected override IEnumerable<Item> GetItems() protected override IEnumerable<Item> GetItems()
=> stainData.Value.Select(t => new Item(new StringPair(t.Value.Name), t.Value.Dye, t.Key, t.Value.Gloss)).Prepend(None); => stainData.Value.Select(t => new Item(new StringPair(StringU8.CreateUnchecked(t.Value.Name)), t.Value.Dye, t.Key, t.Value.Gloss)).Prepend(None);
} }
} }

View file

@ -498,7 +498,7 @@ public class ItemSwapTab : IDisposable, ITab
using (var combo = Im.Combo.Begin("##fromType"u8, _slotFrom.ToNameU8())) using (var combo = Im.Combo.Begin("##fromType"u8, _slotFrom.ToNameU8()))
{ {
if (combo) if (combo)
foreach (var slot in Enum.GetValues<BetweenSlotTypes>()) foreach (var slot in BetweenSlotTypes.Values)
{ {
if (!Im.Selectable(slot.ToNameU8(), slot == _slotFrom) || slot == _slotFrom) if (!Im.Selectable(slot.ToNameU8(), slot == _slotFrom) || slot == _slotFrom)
continue; continue;
@ -778,5 +778,5 @@ public class ItemSwapTab : IDisposable, ITab
}; };
private static readonly IReadOnlyList<BetweenSlotTypes> AvailableToTypes = private static readonly IReadOnlyList<BetweenSlotTypes> AvailableToTypes =
Enum.GetValues<BetweenSlotTypes>().Where(s => s is not BetweenSlotTypes.Hat).ToArray(); BetweenSlotTypes.Values.Where(s => s is not BetweenSlotTypes.Hat).ToArray();
} }

View file

@ -178,7 +178,7 @@ public partial class MtrlTab
return false; return false;
var ret = false; var ret = false;
foreach (var mode in Enum.GetValues<TextureAddressMode>()) foreach (var mode in TextureAddressMode.Values)
{ {
if (Im.Selectable(mode.ToNameU8(), mode == value)) if (Im.Selectable(mode.ToNameU8(), mode == value))
{ {

View file

@ -90,7 +90,7 @@ public sealed class GlobalEqpMetaDrawer(ModMetaEditor editor, MetaFileManager me
return false; return false;
var ret = false; var ret = false;
foreach (var type in Enum.GetValues<GlobalEqpType>()) foreach (var type in GlobalEqpType.Values)
{ {
if (Im.Selectable(type.ToNameU8(), type == identifier.Type)) if (Im.Selectable(type.ToNameU8(), type == identifier.Type))
{ {

View file

@ -230,7 +230,7 @@ public partial class ModEditWindow : IndexedWindow, IDisposable
DrawMaterialReassignmentTab(); DrawMaterialReassignmentTab();
} }
private static readonly FrozenDictionary<GenderRace, StringU8> RaceCodeNames = Enum.GetValues<GenderRace>().ToFrozenDictionary(v => v, v => private static readonly FrozenDictionary<GenderRace, StringU8> RaceCodeNames = GenderRace.Values.ToFrozenDictionary(v => v, v =>
{ {
if (v is GenderRace.Unknown) if (v is GenderRace.Unknown)
return new StringU8("All Races and Genders"); return new StringU8("All Races and Genders");

View file

@ -258,6 +258,6 @@ public class ModMergeTab(ModMerger modMerger, ModComboWithoutCurrent combo) : IU
Im.Separator(); Im.Separator();
Im.Dummy(Vector2.One); Im.Dummy(Vector2.One);
using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder); using var color = ImGuiColor.Text.Push(Colors.RegexWarningBorder);
Im.TextWrapped(modMerger.Error.ToString()); Im.TextWrapped($"{modMerger.Error}");
} }
} }

View file

@ -181,10 +181,11 @@ public class ResourceTreeViewer(
using (Im.Id.Push("TreeCategoryFilter"u8)) using (Im.Id.Push("TreeCategoryFilter"u8))
{ {
foreach (var category in Enum.GetValues<TreeCategory>()) foreach (var category in TreeCategory.Values)
{ {
using var c = ImGuiColor.CheckMark.Push(CategoryColor(category).Value()); using var id = Im.Id.Push((int)category);
Im.Checkbox($"##{category}", ref _categoryFilter, category); using var c = ImGuiColor.CheckMark.Push(CategoryColor(category).Value());
Im.Checkbox(StringU8.Empty, ref _categoryFilter, category);
Im.Tooltip.OnHover(CategoryFilterDescription(category)); Im.Tooltip.OnHover(CategoryFilterDescription(category));
Im.Line.Same(0.0f, checkSpacing); Im.Line.Same(0.0f, checkSpacing);
} }

View file

@ -117,7 +117,7 @@ public class TutorialService(EphemeralConfig config) : Luna.IUiService
"You can now toggle mods as favorites using this button. You can filter for favorited mods in the mod selector. Favorites are stored locally, not within the mod, but independently of collections."u8) "You can now toggle mods as favorites using this button. You can filter for favorited mods in the mod selector. Favorites are stored locally, not within the mod, but independently of collections."u8)
.Register("Tags"u8, .Register("Tags"u8,
"Mods can now have two types of tags:\n\n- Local Tags are those that you can set for yourself. They are stored locally and are not saved in any way in the mod directory itself.\n- Mod Tags are stored in the mod metadata, are set by the mod creator and are exported together with the mod, they can only be edited in the Edit Mod tab.\n\nIf a mod has a tag in its Mod Tags, this overwrites any identical Local Tags.\n\nYou can filter for tags in the mod selector via 't:text'."u8) "Mods can now have two types of tags:\n\n- Local Tags are those that you can set for yourself. They are stored locally and are not saved in any way in the mod directory itself.\n- Mod Tags are stored in the mod metadata, are set by the mod creator and are exported together with the mod, they can only be edited in the Edit Mod tab.\n\nIf a mod has a tag in its Mod Tags, this overwrites any identical Local Tags.\n\nYou can filter for tags in the mod selector via 't:text'."u8)
.EnsureSize(Enum.GetValues<BasicTutorialSteps>().Length); .EnsureSize(BasicTutorialSteps.Values.Count);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void OpenTutorial(BasicTutorialSteps step) public void OpenTutorial(BasicTutorialSteps step)

View file

@ -84,7 +84,7 @@ public sealed class CollectionPanel(
Button(CollectionType.NonPlayerChild); Button(CollectionType.NonPlayerChild);
Button(CollectionType.NonPlayerElderly); Button(CollectionType.NonPlayerElderly);
foreach (var race in Enum.GetValues<SubRace>().Skip(1)) foreach (var race in SubRace.Values.Skip(1))
{ {
Button(CollectionTypeExtensions.FromParts(race, Gender.Male, false)); Button(CollectionTypeExtensions.FromParts(race, Gender.Male, false));
Button(CollectionTypeExtensions.FromParts(race, Gender.Female, false)); Button(CollectionTypeExtensions.FromParts(race, Gender.Female, false));
@ -691,9 +691,9 @@ public sealed class CollectionPanel(
/// <summary> Create names and border colors for special assignments. </summary> /// <summary> Create names and border colors for special assignments. </summary>
private static IReadOnlyDictionary<CollectionType, (StringU8 Name, Vector4 Border)> CreateButtons() private static IReadOnlyDictionary<CollectionType, (StringU8 Name, Vector4 Border)> CreateButtons()
{ {
var ret = Enum.GetValues<CollectionType>().ToDictionary(t => t, t => (new StringU8(t.ToName()), Vector4.Zero)); var ret = CollectionType.Values.ToDictionary(t => t, t => (new StringU8(t.ToName()), Vector4.Zero));
foreach (var race in Enum.GetValues<SubRace>().Skip(1)) foreach (var race in SubRace.Values.Skip(1))
{ {
Rgba32 color = race switch Rgba32 color = race switch
{ {
@ -749,7 +749,7 @@ public sealed class CollectionPanel(
Add(CollectionType.MaleNonPlayerCharacter, true, true); Add(CollectionType.MaleNonPlayerCharacter, true, true);
Add(CollectionType.FemaleNonPlayerCharacter, true, true); Add(CollectionType.FemaleNonPlayerCharacter, true, true);
var pre = true; var pre = true;
foreach (var race in Enum.GetValues<SubRace>().Skip(1)) foreach (var race in SubRace.Values.Skip(1))
{ {
Add(CollectionTypeExtensions.FromParts(race, Gender.Male, false), pre, !pre); Add(CollectionTypeExtensions.FromParts(race, Gender.Male, false), pre, !pre);
Add(CollectionTypeExtensions.FromParts(race, Gender.Female, false), pre, !pre); Add(CollectionTypeExtensions.FromParts(race, Gender.Female, false), pre, !pre);

View file

@ -9,7 +9,13 @@ using Penumbra.UI.Classes;
namespace Penumbra.UI.CollectionTab; namespace Penumbra.UI.CollectionTab;
public sealed class CollectionSelector(ActiveCollections active, TutorialService tutorial, IncognitoService incognito) : IPanel public sealed class CollectionSelector(
CollectionFilter filter,
CollectionStorage collections,
CommunicatorService communicator,
ActiveCollections active,
TutorialService tutorial,
IncognitoService incognito) : IPanel
{ {
public ReadOnlySpan<byte> Id public ReadOnlySpan<byte> Id
=> "##cs"u8; => "##cs"u8;
@ -38,7 +44,7 @@ public sealed class CollectionSelector(ActiveCollections active, TutorialService
public void Draw() public void Draw()
{ {
Im.Cursor.Y += Im.Style.FramePadding.Y; Im.Cursor.Y += Im.Style.FramePadding.Y;
var cache = CacheManager.Instance.GetOrCreateCache<Cache>(Im.Id.Current); var cache = CacheManager.Instance.GetOrCreateCache(Im.Id.Current, () => new Cache(filter, collections, communicator));
using var color = ImGuiColor.Header.Push(ColorId.SelectedCollection.Value()); using var color = ImGuiColor.Header.Push(ColorId.SelectedCollection.Value());
foreach (var item in cache) foreach (var item in cache)
{ {

View file

@ -20,7 +20,7 @@ public sealed class RaceCodeTab : IKnowledgeTab
return; return;
DrawHeaders(table); DrawHeaders(table);
foreach (var gr in Enum.GetValues<GenderRace>()) foreach (var gr in GenderRace.Values)
{ {
var (gender, race) = gr.Split(); var (gender, race) = gr.Split();
if (gender is not Gender.Male and not Gender.Female || race is ModelRace.Unknown) if (gender is not Gender.Male and not Gender.Female || race is ModelRace.Unknown)

View file

@ -24,7 +24,7 @@ public readonly struct ImcModGroupEditDrawer(ModGroupEditDrawer editor, ImcModGr
- Im.Font.CalculateSize("All Variants"u8).X - Im.Font.CalculateSize("All Variants"u8).X
- Im.Font.CalculateSize("Only Attributes"u8).X - Im.Font.CalculateSize("Only Attributes"u8).X
- 2 * Im.Style.FrameHeight; - 2 * Im.Style.FrameHeight;
ImEx.TextFramed(identifier.ToString(), new Vector2(width, 0), Rgba32.Transparent); ImEx.TextFramed($"{identifier}", new Vector2(width, 0), Rgba32.Transparent);
Im.Line.SameInner(); Im.Line.SameInner();
var allVariants = group.AllVariants; var allVariants = group.AllVariants;

View file

@ -176,7 +176,7 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
=> item.TypeName; => item.TypeName;
protected override IReadOnlyList<(RecordType Value, StringU8 Name)> EnumData protected override IReadOnlyList<(RecordType Value, StringU8 Name)> EnumData
=> Enum.GetValues<RecordType>().Select(t => (t, new StringU8(t.ToNameU8()))).ToArray(); => RecordType.Values.Select(t => (t, new StringU8(t.ToNameU8()))).ToArray();
protected override RecordType GetValue(in CachedRecord item, int globalIndex) protected override RecordType GetValue(in CachedRecord item, int globalIndex)
=> item.Record.RecordType; => item.Record.RecordType;
@ -304,7 +304,7 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
=> item.ResourceCategory; => item.ResourceCategory;
protected override IReadOnlyList<(ResourceCategoryFlag Value, StringU8 Name)> EnumData { get; } = protected override IReadOnlyList<(ResourceCategoryFlag Value, StringU8 Name)> EnumData { get; } =
Enum.GetValues<ResourceCategoryFlag>().Select(r => (r, new StringU8($"{r}"))).ToArray(); ResourceCategoryFlag.Values.Select(r => (r, new StringU8($"{r}"))).ToArray();
protected override ResourceCategoryFlag GetValue(in CachedRecord item, int globalIndex) protected override ResourceCategoryFlag GetValue(in CachedRecord item, int globalIndex)
=> item.Record.Category; => item.Record.Category;
@ -323,7 +323,7 @@ internal sealed class ResourceWatcherTable : TableBase<CachedRecord, TableCache<
} }
protected override IReadOnlyList<(ResourceTypeFlag Value, StringU8 Name)> EnumData { get; } = protected override IReadOnlyList<(ResourceTypeFlag Value, StringU8 Name)> EnumData { get; } =
Enum.GetValues<ResourceTypeFlag>().Select(r => (r, new StringU8(r.ToString().ToLowerInvariant()))).ToArray(); ResourceTypeFlag.Values.Select(r => (r, new StringU8(r.ToString().ToLowerInvariant()))).ToArray();
protected override StringU8 DisplayString(in CachedRecord item, int globalIndex) protected override StringU8 DisplayString(in CachedRecord item, int globalIndex)
=> item.ResourceType; => item.ResourceType;

View file

@ -403,7 +403,7 @@ public sealed class DebugTab : Window, ITab<TabType>
using var table = Im.Table.Begin("##Tasks"u8, 2, TableFlags.RowBackground); using var table = Im.Table.Begin("##Tasks"u8, 2, TableFlags.RowBackground);
if (table) if (table)
foreach (var task in _textureManager.Tasks) foreach (var task in _textureManager.Tasks)
table.DrawDataPair(task.Key.ToString()!, $"{task.Value.Item1.Status}"); table.DrawDataPair($"{task.Key}", $"{task.Value.Item1.Status}");
} }
} }

View file

@ -73,7 +73,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
table.SetupColumn("State"u8, TableColumnFlags.WidthStretch); table.SetupColumn("State"u8, TableColumnFlags.WidthStretch);
table.HeaderRow(); table.HeaderRow();
foreach (var condition in Enum.GetValues<ShapeConnectorCondition>()) foreach (var condition in ShapeConnectorCondition.Values)
{ {
foreach (var (shape, set) in data.ModCollection.MetaCache!.Shp.State(condition).OrderBy(shp => shp.Key)) foreach (var (shape, set) in data.ModCollection.MetaCache!.Shp.State(condition).OrderBy(shp => shp.Key))
{ {

View file

@ -48,7 +48,6 @@ public sealed class SettingsTab : ITab<TabType>
private readonly CrashHandlerService _crashService; private readonly CrashHandlerService _crashService;
private readonly MigrationSectionDrawer _migrationDrawer; private readonly MigrationSectionDrawer _migrationDrawer;
private readonly CollectionAutoSelector _autoSelector; private readonly CollectionAutoSelector _autoSelector;
private readonly CleanupService _cleanupService;
private readonly AttributeHook _attributeHook; private readonly AttributeHook _attributeHook;
private readonly PcpService _pcpService; private readonly PcpService _pcpService;
private readonly IntegrationSettingsRegistry _integrationSettings; private readonly IntegrationSettingsRegistry _integrationSettings;
@ -63,9 +62,8 @@ public sealed class SettingsTab : ITab<TabType>
FileWatcher fileWatcher, HttpApi httpApi, FileWatcher fileWatcher, HttpApi httpApi,
DalamudSubstitutionProvider dalamudSubstitutionProvider, FileCompactor compactor, DalamudConfigService dalamudConfig, DalamudSubstitutionProvider dalamudSubstitutionProvider, FileCompactor compactor, DalamudConfigService dalamudConfig,
IDataManager gameData, PredefinedTagManager predefinedTagConfig, CrashHandlerService crashService, IDataManager gameData, PredefinedTagManager predefinedTagConfig, CrashHandlerService crashService,
MigrationSectionDrawer migrationDrawer, CollectionAutoSelector autoSelector, CleanupService cleanupService, MigrationSectionDrawer migrationDrawer, CollectionAutoSelector autoSelector, AttributeHook attributeHook, PcpService pcpService,
AttributeHook attributeHook, PcpService pcpService, IntegrationSettingsRegistry integrationSettings, IntegrationSettingsRegistry integrationSettings, ModFileSystemDrawer modFileSystemDrawer)
ModFileSystemDrawer modFileSystemDrawer)
{ {
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_config = config; _config = config;
@ -89,7 +87,6 @@ public sealed class SettingsTab : ITab<TabType>
_crashService = crashService; _crashService = crashService;
_migrationDrawer = migrationDrawer; _migrationDrawer = migrationDrawer;
_autoSelector = autoSelector; _autoSelector = autoSelector;
_cleanupService = cleanupService;
_attributeHook = attributeHook; _attributeHook = attributeHook;
_pcpService = pcpService; _pcpService = pcpService;
_integrationSettings = integrationSettings; _integrationSettings = integrationSettings;
@ -423,7 +420,7 @@ public sealed class SettingsTab : ITab<TabType>
_config.RememberCollectionFilters, v => _config.RememberCollectionFilters = v); _config.RememberCollectionFilters, v => _config.RememberCollectionFilters = v);
Checkbox("Remember Changed Items Filters Across Sessions"u8, Checkbox("Remember Changed Items Filters Across Sessions"u8,
"Whether filters in the Changed Items tab should remember their input and start with their respective lists filtered identically to the last session."u8, "Whether filters in the Changed Items tab should remember their input and start with their respective lists filtered identically to the last session."u8,
_config.RememberChangedItemFilters, v => _config.RememberChangedItemFilters= v); _config.RememberChangedItemFilters, v => _config.RememberChangedItemFilters = v);
Checkbox("Remember Effective Changes Filters Across Sessions"u8, Checkbox("Remember Effective Changes Filters Across Sessions"u8,
"Whether filters in the Effective Changes tab should remember their input and start with their respective lists filtered identically to the last session."u8, "Whether filters in the Effective Changes tab should remember their input and start with their respective lists filtered identically to the last session."u8,
_config.RememberEffectiveChangesFilters, v => _config.RememberEffectiveChangesFilters = v); _config.RememberEffectiveChangesFilters, v => _config.RememberEffectiveChangesFilters = v);
@ -433,7 +430,6 @@ public sealed class SettingsTab : ITab<TabType>
Checkbox("Remember Resource Manager Filters Across Sessions"u8, Checkbox("Remember Resource Manager Filters Across Sessions"u8,
"Whether filters in the Resource Manager tab should remember their input and start with their respective lists filtered identically to the last session."u8, "Whether filters in the Resource Manager tab should remember their input and start with their respective lists filtered identically to the last session."u8,
_config.RememberResourceManagerFilters, v => _config.RememberResourceManagerFilters = v); _config.RememberResourceManagerFilters, v => _config.RememberResourceManagerFilters = v);
} }
/// <summary> Draw all settings that do not fit into other categories. </summary> /// <summary> Draw all settings that do not fit into other categories. </summary>
@ -828,7 +824,7 @@ public sealed class SettingsTab : ITab<TabType>
if (!Im.Tree.Header("Colors"u8)) if (!Im.Tree.Header("Colors"u8))
return; return;
foreach (var color in Enum.GetValues<ColorId>()) foreach (var color in ColorId.Values)
{ {
var (defaultColor, name, description) = color.Data(); var (defaultColor, name, description) = color.Data();
var currentColor = _config.Colors.GetValueOrDefault(color, defaultColor); var currentColor = _config.Colors.GetValueOrDefault(color, defaultColor);