mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Add Palette+ Import.
This commit is contained in:
parent
ada0c6f479
commit
a50b63f67e
4 changed files with 166 additions and 6 deletions
|
|
@ -35,6 +35,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public bool ShowQuickBarInTabs { get; set; } = true;
|
public bool ShowQuickBarInTabs { get; set; } = true;
|
||||||
public bool OpenWindowAtStart { get; set; } = false;
|
public bool OpenWindowAtStart { get; set; } = false;
|
||||||
public bool UseAdvancedParameters { get; set; } = false;
|
public bool UseAdvancedParameters { get; set; } = false;
|
||||||
|
public bool ShowPalettePlusImport { get; set; } = true;
|
||||||
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
|
||||||
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
|
||||||
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.GameData;
|
using Glamourer.GameData;
|
||||||
|
using Glamourer.Interop.PalettePlus;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
@ -8,11 +9,19 @@ using OtterGui.Services;
|
||||||
|
|
||||||
namespace Glamourer.Gui.Customization;
|
namespace Glamourer.Gui.Customization;
|
||||||
|
|
||||||
public class CustomizeParameterDrawer(Configuration config) : IService
|
public class CustomizeParameterDrawer(Configuration config, PaletteImport import) : IService
|
||||||
{
|
{
|
||||||
|
private readonly Dictionary<Design, CustomizeParameterData> _lastData = [];
|
||||||
|
private string _paletteName = string.Empty;
|
||||||
|
private CustomizeParameterData _data;
|
||||||
|
private float _width;
|
||||||
|
private bool _foundPalette;
|
||||||
|
|
||||||
|
|
||||||
public void Draw(DesignManager designManager, Design design)
|
public void Draw(DesignManager designManager, Design design)
|
||||||
{
|
{
|
||||||
using var _ = EnsureSize();
|
using var _ = EnsureSize();
|
||||||
|
DrawPaletteImport(designManager, design);
|
||||||
foreach (var flag in CustomizeParameterExtensions.RgbFlags)
|
foreach (var flag in CustomizeParameterExtensions.RgbFlags)
|
||||||
DrawColorInput3(CustomizeParameterDrawData.FromDesign(designManager, design, flag));
|
DrawColorInput3(CustomizeParameterDrawData.FromDesign(designManager, design, flag));
|
||||||
|
|
||||||
|
|
@ -26,11 +35,54 @@ public class CustomizeParameterDrawer(Configuration config) : IService
|
||||||
DrawValueInput(CustomizeParameterDrawData.FromDesign(designManager, design, flag));
|
DrawValueInput(CustomizeParameterDrawData.FromDesign(designManager, design, flag));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImRaii.IEndObject EnsureSize()
|
private void DrawPaletteImport(DesignManager manager, Design design)
|
||||||
{
|
{
|
||||||
var iconSize = ImGui.GetTextLineHeight() * 2 + ImGui.GetStyle().ItemSpacing.Y + 4 * ImGui.GetStyle().FramePadding.Y;
|
if (!config.ShowPalettePlusImport)
|
||||||
var width = 6 * iconSize + 4 * ImGui.GetStyle().ItemInnerSpacing.X;
|
return;
|
||||||
return ImRaii.ItemWidth(width);
|
|
||||||
|
var spacing = ImGui.GetStyle().ItemInnerSpacing.X;
|
||||||
|
|
||||||
|
if (ImGui.InputTextWithHint("##import", "Palette Name...", ref _paletteName, 256))
|
||||||
|
{
|
||||||
|
_data = design.DesignData.Parameters;
|
||||||
|
_foundPalette = import.TryRead(_paletteName, ref _data);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine(0, spacing);
|
||||||
|
var value = true;
|
||||||
|
if (ImGui.Checkbox("Show Import", ref value))
|
||||||
|
{
|
||||||
|
config.ShowPalettePlusImport = false;
|
||||||
|
config.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiUtil.HoverTooltip("Hide the Palette+ Import bar from all designs. You can re-enable it in Glamourers interface settings.");
|
||||||
|
|
||||||
|
var buttonWidth = new Vector2((_width - spacing) / 2, 0);
|
||||||
|
var tt = _foundPalette
|
||||||
|
? $"Apply the imported data from the Palette+ palette [{_paletteName}] to this design."
|
||||||
|
: $"The palette [{_paletteName}] could not be imported from your Palette+ configuration.";
|
||||||
|
if (ImGuiUtil.DrawDisabledButton("Apply Import", buttonWidth, tt, !_foundPalette || design.WriteProtected()))
|
||||||
|
{
|
||||||
|
// Reload Data in case anything changed since entering text.
|
||||||
|
_data = design.DesignData.Parameters;
|
||||||
|
_foundPalette = import.TryRead(_paletteName, ref _data);
|
||||||
|
_lastData[design] = design.DesignData.Parameters;
|
||||||
|
foreach (var parameter in CustomizeParameterExtensions.AllFlags)
|
||||||
|
manager.ChangeCustomizeParameter(design, parameter, _data[parameter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine(0, spacing);
|
||||||
|
var enabled = _lastData.TryGetValue(design, out var oldData);
|
||||||
|
tt = enabled
|
||||||
|
? $"Revert to the last set of advanced customization parameters of [{design.Name}] before importing."
|
||||||
|
: $"You have not imported any data that could be reverted for [{design.Name}].";
|
||||||
|
if (ImGuiUtil.DrawDisabledButton("Revert Import", buttonWidth, tt, !enabled || design.WriteProtected()))
|
||||||
|
{
|
||||||
|
_lastData.Remove(design);
|
||||||
|
foreach (var parameter in CustomizeParameterExtensions.AllFlags)
|
||||||
|
manager.ChangeCustomizeParameter(design, parameter, oldData[parameter]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(StateManager stateManager, ActorState state)
|
public void Draw(StateManager stateManager, ActorState state)
|
||||||
|
|
@ -145,4 +197,12 @@ public class CustomizeParameterDrawer(Configuration config) : IService
|
||||||
=> ImGui.GetIO().KeyCtrl
|
=> ImGui.GetIO().KeyCtrl
|
||||||
? ImGuiColorEditFlags.Float | ImGuiColorEditFlags.HDR | ImGuiColorEditFlags.NoOptions
|
? ImGuiColorEditFlags.Float | ImGuiColorEditFlags.HDR | ImGuiColorEditFlags.NoOptions
|
||||||
: ImGuiColorEditFlags.Float | ImGuiColorEditFlags.HDR;
|
: ImGuiColorEditFlags.Float | ImGuiColorEditFlags.HDR;
|
||||||
|
|
||||||
|
|
||||||
|
private ImRaii.IEndObject EnsureSize()
|
||||||
|
{
|
||||||
|
var iconSize = ImGui.GetTextLineHeight() * 2 + ImGui.GetStyle().ItemSpacing.Y + 4 * ImGui.GetStyle().FramePadding.Y;
|
||||||
|
_width = 6 * iconSize + 4 * ImGui.GetStyle().ItemInnerSpacing.X;
|
||||||
|
return ImRaii.ItemWidth(_width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,8 @@ public class SettingsTab : ITab
|
||||||
Checkbox("Revert Manual Changes on Zone Change",
|
Checkbox("Revert Manual Changes on Zone Change",
|
||||||
"Restores the old behaviour of reverting your character to its game or automation base whenever you change the zone.",
|
"Restores the old behaviour of reverting your character to its game or automation base whenever you change the zone.",
|
||||||
_config.RevertManualChangesOnZoneChange, v => _config.RevertManualChangesOnZoneChange = v);
|
_config.RevertManualChangesOnZoneChange, v => _config.RevertManualChangesOnZoneChange = v);
|
||||||
Checkbox("Enable Advanced Customization Options", "Enable the display and editing of advanced customization options like arbitrary colors.",
|
Checkbox("Enable Advanced Customization Options",
|
||||||
|
"Enable the display and editing of advanced customization options like arbitrary colors.",
|
||||||
_config.UseAdvancedParameters, v => _config.UseAdvancedParameters = v);
|
_config.UseAdvancedParameters, v => _config.UseAdvancedParameters = v);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
|
|
@ -171,6 +172,10 @@ public class SettingsTab : ITab
|
||||||
Checkbox("Show Unobtained Item Warnings",
|
Checkbox("Show Unobtained Item Warnings",
|
||||||
"Show information whether you have unlocked all items and customizations in your automated design or not.",
|
"Show information whether you have unlocked all items and customizations in your automated design or not.",
|
||||||
_config.ShowUnlockedItemWarnings, v => _config.ShowUnlockedItemWarnings = v);
|
_config.ShowUnlockedItemWarnings, v => _config.ShowUnlockedItemWarnings = v);
|
||||||
|
if (_config.UseAdvancedParameters)
|
||||||
|
Checkbox("Show Palette+ Import Button",
|
||||||
|
"Show the import button that allows you to import Palette+ palettes onto a design in the Advanced Customization options section for designs.",
|
||||||
|
_config.ShowPalettePlusImport, v => _config.ShowPalettePlusImport = v);
|
||||||
Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general.", _config.DebugMode,
|
Checkbox("Debug Mode", "Show the debug tab. Only useful for debugging or advanced use. Not recommended in general.", _config.DebugMode,
|
||||||
v => _config.DebugMode = v);
|
v => _config.DebugMode = v);
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
|
||||||
94
Glamourer/Interop/PalettePlus/PaletteImport.cs
Normal file
94
Glamourer/Interop/PalettePlus/PaletteImport.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Glamourer.GameData;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using OtterGui.Services;
|
||||||
|
|
||||||
|
namespace Glamourer.Interop.PalettePlus;
|
||||||
|
|
||||||
|
public class PaletteImport(DalamudPluginInterface pluginInterface) : IService
|
||||||
|
{
|
||||||
|
private string ConfigFile
|
||||||
|
=> Path.Combine(Path.GetDirectoryName(pluginInterface.GetPluginConfigDirectory())!, "PalettePlus.json");
|
||||||
|
|
||||||
|
public bool TryRead(string name, ref CustomizeParameterData data)
|
||||||
|
{
|
||||||
|
if (name.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
var path = ConfigFile;
|
||||||
|
if (!File.Exists(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var text = File.ReadAllText(path);
|
||||||
|
var obj = JObject.Parse(text);
|
||||||
|
var palettes = obj["SavedPalettes"];
|
||||||
|
|
||||||
|
var target = palettes?.Children().FirstOrDefault(c => c["Name"]?.ToObject<string>() == name);
|
||||||
|
if (target == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var conditions = target["Conditions"]?.ToObject<int>() ?? 0;
|
||||||
|
var parameters = target["ShaderParams"];
|
||||||
|
if (parameters == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var discard = 0f;
|
||||||
|
|
||||||
|
Parse("SkinTone", ref data.SkinDiffuse.X, ref data.SkinDiffuse.Y, ref data.SkinDiffuse.Z, ref discard);
|
||||||
|
Parse("SkinGloss", ref data.SkinSpecular.X, ref data.SkinSpecular.Y, ref data.SkinSpecular.Z, ref discard);
|
||||||
|
Parse("LipColor", ref data.LipDiffuse.X, ref data.LipDiffuse.Y, ref data.LipDiffuse.Z, ref data.LipDiffuse.W);
|
||||||
|
Parse("HairColor", ref data.HairDiffuse.X, ref data.HairDiffuse.Y, ref data.HairDiffuse.Z, ref discard);
|
||||||
|
Parse("HairShine", ref data.HairSpecular.X, ref data.HairSpecular.Y, ref data.HairSpecular.Z, ref discard);
|
||||||
|
Parse("LeftEyeColor", ref data.LeftEye.X, ref data.LeftEye.Y, ref data.LeftEye.Z, ref discard);
|
||||||
|
Parse("RaceFeatureColor", ref data.FeatureColor.X, ref data.FeatureColor.Y, ref data.FeatureColor.Z, ref discard);
|
||||||
|
Parse("FacePaintColor", ref data.DecalColor.X, ref data.DecalColor.Y, ref data.DecalColor.Z, ref data.DecalColor.W);
|
||||||
|
// Highlights is flag 2.
|
||||||
|
if ((conditions & 2) == 2)
|
||||||
|
Parse("HighlightsColor", ref data.HairHighlight.X, ref data.HairHighlight.Y, ref data.HairHighlight.Z, ref discard);
|
||||||
|
// Heterochromia is flag 1
|
||||||
|
if ((conditions & 1) == 1)
|
||||||
|
Parse("RightEyeColor", ref data.RightEye.X, ref data.RightEye.Y, ref data.RightEye.Z, ref discard);
|
||||||
|
|
||||||
|
ParseSingle("FacePaintOffset", ref data.FacePaintUvOffset);
|
||||||
|
ParseSingle("FacePaintWidth", ref data.FacePaintUvMultiplier);
|
||||||
|
ParseSingle("MuscleTone", ref data.MuscleTone);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
void Parse(string attribute, ref float x, ref float y, ref float z, ref float w)
|
||||||
|
{
|
||||||
|
var node = parameters![attribute];
|
||||||
|
if (node == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var xVal = node["X"]?.ToObject<float>();
|
||||||
|
var yVal = node["Y"]?.ToObject<float>();
|
||||||
|
var zVal = node["Z"]?.ToObject<float>();
|
||||||
|
var wVal = node["W"]?.ToObject<float>();
|
||||||
|
if (xVal.HasValue)
|
||||||
|
x = xVal.Value > 0 ? MathF.Sqrt(xVal.Value) : -MathF.Sqrt(-xVal.Value);
|
||||||
|
if (yVal.HasValue)
|
||||||
|
y = yVal.Value > 0 ? MathF.Sqrt(yVal.Value) : -MathF.Sqrt(-yVal.Value);
|
||||||
|
if (zVal.HasValue)
|
||||||
|
z = zVal.Value > 0 ? MathF.Sqrt(zVal.Value) : -MathF.Sqrt(-zVal.Value);
|
||||||
|
if (wVal.HasValue)
|
||||||
|
w = wVal.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseSingle(string attribute, ref float value)
|
||||||
|
{
|
||||||
|
var node = parameters![attribute]?.ToObject<float>();
|
||||||
|
if (node.HasValue)
|
||||||
|
value = node.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Error($"Could not read Palette+ configuration:\n{ex}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue