Add Palette+ Import.

This commit is contained in:
Ottermandias 2024-01-12 13:46:45 +01:00
parent ada0c6f479
commit a50b63f67e
4 changed files with 166 additions and 6 deletions

View file

@ -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;

View file

@ -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);
}
} }

View file

@ -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();

View 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;
}
}
}