Add height display in real-world units.

This commit is contained in:
Ottermandias 2024-04-19 01:05:15 +02:00
parent 552338e5b5
commit 78d7aef13f
5 changed files with 133 additions and 36 deletions

View file

@ -14,43 +14,54 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Glamourer; namespace Glamourer;
public enum HeightDisplayType
{
None,
Centimetre,
Metre,
Wrong,
WrongFoot,
}
public class Configuration : IPluginConfiguration, ISavable public class Configuration : IPluginConfiguration, ISavable
{ {
[JsonIgnore] [JsonIgnore]
public readonly EphemeralConfig Ephemeral; public readonly EphemeralConfig Ephemeral;
public bool UseRestrictedGearProtection { get; set; } = false; public bool UseRestrictedGearProtection { get; set; } = false;
public bool OpenFoldersByDefault { get; set; } = false; public bool OpenFoldersByDefault { get; set; } = false;
public bool AutoRedrawEquipOnChanges { get; set; } = false; public bool AutoRedrawEquipOnChanges { get; set; } = false;
public bool EnableAutoDesigns { get; set; } = true; public bool EnableAutoDesigns { get; set; } = true;
public bool HideApplyCheckmarks { get; set; } = false; public bool HideApplyCheckmarks { get; set; } = false;
public bool SmallEquip { get; set; } = false; public bool SmallEquip { get; set; } = false;
public bool UnlockedItemMode { get; set; } = false; public bool UnlockedItemMode { get; set; } = false;
public byte DisableFestivals { get; set; } = 1; public byte DisableFestivals { get; set; } = 1;
public bool EnableGameContextMenu { get; set; } = true; public bool EnableGameContextMenu { get; set; } = true;
public bool HideWindowInCutscene { get; set; } = false; public bool HideWindowInCutscene { get; set; } = false;
public bool ShowAutomationSetEditing { get; set; } = true; public bool ShowAutomationSetEditing { get; set; } = true;
public bool ShowAllAutomatedApplicationRules { get; set; } = true; public bool ShowAllAutomatedApplicationRules { get; set; } = true;
public bool ShowUnlockedItemWarnings { get; set; } = true; public bool ShowUnlockedItemWarnings { get; set; } = true;
public bool RevertManualChangesOnZoneChange { get; set; } = false; public bool RevertManualChangesOnZoneChange { get; set; } = false;
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 ShowWindowWhenUiHidden { get; set; } = false; public bool ShowWindowWhenUiHidden { get; set; } = false;
public bool UseAdvancedParameters { get; set; } = true; public bool UseAdvancedParameters { get; set; } = true;
public bool UseAdvancedDyes { get; set; } = true; public bool UseAdvancedDyes { get; set; } = true;
public bool KeepAdvancedDyesAttached { get; set; } = true; public bool KeepAdvancedDyesAttached { get; set; } = true;
public bool ShowPalettePlusImport { get; set; } = true; public bool ShowPalettePlusImport { get; set; } = true;
public bool UseFloatForColors { get; set; } = true; public bool UseFloatForColors { get; set; } = true;
public bool UseRgbForColors { get; set; } = true; public bool UseRgbForColors { get; set; } = true;
public bool ShowColorConfig { get; set; } = true; public bool ShowColorConfig { get; set; } = true;
public bool ChangeEntireItem { get; set; } = false; public bool ChangeEntireItem { get; set; } = false;
public bool AlwaysApplyAssociatedMods { get; set; } = false; public bool AlwaysApplyAssociatedMods { get; set; } = false;
public bool AllowDoubleClickToApply { get; set; } = false; public bool AllowDoubleClickToApply { get; set; } = false;
public bool RespectManualOnAutomationUpdate { get; set; } = false; public bool RespectManualOnAutomationUpdate { get; set; } = false;
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY); public HeightDisplayType HeightDisplayType { get; set; } = HeightDisplayType.Centimetre;
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift); public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New; public ModifiableHotkey ToggleQuickDesignBar { get; set; } = new(VirtualKey.NO_KEY);
public DoubleModifier DeleteDesignModifier { get; set; } = new(ModifierHotkey.Control, ModifierHotkey.Shift);
public ChangeLogDisplayType ChangeLogDisplayType { get; set; } = ChangeLogDisplayType.New;
public QdbButtons QdbButtons { get; set; } = public QdbButtons QdbButtons { get; set; } =
QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced; QdbButtons.ApplyDesign | QdbButtons.RevertAll | QdbButtons.RevertAutomation | QdbButtons.RevertAdvanced;

View file

@ -29,6 +29,27 @@ public partial class CustomizationDrawer
ImGui.SameLine(); ImGui.SameLine();
ImGui.AlignTextToFramePadding(); ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(_currentOption); ImGui.TextUnformatted(_currentOption);
if (_currentIndex is CustomizeIndex.Height)
DrawHeight();
}
private void DrawHeight()
{
if (_config.HeightDisplayType is HeightDisplayType.None)
return;
var height = _heightService.Height(_customize);
ImGui.SameLine();
var heightString = _config.HeightDisplayType switch
{
HeightDisplayType.Centimetre => $"({height * 100:F1} cm)",
HeightDisplayType.Metre => $"({height:F2} m)",
HeightDisplayType.Wrong => $"({height * 100 / 2.539:F1} in)",
HeightDisplayType.WrongFoot => $"({(int)(height * 100 / 2.539 / 12)}'{(int)(height * 100 / 2.539) % 12}'')",
_ => $"({height})",
};
ImGui.TextUnformatted(heightString);
} }
private void DrawPercentageSlider() private void DrawPercentageSlider()

View file

@ -12,7 +12,13 @@ using Penumbra.GameData.Structs;
namespace Glamourer.Gui.Customization; namespace Glamourer.Gui.Customization;
public partial class CustomizationDrawer(DalamudPluginInterface pi, CustomizeService _service, CodeService _codes, Configuration _config, FavoriteManager _favorites) public partial class CustomizationDrawer(
DalamudPluginInterface pi,
CustomizeService _service,
CodeService _codes,
Configuration _config,
FavoriteManager _favorites,
HeightService _heightService)
: IDisposable : IDisposable
{ {
private readonly Vector4 _redTint = new(0.6f, 0.3f, 0.3f, 1f); private readonly Vector4 _redTint = new(0.6f, 0.3f, 0.3f, 1f);
@ -20,8 +26,8 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, CustomizeSer
private Exception? _terminate; private Exception? _terminate;
private CustomizeArray _customize = CustomizeArray.Default; private CustomizeArray _customize = CustomizeArray.Default;
private CustomizeSet _set = null!; private CustomizeSet _set = null!;
public CustomizeArray Customize public CustomizeArray Customize
=> _customize; => _customize;
@ -46,7 +52,7 @@ public partial class CustomizationDrawer(DalamudPluginInterface pi, CustomizeSer
public bool Draw(CustomizeArray current, bool locked, bool lockedRedraw) public bool Draw(CustomizeArray current, bool locked, bool lockedRedraw)
{ {
_withApply = false; _withApply = false;
Init(current, locked, lockedRedraw); Init(current, locked, lockedRedraw);
return DrawInternal(); return DrawInternal();

View file

@ -161,6 +161,7 @@ public class SettingsTab(
Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.", Checkbox("Smaller Equip Display", "Use single-line display without icons and small dye buttons instead of double-line display.",
config.SmallEquip, v => config.SmallEquip = v); config.SmallEquip, v => config.SmallEquip = v);
DrawHeightUnitSettings();
Checkbox("Show Application Checkboxes", Checkbox("Show Application Checkboxes",
"Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.", "Show the application checkboxes in the Customization and Equipment panels of the design tab, instead of only showing them under Application Rules.",
!config.HideApplyCheckmarks, v => config.HideApplyCheckmarks = !v); !config.HideApplyCheckmarks, v => config.HideApplyCheckmarks = !v);
@ -441,4 +442,39 @@ public class SettingsTab(
ImGui.TextUnformatted("Rename Fields in Design Context Menu"); ImGui.TextUnformatted("Rename Fields in Design Context Menu");
ImGuiUtil.HoverTooltip(tt); ImGuiUtil.HoverTooltip(tt);
} }
private void DrawHeightUnitSettings()
{
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale);
using (var combo = ImRaii.Combo("##heightUnit", HeightDisplayTypeName(config.HeightDisplayType)))
{
if (combo)
foreach (var type in Enum.GetValues<HeightDisplayType>())
{
if (ImGui.Selectable(HeightDisplayTypeName(type), type == config.HeightDisplayType) && type != config.HeightDisplayType)
{
config.HeightDisplayType = type;
config.Save();
}
}
}
ImGui.SameLine();
const string tt = "Select how to display the height of characters in real-world units, if at all.";
ImGuiComponents.HelpMarker(tt);
ImGui.SameLine();
ImGui.TextUnformatted("Character Height Display Type");
ImGuiUtil.HoverTooltip(tt);
}
private string HeightDisplayTypeName(HeightDisplayType type)
=> type switch
{
HeightDisplayType.None => "Do Not Display",
HeightDisplayType.Centimetre => "Centimetres (000.0 cm)",
HeightDisplayType.Metre => "Metres (0.00 m)",
HeightDisplayType.Wrong => "Inches (00.0 in)",
HeightDisplayType.WrongFoot => "Feet (0'00'')",
_ => string.Empty,
};
} }

View file

@ -0,0 +1,23 @@
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
namespace Glamourer.Services;
public unsafe class HeightService : IService
{
[Signature("E8 ?? ?? ?? FF 48 8B 0D ?? ?? ?? ?? 0F 28 F0")]
private readonly delegate* unmanaged[Stdcall]<CharacterUtility*, byte, byte, byte, byte, float> _calculateHeight = null!;
public HeightService(IGameInteropProvider interop)
=> interop.InitializeFromAttributes(this);
public float Height(CustomizeValue height, SubRace clan, Gender gender, CustomizeValue bodyType)
=> _calculateHeight(CharacterUtility.Instance(), height.Value, (byte)clan, (byte)((byte)gender - 1), bodyType.Value);
public float Height(in CustomizeArray customize)
=> Height(customize[CustomizeIndex.Height], customize.Clan, customize.Gender, customize.BodyType);
}