feat: add job layouts and roleplaying layout

This commit is contained in:
Anna 2020-07-31 00:15:07 -04:00
parent 77d527a161
commit c793cfc613
3 changed files with 127 additions and 16 deletions

View File

@ -26,6 +26,11 @@ namespace HudSwap {
public Guid craftingLayout = Guid.Empty;
public Guid gatheringLayout = Guid.Empty;
public Guid fishingLayout = Guid.Empty;
public Guid roleplayingLayout = Guid.Empty;
public Dictionary<string, Guid> JobLayouts { get; set; } = new Dictionary<string, Guid>();
public bool HighPriorityJobs { get; set; } = false;
public bool JobsCombatOnly { get; set; } = false;
public Dictionary<Guid, Tuple<string, byte[]>> Layouts { get; } = new Dictionary<Guid, Tuple<string, byte[]>>();

View File

@ -40,6 +40,14 @@
<Reference Include="ImGuiScene">
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\ImGuiScene.dll</HintPath>
</Reference>
<Reference Include="Lumina, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.dll</HintPath>
</Reference>
<Reference Include="Lumina.Generated, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.Generated.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
@ -61,4 +69,4 @@
<None Include="HudSwap.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>

View File

@ -2,13 +2,13 @@
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Plugin;
using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
// TODO: Job swaps?
// TODO: Zone swaps?
namespace HudSwap {
@ -34,6 +34,8 @@ namespace HudSwap {
private string renameName = "";
private Guid selectedLayout = Guid.Empty;
private string jobFilter = "";
private static bool configErrorOpen = true;
public static void ConfigError() {
if (ImGui.Begin("HudSwap error", ref configErrorOpen)) {
@ -186,16 +188,85 @@ namespace HudSwap {
ImGui.Text("These settings are ordered from highest priority to lowest priority.\nHigher priorities overwrite lower priorities when enabled.");
ImGui.Spacing();
ImGui.Columns(2);
if (ImGui.CollapsingHeader("Status layouts", ImGuiTreeNodeFlags.DefaultOpen)) {
if (ImGui.BeginChild("##layout-selections", new Vector2(0, 125))) {
ImGui.Columns(2);
this.LayoutBox("In combat", ref this.plugin.config.combatLayout, player);
this.LayoutBox("Weapon drawn", ref this.plugin.config.weaponDrawnLayout, player);
this.LayoutBox("In instance", ref this.plugin.config.instanceLayout, player);
this.LayoutBox("Crafting", ref this.plugin.config.craftingLayout, player);
this.LayoutBox("Gathering", ref this.plugin.config.gatheringLayout, player);
this.LayoutBox("Fishing", ref this.plugin.config.fishingLayout, player);
List<float> textSizes = new List<float>();
ImGui.Columns(1);
this.LayoutBox("In combat", ref this.plugin.config.combatLayout, player, textSizes);
this.LayoutBox("Weapon drawn", ref this.plugin.config.weaponDrawnLayout, player, textSizes);
this.LayoutBox("In instance", ref this.plugin.config.instanceLayout, player, textSizes);
this.LayoutBox("Crafting", ref this.plugin.config.craftingLayout, player, textSizes);
this.LayoutBox("Gathering", ref this.plugin.config.gatheringLayout, player, textSizes);
this.LayoutBox("Fishing", ref this.plugin.config.fishingLayout, player, textSizes);
this.LayoutBox("Roleplaying", ref this.plugin.config.roleplayingLayout, player, textSizes);
ImGui.SetColumnWidth(0, textSizes.Max() + ImGui.GetStyle().ItemSpacing.X * 2);
ImGui.Columns(1);
ImGui.EndChild();
}
}
if (ImGui.CollapsingHeader("Job layouts")) {
if (ImGui.InputText("Filter", ref this.jobFilter, 50, ImGuiInputTextFlags.AutoSelectAll)) {
this.jobFilter = this.jobFilter.ToLower();
}
if (ImGui.BeginChild("##job-layout-selections", new Vector2(0, 125))) {
ImGui.Columns(2);
List<float> textSizes = new List<float>();
var acceptableJobs = this.pi.Data.GetExcelSheet<ClassJob>()
.Where(job => job.NameEnglish != "Adventurer")
.Where(job => this.jobFilter.Length == 0 || (job.NameEnglish.ToLower().Contains(this.jobFilter) || job.Abbreviation.ToLower().Contains(this.jobFilter)));
foreach (ClassJob job in acceptableJobs) {
this.plugin.config.JobLayouts.TryGetValue(job.Abbreviation, out Guid layout);
Guid oldLayout = layout;
this.LayoutBox(job.NameEnglish, ref layout, player, textSizes);
if (oldLayout != layout) {
this.plugin.config.JobLayouts[job.Abbreviation] = layout;
this.plugin.config.Save();
if (this.plugin.config.SwapsEnabled) {
this.statuses.SetHudLayout(player, true);
}
}
}
ImGui.SetColumnWidth(0, textSizes.DefaultIfEmpty(0).Max() + ImGui.GetStyle().ItemSpacing.X * 2);
ImGui.Columns(1);
ImGui.EndChild();
}
bool combatOnlyJobs = this.plugin.config.JobsCombatOnly;
if (ImGui.Checkbox("Jobs only in combat/weapon drawn", ref combatOnlyJobs)) {
this.plugin.config.JobsCombatOnly = combatOnlyJobs;
this.plugin.config.Save();
if (this.plugin.config.SwapsEnabled) {
this.statuses.SetHudLayout(player, true);
}
}
ImGui.SameLine();
this.HelpMarker("Selecting this will make the HUD layout change for a job only when in combat or when your weapon is drawn.");
bool highPriorityJobs = this.plugin.config.HighPriorityJobs;
if (ImGui.Checkbox("Jobs take priority over status", ref highPriorityJobs)) {
this.plugin.config.HighPriorityJobs = highPriorityJobs;
this.plugin.config.Save();
if (this.plugin.config.SwapsEnabled) {
this.statuses.SetHudLayout(player, true);
}
}
ImGui.SameLine();
this.HelpMarker("Selecting this will make job layouts always apply when on that job. If this is unselected, job layouts will only apply if the default layout was going to be used (or only in combat if the above checkbox is selected).");
}
ImGui.EndTabItem();
}
@ -219,8 +290,7 @@ namespace HudSwap {
}
private string LayoutNameOrDefault(Guid key) {
Tuple<string, byte[]> tuple;
if (this.plugin.config.Layouts.TryGetValue(key, out tuple)) {
if (this.plugin.config.Layouts.TryGetValue(key, out Tuple<string, byte[]> tuple)) {
return tuple.Item1;
} else {
return "";
@ -244,7 +314,8 @@ namespace HudSwap {
}
}
private void LayoutBox(string name, ref Guid layout, PlayerCharacter player) {
private void LayoutBox(string name, ref Guid layout, PlayerCharacter player, List<float> textSizes) {
textSizes.Add(ImGui.CalcTextSize(name).X);
ImGui.Text(name);
ImGui.NextColumn();
if (ImGui.BeginCombo($"##{name}-layout", this.LayoutNameOrDefault(layout))) {
@ -283,10 +354,12 @@ namespace HudSwap {
private readonly DalamudPluginInterface pi;
private readonly bool[] condition = new bool[ORDER.Length];
private ClassJob job;
// Order: lowest to highest priority
// For conditions that require custom logic, use ConditionFlag.None
private static readonly ConditionFlag[] ORDER = {
ConditionFlag.RolePlaying,
ConditionFlag.Fishing,
ConditionFlag.Gathering,
ConditionFlag.Crafting,
@ -322,6 +395,7 @@ namespace HudSwap {
private Guid[] GetLayouts() {
// These layouts must be in the same order as the flags in ORDER are defined
Guid[] layouts = {
this.plugin.config.roleplayingLayout,
this.plugin.config.fishingLayout,
this.plugin.config.gatheringLayout,
this.plugin.config.craftingLayout,
@ -343,6 +417,12 @@ namespace HudSwap {
bool anyChanged = false;
ClassJob currentJob = this.pi.Data.GetExcelSheet<ClassJob>().GetRow(player.ClassJob.Id);
if (this.job != null && this.job != currentJob) {
anyChanged = true;
}
this.job = currentJob;
for (int i = 0; i < ORDER.Length; i++) {
ConditionFlag flag = ORDER[i];
if (flag == ConditionFlag.None) {
@ -362,11 +442,16 @@ namespace HudSwap {
if (player == null) {
return Guid.Empty;
}
this.Update(player);
Guid layout = this.plugin.config.defaultLayout;
// get the job layout if there is one and check if jobs are high priority
if (this.plugin.config.JobLayouts.TryGetValue(this.job.Abbreviation, out Guid jobLayout) && this.plugin.config.HighPriorityJobs) {
return jobLayout;
}
Guid layout = Guid.Empty;
Guid[] layouts = this.GetLayouts();
// check all status conditions and set layout as appropriate
for (int i = 0; i < ORDER.Length; i++) {
Guid flagLayout = layouts[i];
@ -375,7 +460,20 @@ namespace HudSwap {
}
}
return layout;
// if a job layout is set for the current job
if (jobLayout != Guid.Empty) {
// if jobs are combat only and the player is either in combat or has their weapon drawn, use the job layout
if (this.plugin.config.JobsCombatOnly && (this.condition[5] || this.condition[6])) {
layout = jobLayout;
}
// if the layout was going to be default, use job layout unless jobs are not combat only
if (!this.plugin.config.JobsCombatOnly && layout == Guid.Empty) {
layout = jobLayout;
}
}
return layout == Guid.Empty ? this.plugin.config.defaultLayout : layout;
}
public void SetHudLayout(PlayerCharacter player, bool update = false) {