Fix bug with weapon colorsets, add table buttons.

This commit is contained in:
Ottermandias 2024-02-18 14:45:34 +01:00
parent c85598acf4
commit cdaabc05e9
4 changed files with 92 additions and 14 deletions

View file

@ -26,6 +26,7 @@ public sealed unsafe class AdvancedDyePopup(
private ActorState _state = null!; private ActorState _state = null!;
private Actor _actor; private Actor _actor;
private byte _selectedMaterial = byte.MaxValue; private byte _selectedMaterial = byte.MaxValue;
private bool _anyChanged = false;
private bool ShouldBeDrawn() private bool ShouldBeDrawn()
{ {
@ -162,7 +163,7 @@ public sealed unsafe class AdvancedDyePopup(
} }
var size = new Vector2(7 * ImGui.GetFrameHeight() + 3 * ImGui.GetStyle().ItemInnerSpacing.X + 300 * ImGuiHelpers.GlobalScale, var size = new Vector2(7 * ImGui.GetFrameHeight() + 3 * ImGui.GetStyle().ItemInnerSpacing.X + 300 * ImGuiHelpers.GlobalScale,
17f * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y); 18 * ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().WindowPadding.Y + ImGui.GetStyle().ItemSpacing.Y);
ImGui.SetNextWindowSize(size); ImGui.SetNextWindowSize(size);
@ -192,12 +193,57 @@ public sealed unsafe class AdvancedDyePopup(
private void DrawTable(MaterialValueIndex materialIndex, in MtrlFile.ColorTable table) private void DrawTable(MaterialValueIndex materialIndex, in MtrlFile.ColorTable table)
{ {
using var disabled = ImRaii.Disabled(_state.IsLocked); using var disabled = ImRaii.Disabled(_state.IsLocked);
_anyChanged = false;
for (byte i = 0; i < MtrlFile.ColorTable.NumRows; ++i) for (byte i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
{ {
var index = materialIndex with { RowIndex = i }; var index = materialIndex with { RowIndex = i };
ref var row = ref table[i]; ref var row = ref table[i];
DrawRow(ref row, index, table); DrawRow(ref row, index, table);
} }
ImGui.Separator();
DrawAllRow(materialIndex, table);
}
private void DrawAllRow(MaterialValueIndex materialIndex, in MtrlFile.ColorTable table)
{
using var id = ImRaii.PushId(100);
var buttonSize = new Vector2(ImGui.GetFrameHeight());
ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Crosshairs.ToIconString(), buttonSize, "Highlight all affected colors on the character.",
false, true);
if (ImGui.IsItemHovered())
preview.OnHover(materialIndex with { RowIndex = byte.MaxValue }, _actor.Index, table);
ImGui.SameLine();
ImGui.AlignTextToFramePadding();
using (ImRaii.PushFont(UiBuilder.MonoFont))
{
ImGui.TextUnformatted("All Color Rows");
}
var spacing = ImGui.GetStyle().ItemInnerSpacing.X;
ImGui.SameLine(ImGui.GetWindowSize().X - 3 * buttonSize.X - 3 * spacing);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Clipboard.ToIconString(), buttonSize, "Export this table to your clipboard.", false,
true))
ColorRowClipboard.Table = table;
ImGui.SameLine(0, spacing);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Paste.ToIconString(), buttonSize,
"Import an exported table from your clipboard onto this table.", !ColorRowClipboard.IsTableSet, true))
foreach (var (row, idx) in ColorRowClipboard.Table.WithIndex())
{
var internalRow = new ColorRow(row);
var slot = materialIndex.ToEquipSlot();
var weapon = slot is EquipSlot.MainHand or EquipSlot.OffHand
? _state.ModelData.Weapon(slot)
: _state.ModelData.Armor(slot).ToWeapon(0);
var value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual);
stateManager.ChangeMaterialValue(_state!, materialIndex with { RowIndex = (byte)idx }, value, ApplySettings.Manual);
}
ImGui.SameLine(0, spacing);
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.UndoAlt.ToIconString(), buttonSize, "Reset this table to game state.", !_anyChanged,
true))
for (byte i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
stateManager.ResetMaterialValue(_state, materialIndex with { RowIndex = (byte)i }, ApplySettings.Game);
} }
private void DrawRow(ref MtrlFile.ColorTable.Row row, MaterialValueIndex index, in MtrlFile.ColorTable table) private void DrawRow(ref MtrlFile.ColorTable.Row row, MaterialValueIndex index, in MtrlFile.ColorTable table)
@ -213,6 +259,10 @@ public sealed unsafe class AdvancedDyePopup(
: _state.ModelData.Armor(slot).ToWeapon(0); : _state.ModelData.Armor(slot).ToWeapon(0);
value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual); value = new MaterialValueState(internalRow, internalRow, weapon, StateSource.Manual);
} }
else
{
_anyChanged = true;
}
var buttonSize = new Vector2(ImGui.GetFrameHeight()); var buttonSize = new Vector2(ImGui.GetFrameHeight());
ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Crosshairs.ToIconString(), buttonSize, "Highlight the affected colors on the character.", ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Crosshairs.ToIconString(), buttonSize, "Highlight the affected colors on the character.",

View file

@ -1,13 +1,27 @@
using Glamourer.Interop.Material; using Glamourer.Interop.Material;
using Penumbra.GameData.Files;
namespace Glamourer.Gui.Materials; namespace Glamourer.Gui.Materials;
public static class ColorRowClipboard public static class ColorRowClipboard
{ {
private static ColorRow _row; private static ColorRow _row;
private static MtrlFile.ColorTable _table;
public static bool IsSet { get; private set; } public static bool IsSet { get; private set; }
public static bool IsTableSet { get; private set; }
public static MtrlFile.ColorTable Table
{
get => _table;
set
{
IsTableSet = true;
_table = value;
}
}
public static ColorRow Row public static ColorRow Row
{ {
get => _row; get => _row;

View file

@ -29,21 +29,20 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable
private void Reset() private void Reset()
{ {
if (!LastValueIndex.Valid || _lastObjectIndex == ObjectIndex.AnyIndex) if (LastValueIndex.DrawObject is MaterialValueIndex.DrawObjectType.Invalid || _lastObjectIndex == ObjectIndex.AnyIndex)
return; return;
var actor = (Actor)_objects.GetObjectAddress(_lastObjectIndex.Index); var actor = (Actor)_objects.GetObjectAddress(_lastObjectIndex.Index);
if (actor.IsCharacter && LastValueIndex.TryGetTexture(actor, out var texture)) if (actor.IsCharacter && LastValueIndex.TryGetTexture(actor, out var texture))
MaterialService.ReplaceColorTable(texture, LastOriginalColorTable); MaterialService.ReplaceColorTable(texture, LastOriginalColorTable);
Glamourer.Log.Information($"Reset {_lastObjectIndex} {LastValueIndex}");
LastValueIndex = MaterialValueIndex.Invalid; LastValueIndex = MaterialValueIndex.Invalid;
_lastObjectIndex = ObjectIndex.AnyIndex; _lastObjectIndex = ObjectIndex.AnyIndex;
} }
private void OnFramework(IFramework _) private void OnFramework(IFramework _)
{ {
if (!_valueIndex.Valid || _objectIndex == ObjectIndex.AnyIndex) if (_valueIndex.DrawObject is MaterialValueIndex.DrawObjectType.Invalid || _objectIndex == ObjectIndex.AnyIndex)
{ {
Reset(); Reset();
_valueIndex = MaterialValueIndex.Invalid; _valueIndex = MaterialValueIndex.Invalid;
@ -69,10 +68,24 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable
if (_valueIndex.TryGetTexture(actor, out var texture)) if (_valueIndex.TryGetTexture(actor, out var texture))
{ {
var diffuse = CalculateDiffuse(); var diffuse = CalculateDiffuse();
var table = LastOriginalColorTable; var emissive = diffuse / 8;
table[_valueIndex.RowIndex].Diffuse = diffuse; var table = LastOriginalColorTable;
table[_valueIndex.RowIndex].Emissive = diffuse / 8; if (_valueIndex.RowIndex != byte.MaxValue)
{
table[_valueIndex.RowIndex].Diffuse = diffuse;
table[_valueIndex.RowIndex].Emissive = emissive;
}
else
{
for (var i = 0; i < MtrlFile.ColorTable.NumRows; ++i)
{
table[i].Diffuse = diffuse;
table[i].Emissive = emissive;
}
}
MaterialService.ReplaceColorTable(texture, table); MaterialService.ReplaceColorTable(texture, table);
} }
@ -82,12 +95,12 @@ public sealed unsafe class LiveColorTablePreviewer : IService, IDisposable
public void OnHover(MaterialValueIndex index, ObjectIndex objectIndex, MtrlFile.ColorTable table) public void OnHover(MaterialValueIndex index, ObjectIndex objectIndex, MtrlFile.ColorTable table)
{ {
if (_valueIndex.Valid) if (_valueIndex.DrawObject is not MaterialValueIndex.DrawObjectType.Invalid)
return; return;
_valueIndex = index; _valueIndex = index;
_objectIndex = objectIndex; _objectIndex = objectIndex;
if (!LastValueIndex.Valid if (LastValueIndex.DrawObject is MaterialValueIndex.DrawObjectType.Invalid
|| _lastObjectIndex == ObjectIndex.AnyIndex || _lastObjectIndex == ObjectIndex.AnyIndex
|| LastValueIndex.MaterialIndex != _valueIndex.MaterialIndex || LastValueIndex.MaterialIndex != _valueIndex.MaterialIndex
|| LastValueIndex.DrawObject != _valueIndex.DrawObject || LastValueIndex.DrawObject != _valueIndex.DrawObject

View file

@ -74,15 +74,16 @@ public sealed unsafe class PrepareColorSet
public static bool TryGetColorTable(Actor actor, MaterialValueIndex index, out MtrlFile.ColorTable table) public static bool TryGetColorTable(Actor actor, MaterialValueIndex index, out MtrlFile.ColorTable table)
{ {
var idx = index.SlotIndex * MaterialService.MaterialsPerModel + index.MaterialIndex; var idx = index.SlotIndex * MaterialService.MaterialsPerModel + index.MaterialIndex;
var model = actor.Model.AsCharacterBase; if (!index.TryGetModel(actor, out var model))
var handle = (MaterialResourceHandle*)model->Materials[idx]; return false;
var handle = (MaterialResourceHandle*)model.AsCharacterBase->Materials[idx];
if (handle == null) if (handle == null)
{ {
table = default; table = default;
return false; return false;
} }
return TryGetColorTable(model, handle, GetStain(), out table); return TryGetColorTable(model.AsCharacterBase, handle, GetStain(), out table);
StainId GetStain() StainId GetStain()
{ {