mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-13 12:14:18 +01:00
Add some valid options for material values.
This commit is contained in:
parent
ef2d9ba207
commit
0bc9fc872e
3 changed files with 52 additions and 18 deletions
|
|
@ -57,7 +57,7 @@ public class GlamourerChangelog
|
||||||
.RegisterEntry(
|
.RegisterEntry(
|
||||||
"This was a considerable backend change on both automation sets and design application. I may have messed up and introduced bugs. Please let me know if something does not work right anymore.",
|
"This was a considerable backend change on both automation sets and design application. I may have messed up and introduced bugs. Please let me know if something does not work right anymore.",
|
||||||
1)
|
1)
|
||||||
.RegisterHighlight("Added advanced dye options for equipment. You can now runtime-edit the color sets of your gear.")
|
.RegisterHighlight("Added advanced dye options for equipment. You can now live-edit the color sets of your gear.")
|
||||||
.RegisterEntry(
|
.RegisterEntry(
|
||||||
"The logic for this is very complicated and may interfere with other options or not update correctly, it will need a lot of testing.",
|
"The logic for this is very complicated and may interfere with other options or not update correctly, it will need a lot of testing.",
|
||||||
1)
|
1)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface;
|
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||||
using FFXIVClientStructs.Interop;
|
using FFXIVClientStructs.Interop;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Interop.Material;
|
using Glamourer.Interop.Material;
|
||||||
|
|
@ -13,6 +13,7 @@ using OtterGui.Raii;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
|
using Penumbra.String;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Materials;
|
namespace Glamourer.Gui.Materials;
|
||||||
|
|
||||||
|
|
@ -68,6 +69,20 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
ImGuiUtil.HoverTooltip("Open advanced dyes for this slot.");
|
ImGuiUtil.HoverTooltip("Open advanced dyes for this slot.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private (string Path, string GamePath) ResourceName(MaterialValueIndex index)
|
||||||
|
{
|
||||||
|
var materialHandle = (MaterialResourceHandle*)_actor.Model.AsCharacterBase->MaterialsSpan[
|
||||||
|
index.MaterialIndex + index.SlotIndex * MaterialService.MaterialsPerModel].Value;
|
||||||
|
var model = _actor.Model.AsCharacterBase->ModelsSpan[index.SlotIndex].Value;
|
||||||
|
var modelHandle = model == null ? null : model->ModelResourceHandle;
|
||||||
|
var path = materialHandle == null
|
||||||
|
? string.Empty
|
||||||
|
: ByteString.FromSpanUnsafe(materialHandle->ResourceHandle.FileName.AsSpan(), true).ToString();
|
||||||
|
var gamePath = modelHandle == null
|
||||||
|
? string.Empty
|
||||||
|
: modelHandle->GetMaterialFileNameBySlotAsString(index.MaterialIndex);
|
||||||
|
return (path, gamePath);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawTabBar(ReadOnlySpan<Pointer<Texture>> textures, ref bool firstAvailable)
|
private void DrawTabBar(ReadOnlySpan<Pointer<Texture>> textures, ref bool firstAvailable)
|
||||||
{
|
{
|
||||||
|
|
@ -79,6 +94,7 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
{
|
{
|
||||||
var index = _drawIndex!.Value with { MaterialIndex = i };
|
var index = _drawIndex!.Value with { MaterialIndex = i };
|
||||||
var available = index.TryGetTexture(textures, out var texture) && index.TryGetColorTable(texture, out var table);
|
var available = index.TryGetTexture(textures, out var texture) && index.TryGetColorTable(texture, out var table);
|
||||||
|
|
||||||
if (index == preview.LastValueIndex with { RowIndex = 0 })
|
if (index == preview.LastValueIndex with { RowIndex = 0 })
|
||||||
table = preview.LastOriginalColorTable;
|
table = preview.LastOriginalColorTable;
|
||||||
|
|
||||||
|
|
@ -91,11 +107,16 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
firstAvailable = false;
|
firstAvailable = false;
|
||||||
|
|
||||||
using var tab = _label.TabItem(i, select);
|
using var tab = _label.TabItem(i, select);
|
||||||
if (!available)
|
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
{
|
{
|
||||||
using var disabled = ImRaii.Enabled();
|
using var enabled = ImRaii.Enabled();
|
||||||
ImGuiUtil.HoverTooltip("This material does not exist or does not have an associated color set.",
|
var (path, gamePath) = ResourceName(index);
|
||||||
ImGuiHoveredFlags.AllowWhenDisabled);
|
if (gamePath.Length == 0 || path.Length == 0)
|
||||||
|
ImGui.SetTooltip("This material does not exist.");
|
||||||
|
else if (!available)
|
||||||
|
ImGui.SetTooltip($"This material does not have an associated color set.\n\n{gamePath}\n{path}");
|
||||||
|
else
|
||||||
|
ImGui.SetTooltip($"{gamePath}\n{path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tab.Success || select is ImGuiTabItemFlags.SetSelected) && available)
|
if ((tab.Success || select is ImGuiTabItemFlags.SetSelected) && available)
|
||||||
|
|
@ -186,7 +207,7 @@ public sealed unsafe class AdvancedDyePopup(
|
||||||
if (!changed)
|
if (!changed)
|
||||||
{
|
{
|
||||||
var internalRow = new ColorRow(row);
|
var internalRow = new ColorRow(row);
|
||||||
var slot = index.ToSlot();
|
var slot = index.ToEquipSlot();
|
||||||
var weapon = slot is EquipSlot.MainHand or EquipSlot.OffHand
|
var weapon = slot is EquipSlot.MainHand or EquipSlot.OffHand
|
||||||
? _state.ModelData.Weapon(slot)
|
? _state.ModelData.Weapon(slot)
|
||||||
: _state.ModelData.Armor(slot).ToWeapon(0);
|
: _state.ModelData.Armor(slot).ToWeapon(0);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public readonly record struct MaterialValueIndex(
|
||||||
=> ToKey(DrawObject, SlotIndex, MaterialIndex, RowIndex);
|
=> ToKey(DrawObject, SlotIndex, MaterialIndex, RowIndex);
|
||||||
|
|
||||||
public bool Valid
|
public bool Valid
|
||||||
=> Validate(DrawObject) && ValidateSlot(SlotIndex) && ValidateMaterial(MaterialIndex) && ValidateRow(RowIndex);
|
=> Validate(DrawObject) && ValidateSlot(DrawObject, SlotIndex) && ValidateMaterial(MaterialIndex) && ValidateRow(RowIndex);
|
||||||
|
|
||||||
public static bool FromKey(uint key, out MaterialValueIndex index)
|
public static bool FromKey(uint key, out MaterialValueIndex index)
|
||||||
{
|
{
|
||||||
|
|
@ -42,7 +42,7 @@ public readonly record struct MaterialValueIndex(
|
||||||
return Invalid;
|
return Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EquipSlot ToSlot()
|
public EquipSlot ToEquipSlot()
|
||||||
=> DrawObject switch
|
=> DrawObject switch
|
||||||
{
|
{
|
||||||
DrawObjectType.Human when SlotIndex < 10 => ((uint)SlotIndex).ToEquipSlot(),
|
DrawObjectType.Human when SlotIndex < 10 => ((uint)SlotIndex).ToEquipSlot(),
|
||||||
|
|
@ -155,8 +155,14 @@ public readonly record struct MaterialValueIndex(
|
||||||
public static bool Validate(DrawObjectType type)
|
public static bool Validate(DrawObjectType type)
|
||||||
=> type is not DrawObjectType.Invalid && Enum.IsDefined(type);
|
=> type is not DrawObjectType.Invalid && Enum.IsDefined(type);
|
||||||
|
|
||||||
public static bool ValidateSlot(byte slotIndex)
|
public static bool ValidateSlot(DrawObjectType type, byte slotIndex)
|
||||||
=> slotIndex < 10;
|
=> type switch
|
||||||
|
{
|
||||||
|
DrawObjectType.Human => slotIndex < 14,
|
||||||
|
DrawObjectType.Mainhand => slotIndex == 0,
|
||||||
|
DrawObjectType.Offhand => slotIndex == 0,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
public static bool ValidateMaterial(byte materialIndex)
|
public static bool ValidateMaterial(byte materialIndex)
|
||||||
=> materialIndex < MaterialService.MaterialsPerModel;
|
=> materialIndex < MaterialService.MaterialsPerModel;
|
||||||
|
|
@ -178,12 +184,19 @@ public readonly record struct MaterialValueIndex(
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
=> DrawObject switch
|
||||||
var slot = ToSlot();
|
{
|
||||||
return slot is EquipSlot.Unknown
|
DrawObjectType.Invalid => "Invalid",
|
||||||
? $"{DrawObject} Slot {SlotIndex} Material #{MaterialIndex + 1} Row #{RowIndex + 1}"
|
DrawObjectType.Human when SlotIndex < 10 =>
|
||||||
: $"{slot.ToName()} Material #{MaterialIndex + 1} Row #{RowIndex + 1}";
|
$"{((uint)SlotIndex).ToEquipSlot().ToName()} Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
}
|
DrawObjectType.Human when SlotIndex == 10 => $"BodySlot.Hair.ToString() Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
DrawObjectType.Human when SlotIndex == 11 => $"BodySlot.Face.ToString() Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
DrawObjectType.Human when SlotIndex == 12 => $"{BodySlot.Tail} / {BodySlot.Ear} Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
DrawObjectType.Human when SlotIndex == 13 => $"Connectors Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
DrawObjectType.Mainhand when SlotIndex == 0 => $"{EquipSlot.MainHand.ToName()} Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
DrawObjectType.Offhand when SlotIndex == 0 => $"{EquipSlot.OffHand.ToName()} Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
_ => $"{DrawObject} Slot {SlotIndex} Material #{MaterialIndex + 1} Row #{RowIndex + 1}",
|
||||||
|
};
|
||||||
|
|
||||||
private class Converter : JsonConverter<MaterialValueIndex>
|
private class Converter : JsonConverter<MaterialValueIndex>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue