Fix issue with shapes/attributes not checking the groups correctly.

This commit is contained in:
Ottermandias 2025-05-23 11:29:52 +02:00
parent 1bdbfe22c1
commit 08c9124858
2 changed files with 45 additions and 36 deletions

View file

@ -21,43 +21,39 @@ public sealed class ShapeAttributeHashSet : Dictionary<(HumanSlot Slot, PrimaryI
private readonly BitArray _allIds = new((ShapeAttributeManager.ModelSlotSize + 1) * GenderRaceValues.Count);
public bool this[HumanSlot slot]
=> slot is HumanSlot.Unknown ? All : _allIds[(int)slot * GenderRaceIndices.Count];
public bool this[GenderRace genderRace]
=> GenderRaceIndices.TryGetValue(genderRace, out var index)
&& _allIds[ShapeAttributeManager.ModelSlotSize * GenderRaceIndices.Count + index];
public bool this[HumanSlot slot, GenderRace genderRace]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private bool CheckGroups(HumanSlot slot, GenderRace genderRace)
{
get
{
if (!GenderRaceIndices.TryGetValue(genderRace, out var index))
return false;
if (All || this[slot])
return true;
if (_allIds[ShapeAttributeManager.ModelSlotSize * GenderRaceIndices.Count + index])
return true;
if (!GenderRaceIndices.TryGetValue(genderRace, out var index))
return false;
return _allIds[(int)slot * GenderRaceIndices.Count + index];
}
set
{
if (!GenderRaceIndices.TryGetValue(genderRace, out var index))
return;
if (_allIds[ToIndex(HumanSlot.Unknown, index)])
return true;
var genderRaceCount = GenderRaceValues.Count;
if (slot is HumanSlot.Unknown)
_allIds[ShapeAttributeManager.ModelSlotSize * genderRaceCount + index] = value;
else
_allIds[(int)slot * genderRaceCount + index] = value;
}
return _allIds[ToIndex(slot, index)];
}
public bool this[HumanSlot slot]
=> _allIds[ToIndex(slot, 0)];
public bool this[GenderRace genderRace]
=> ToIndex(HumanSlot.Unknown, genderRace, out var index) && _allIds[index];
public bool this[HumanSlot slot, GenderRace genderRace]
=> ToIndex(slot, genderRace, out var index) && _allIds[index];
public bool All
=> _allIds[ShapeAttributeManager.ModelSlotSize * GenderRaceIndices.Count];
=> _allIds[AllIndex];
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private static int ToIndex(HumanSlot slot, int genderRaceIndex)
=> slot is HumanSlot.Unknown ? genderRaceIndex + AllIndex : genderRaceIndex + (int)slot * GenderRaceValues.Count;
public bool Contains(HumanSlot slot, PrimaryId id, GenderRace genderRace)
=> All || this[slot, genderRace] || ContainsEntry(slot, id, genderRace);
=> CheckGroups(slot, genderRace) || ContainsEntry(slot, id, genderRace);
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private bool ContainsEntry(HumanSlot slot, PrimaryId id, GenderRace genderRace)
@ -72,9 +68,9 @@ public sealed class ShapeAttributeHashSet : Dictionary<(HumanSlot Slot, PrimaryI
if (!id.HasValue)
{
var slotIndex = slot is HumanSlot.Unknown ? ShapeAttributeManager.ModelSlotSize : (int)slot;
var old = _allIds[slotIndex * GenderRaceIndices.Count + index];
_allIds[slotIndex * GenderRaceIndices.Count + index] = value;
var slotIndex = ToIndex(slot, index);
var old = _allIds[slotIndex];
_allIds[slotIndex] = value;
return old != value;
}
@ -120,4 +116,16 @@ public sealed class ShapeAttributeHashSet : Dictionary<(HumanSlot Slot, PrimaryI
public bool IsEmpty
=> !_allIds.HasAnySet() && Count is 0;
private static readonly int AllIndex = ShapeAttributeManager.ModelSlotSize * GenderRaceValues.Count;
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private static bool ToIndex(HumanSlot slot, GenderRace genderRace, out int index)
{
if (!GenderRaceIndices.TryGetValue(genderRace, out index))
return false;
index = ToIndex(slot, index);
return true;
}
}

View file

@ -1,6 +1,7 @@
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using ImGuiNET;
using OtterGui.Extensions;
using OtterGui.Services;
using OtterGui.Text;
using Penumbra.Collections.Cache;
@ -167,7 +168,7 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
ImUtf8.TableSetupColumn("Slot"u8, ImGuiTableColumnFlags.WidthFixed, 150 * ImUtf8.GlobalScale);
ImUtf8.TableSetupColumn("Address"u8, ImGuiTableColumnFlags.WidthFixed, UiBuilder.MonoFont.GetCharAdvance('0') * 14);
ImUtf8.TableSetupColumn("Mask"u8, ImGuiTableColumnFlags.WidthFixed, UiBuilder.MonoFont.GetCharAdvance('0') * 8);
ImUtf8.TableSetupColumn("Count"u8, ImGuiTableColumnFlags.WidthFixed, 30 * ImUtf8.GlobalScale);
ImUtf8.TableSetupColumn("Count"u8, ImGuiTableColumnFlags.WidthFixed, 30 * ImUtf8.GlobalScale);
ImUtf8.TableSetupColumn("Shapes"u8, ImGuiTableColumnFlags.WidthStretch);
ImGui.TableHeadersRow();
@ -187,9 +188,9 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
ImUtf8.DrawTableColumn($"{mask:X8}");
ImUtf8.DrawTableColumn($"{model->ModelResourceHandle->Shapes.Count}");
ImGui.TableNextColumn();
foreach (var (shape, idx) in model->ModelResourceHandle->Shapes)
foreach (var ((shape, flag), idx) in model->ModelResourceHandle->Shapes.WithIndex())
{
var disabled = (mask & (1u << idx)) is 0;
var disabled = (mask & (1u << flag)) is 0;
using var color = ImRaii.PushColor(ImGuiCol.Text, disabledColor, disabled);
ImUtf8.Text(shape.AsSpan());
ImGui.SameLine(0, 0);
@ -241,9 +242,9 @@ public class ShapeInspector(ObjectManager objects, CollectionResolver resolver)
ImUtf8.DrawTableColumn($"{mask:X8}");
ImUtf8.DrawTableColumn($"{model->ModelResourceHandle->Attributes.Count}");
ImGui.TableNextColumn();
foreach (var (attribute, idx) in model->ModelResourceHandle->Attributes)
foreach (var ((attribute, flag), idx) in model->ModelResourceHandle->Attributes.WithIndex())
{
var disabled = (mask & (1u << idx)) is 0;
var disabled = (mask & (1u << flag)) is 0;
using var color = ImRaii.PushColor(ImGuiCol.Text, disabledColor, disabled);
ImUtf8.Text(attribute.AsSpan());
ImGui.SameLine(0, 0);