feat: add fitting room helper

This commit is contained in:
Anna 2021-11-23 13:41:58 -05:00
parent c83aa86108
commit 4066173f23
7 changed files with 148 additions and 61 deletions

View File

@ -11,6 +11,7 @@ namespace Glamaholic {
public List<SavedPlate> Plates { get; init; } = new();
public bool ShowEditorMenu = true;
public bool ShowExamineMenu = true;
public bool ShowTryOnMenu = true;
public bool ShowKofiButton = true;
internal void AddPlate(SavedPlate plate) {

View File

@ -16,6 +16,7 @@ namespace Glamaholic {
private MainInterface MainInterface { get; }
private EditorHelper EditorHelper { get; }
private ExamineHelper ExamineHelper { get; }
private TryOnHelper TryOnHelper { get; }
internal List<AlternativeFinder> AlternativeFinders { get; } = new();
internal List<(string, string)> Help { get; } = new();
@ -38,6 +39,7 @@ namespace Glamaholic {
this.MainInterface = new MainInterface(this);
this.EditorHelper = new EditorHelper(this);
this.ExamineHelper = new ExamineHelper(this);
this.TryOnHelper = new TryOnHelper(this);
this.Plugin.Interface.UiBuilder.Draw += this.Draw;
this.Plugin.Interface.UiBuilder.OpenConfigUi += this.OpenMainInterface;
@ -78,6 +80,7 @@ namespace Glamaholic {
this.MainInterface.Draw();
this.EditorHelper.Draw();
this.ExamineHelper.Draw();
this.TryOnHelper.Draw();
this.AlternativeFinders.RemoveAll(finder => {
finder.Draw();

View File

@ -16,37 +16,17 @@ namespace Glamaholic.Ui.Helpers {
var addon = (AtkUnitBase*) this.Ui.Plugin.GameGui.GetAddonByName(Util.PlateAddon, 1);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (addon != null && addon->IsVisible) {
this.DrawInner(addon);
}
}
private unsafe void DrawInner(AtkUnitBase* addon) {
var drawPos = HelperUtil.DrawPosForAddon(addon);
if (drawPos == null) {
if (addon == null || !addon->IsVisible) {
return;
}
using (new HelperUtil.HelperStyles()) {
ImGui.SetNextWindowPos(drawPos.Value, ImGuiCond.Appearing);
if (!ImGui.Begin("##glamaholic-helper-open", HelperUtil.HelperWindowFlags)) {
ImGui.End();
return;
}
HelperUtil.DrawHelper(addon, "glamaholic-editor-helper", false, this.DrawDropdown);
}
private void DrawDropdown() {
if (ImGui.Selectable($"Open {this.Ui.Plugin.Name}")) {
this.Ui.OpenMainInterface();
}
ImGui.SetNextItemWidth(HelperUtil.DropdownWidth());
if (ImGui.BeginCombo("##glamaholic-helper-examine-combo", this.Ui.Plugin.Name)) {
if (ImGui.Selectable($"Open {this.Ui.Plugin.Name}")) {
this.Ui.OpenMainInterface();
}
ImGui.EndCombo();
}
ImGui.SetNextWindowPos(drawPos.Value);
ImGui.End();
}
}
}

View File

@ -18,45 +18,24 @@ namespace Glamaholic.Ui.Helpers {
var examineAddon = (AtkUnitBase*) this.Ui.Plugin.GameGui.GetAddonByName("CharacterInspect", 1);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (examineAddon != null && examineAddon->IsVisible) {
this.DrawInner(examineAddon);
}
}
private unsafe void DrawInner(AtkUnitBase* addon) {
var drawPos = HelperUtil.DrawPosForAddon(addon);
if (drawPos == null) {
if (examineAddon == null || !examineAddon->IsVisible) {
return;
}
using (new HelperUtil.HelperStyles()) {
// get first frame
ImGui.SetNextWindowPos(drawPos.Value, ImGuiCond.Appearing);
if (!ImGui.Begin("##glamaholic-helper-examine", HelperUtil.HelperWindowFlags)) {
ImGui.End();
return;
}
HelperUtil.DrawHelper(examineAddon, "glamaholic-helper-examine", false, this.DrawDropdown);
}
private void DrawDropdown() {
if (ImGui.Selectable("Create glamour plate")) {
this.CopyToGlamourPlate();
}
ImGui.SetNextItemWidth(HelperUtil.DropdownWidth());
if (ImGui.BeginCombo("##glamaholic-helper-examine-combo", this.Ui.Plugin.Name)) {
if (ImGui.Selectable("Create glamour plate")) {
this.CopyToGlamourPlate();
if (ImGui.Selectable("Try on")) {
var items = GetItems();
if (items != null) {
this.Ui.TryOn(items.Values);
}
if (ImGui.Selectable("Try on")) {
var items = GetItems();
if (items != null) {
this.Ui.TryOn(items.Values);
}
}
ImGui.EndCombo();
}
ImGui.SetWindowPos(drawPos.Value);
ImGui.End();
}
private static unsafe Dictionary<PlateSlot, SavedGlamourItem>? GetItems() {

View File

@ -1,6 +1,7 @@
using System;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Logging;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
@ -31,7 +32,7 @@ namespace Glamaholic.Ui.Helpers {
}
var xModifier = right
? root->Width - DropdownWidth()
? root->Width * addon->Scale - DropdownWidth()
: 0;
return ImGuiHelpers.MainViewport.Pos
@ -52,10 +53,41 @@ namespace Glamaholic.Ui.Helpers {
ImGui.PushStyleVar(ImGuiStyleVar.WindowBorderSize, 0);
ImGui.PushStyleVar(ImGuiStyleVar.WindowMinSize, Vector2.Zero);
}
public void Dispose() {
ImGui.PopStyleVar(3);
}
}
internal static unsafe void DrawHelper(AtkUnitBase* addon, string id, bool right, Action dropdown) {
var drawPos = DrawPosForAddon(addon, right);
if (drawPos == null) {
return;
}
using (new HelperStyles()) {
// get first frame
ImGui.SetNextWindowPos(drawPos.Value, ImGuiCond.Appearing);
if (!ImGui.Begin($"##{id}", HelperWindowFlags)) {
ImGui.End();
return;
}
}
ImGui.SetNextItemWidth(DropdownWidth());
if (ImGui.BeginCombo($"##{id}-combo", Plugin.PluginName)) {
try {
dropdown();
} catch (Exception ex) {
PluginLog.LogError(ex, "Error drawing helper combo");
}
ImGui.EndCombo();
}
ImGui.SetWindowPos(drawPos.Value);
ImGui.End();
}
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
namespace Glamaholic.Ui.Helpers {
internal class TryOnHelper {
private PluginUi Ui { get; }
internal TryOnHelper(PluginUi ui) {
this.Ui = ui;
}
internal unsafe void Draw() {
if (!this.Ui.Plugin.Config.ShowTryOnMenu) {
return;
}
var tryOnAddon = (AtkUnitBase*) this.Ui.Plugin.GameGui.GetAddonByName("Tryon", 1);
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (tryOnAddon == null || !tryOnAddon->IsVisible) {
return;
}
var right = this.Ui.Plugin.Interface.PluginInternalNames.Contains("ItemSearchPlugin");
HelperUtil.DrawHelper(tryOnAddon, "glamaholic-helper-try-on", right, this.DrawDropdown);
}
private void DrawDropdown() {
if (ImGui.Selectable("Create glamour plate")) {
var items = GetTryOnItems();
this.Ui.Plugin.Config.AddPlate(new SavedPlate("Fitting Room") {
Items = items,
});
this.Ui.Plugin.SaveConfig();
this.Ui.OpenMainInterface();
this.Ui.SwitchPlate(this.Ui.Plugin.Config.Plates.Count - 1, true);
}
}
private static unsafe Dictionary<PlateSlot, SavedGlamourItem> GetTryOnItems() {
var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Tryon);
var firstItem = agent + 0x2E8;
var items = new Dictionary<PlateSlot, SavedGlamourItem>();
for (var i = 0; i < 12; i++) {
var item = (TryOnItem*) (firstItem + i * 24);
if (item->Slot == 14 || item->ItemId == 0) {
continue;
}
var itemId = item->ItemId;
if (item->GlamourId != 0) {
itemId = item->GlamourId;
}
// TODO: remove this logic in endwalker
var slot = item->Slot > 5 ? item->Slot - 1 : item->Slot;
items[(PlateSlot) slot] =new SavedGlamourItem {
ItemId = itemId,
StainId = item->StainId,
};
}
return items;
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
private readonly struct TryOnItem {
[FieldOffset(0)]
internal readonly byte Slot;
[FieldOffset(2)]
internal readonly byte StainId;
[FieldOffset(5)]
internal readonly byte UnknownByte;
[FieldOffset(8)]
internal readonly uint ItemId;
[FieldOffset(12)]
internal readonly uint GlamourId;
}
}
}

View File

@ -160,6 +160,7 @@ namespace Glamaholic.Ui {
if (ImGui.BeginMenu("Settings")) {
anyChanged |= ImGui.MenuItem("Show plate editor menu", null, ref this.Ui.Plugin.Config.ShowEditorMenu);
anyChanged |= ImGui.MenuItem("Show examine window menu", null, ref this.Ui.Plugin.Config.ShowExamineMenu);
anyChanged |= ImGui.MenuItem("Show try on menu", null, ref this.Ui.Plugin.Config.ShowTryOnMenu);
ImGui.Separator();
anyChanged |= ImGui.MenuItem("Show Ko-fi button", null, ref this.Ui.Plugin.Config.ShowKofiButton);