diff --git a/HuntBuddy/Configuration.cs b/HuntBuddy/Configuration.cs index 096f28f..de27846 100644 --- a/HuntBuddy/Configuration.cs +++ b/HuntBuddy/Configuration.cs @@ -8,6 +8,8 @@ public class Configuration : IPluginConfiguration { public int Version { get; set; } + public bool IncludeAreaOnMap; + public bool LockWindowPositions; public bool ShowLocalHunts; public bool ShowLocalHuntIcons; public bool HideLocalHuntBackground; diff --git a/HuntBuddy/Interface.cs b/HuntBuddy/Interface.cs index df318d1..7f7889a 100644 --- a/HuntBuddy/Interface.cs +++ b/HuntBuddy/Interface.cs @@ -24,7 +24,14 @@ public unsafe bool Draw() ImGui.SetNextWindowSize(new Vector2(400 * ImGui.GetIO().FontGlobalScale, 500), ImGuiCond.Once); - if (!ImGui.Begin($"{this.plugin.Name}", ref draw, ImGuiWindowFlags.NoDocking)) + var windowFlags = ImGuiWindowFlags.NoDocking; + + if (this.plugin.Configuration.LockWindowPositions) + { + windowFlags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; + } + + if (!ImGui.Begin($"{this.plugin.Name}", ref draw, windowFlags)) { return draw; } @@ -86,7 +93,7 @@ public unsafe bool Draw() return treeOpen; })) { - ImGui.Indent(); + //ImGui.Indent(); foreach (var mobHuntEntry in entry.Value) { if (Location.Database.ContainsKey(mobHuntEntry.MobHuntId)) @@ -110,38 +117,39 @@ public unsafe bool Draw() ImGui.SameLine(); - if (Interface.IconButton(FontAwesomeIcon.Compass, $"openRadius##{mobHuntEntry.MobHuntId}")) - { - Location.CreateMapMarker( - mobHuntEntry.TerritoryType, - mobHuntEntry.MapId, - mobHuntEntry.MobHuntId, - mobHuntEntry.Name, - Location.OpenType.ShowOpen); - } - - if (ImGui.IsItemHovered()) - { - ImGui.BeginTooltip(); - ImGui.Text("Show hunt location on the map"); - ImGui.EndTooltip(); - } - - ImGui.SameLine(); - if (Interface.IconButton(FontAwesomeIcon.MapMarkedAlt, $"open##{mobHuntEntry.MobHuntId}")) { + var includeArea = this.plugin.Configuration.IncludeAreaOnMap; + if (ImGui.IsKeyDown(ImGuiKey.ModShift)) + { + includeArea = !includeArea; + } Location.CreateMapMarker( mobHuntEntry.TerritoryType, mobHuntEntry.MapId, mobHuntEntry.MobHuntId, - mobHuntEntry.Name); + mobHuntEntry.Name, + includeArea ? Location.OpenType.ShowOpen : Location.OpenType.MarkerOpen); } if (ImGui.IsItemHovered()) { + var color = ImGui.IsKeyDown(ImGuiKey.ModShift) ? new Vector4(0f, 0.7f, 0f, 1f) : new Vector4(0.7f, 0.7f, 0.7f, 1f); ImGui.BeginTooltip(); - ImGui.Text("Show hunt location on the map"); + if (this.plugin.Configuration.IncludeAreaOnMap) + { + ImGui.Text("Show hunt area on the map"); + ImGui.TextColored( + color, + "Hold [SHIFT] to show the location only"); + } + else + { + ImGui.Text("Show hunt location on the map"); + ImGui.TextColored( + color, + "Hold [SHIFT] to include the area"); + } ImGui.EndTooltip(); } @@ -192,7 +200,7 @@ public unsafe bool Draw() } } - ImGui.Unindent(); + //ImGui.Unindent(); ImGui.TreePop(); } @@ -230,6 +238,11 @@ public unsafe void DrawLocalHunts() windowFlags |= ImGuiWindowFlags.NoBackground; } + if (this.plugin.Configuration.LockWindowPositions) + { + windowFlags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; + } + if (!ImGui.Begin("Hunts in current area", windowFlags)) { return; @@ -278,7 +291,7 @@ public unsafe void DrawLocalHunts() if (ImGui.IsItemHovered()) { ImGui.BeginTooltip(); - ImGui.Text("Show hunt location on the map"); + ImGui.Text("Show hunt area on the map"); ImGui.EndTooltip(); } @@ -320,13 +333,22 @@ private void DrawConfiguration() { ImGui.SetNextWindowSize(Vector2.Zero, ImGuiCond.Always); - if (!ImGui.Begin($"{this.plugin.Name} settings", ImGuiWindowFlags.NoDocking)) + var windowFlags = ImGuiWindowFlags.NoDocking; + + if (this.plugin.Configuration.LockWindowPositions) + { + windowFlags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; + } + + if (!ImGui.Begin($"{this.plugin.Name} settings", windowFlags)) { return; } var save = false; + save |= ImGui.Checkbox("Lock plugin window positions", ref this.plugin.Configuration.LockWindowPositions); + save |= ImGui.Checkbox("Include hunt area on map by default", ref this.plugin.Configuration.IncludeAreaOnMap); save |= ImGui.Checkbox("Show hunts in local area", ref this.plugin.Configuration.ShowLocalHunts); save |= ImGui.Checkbox( "Show icons of hunts in local area", diff --git a/HuntBuddy/Plugin.cs b/HuntBuddy/Plugin.cs index 117febd..0de797d 100644 --- a/HuntBuddy/Plugin.cs +++ b/HuntBuddy/Plugin.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; @@ -10,6 +11,7 @@ using Dalamud.Game.Command; using Dalamud.Game.Gui; using Dalamud.IoC; +using Dalamud.Logging; using Dalamud.Plugin; using Dalamud.Utility; using Lumina.Excel.GeneratedSheets; @@ -61,6 +63,7 @@ public class Plugin : IDalamudPlugin private readonly PluginCommandManager commandManager; private readonly Interface pluginInterface; private ObtainedBillEnum lastState; + // Dictionary, List>> public readonly Dictionary, List>> MobHuntEntries; public readonly ConcurrentBag CurrentAreaMobHuntEntries; public bool MobHuntEntriesReady = true; @@ -135,6 +138,7 @@ private void Dispose(bool disposing) } this.MobHuntEntriesReady = false; + Plugin.ClientState.TerritoryChanged -= this.ClientStateOnTerritoryChanged; Plugin.Framework.Update -= this.FrameworkOnUpdate; Plugin.PluginInterface.UiBuilder.Draw -= this.DrawInterface; Plugin.PluginInterface.UiBuilder.Draw -= this.pluginInterface.DrawLocalHunts; @@ -144,17 +148,73 @@ private void Dispose(bool disposing) } [Command("/phb")] - [HelpMessage("Toggles UI\nArguments:\nreload - Reloads data")] - public void PluginCommand(string command, string args) + [HelpMessage("Toggles UI\nArguments:\nreload - Reloads data\nlocal - Toggles the local hunt marks window\nnext - Flags the next hunt target to find")] + public unsafe void PluginCommand(string command, string args) { - if (args == "reload") - { - this.MobHuntEntriesReady = false; - Task.Run(this.ReloadData); - } - else - { - this.OpenConfigUi(); + switch (args.Trim().ToLower()) { + case "reload": + this.MobHuntEntriesReady = false; + Task.Run(this.ReloadData); + break; + case "local": + this.Configuration.ShowLocalHunts = !this.Configuration.ShowLocalHunts; + this.Configuration.Save(); + break; + case "next": + if (this.MobHuntEntries.Count > 0) + { + var openType = Location.OpenType.None; + var playerLocation = Plugin.ClientState.LocalPlayer!.Position; + var map = Plugin.DataManager.GetExcelSheet()!.GetRow(Plugin.ClientState.TerritoryType)!.Map!.Value!; + var playerVec2 = MapUtil.WorldToMap(new Vector2(playerLocation.X, playerLocation.Z), map); + var chosen = this.CurrentAreaMobHuntEntries + .Where(entry => this.MobHuntStruct->CurrentKills[entry.CurrentKillsOffset] < entry.NeededKills) + .OrderBy(entry => Vector2.Distance(Location.Database[entry.MobHuntId].Coordinate, playerVec2)) + .FirstOrDefault(); + if (chosen == null) + { + PluginLog.Information("No marks in current zone, looking in current expansion"); + openType = this.Configuration.IncludeAreaOnMap ? Location.OpenType.ShowOpen : Location.OpenType.MarkerOpen; + var expansion = Plugin.DataManager.Excel.GetSheet()!.GetRow(Plugin.ClientState.TerritoryType)!.ExVersion.Value!.Name; + PluginLog.Information($"Player is in a zone from {expansion}; known expansions are {string.Join(", ", this.MobHuntEntries.Keys)}"); + var candidates = this.MobHuntEntries.ContainsKey(expansion) + ? this.MobHuntEntries[expansion] + .Values + .SelectMany(l => l) + .Where(entry => this.MobHuntStruct->CurrentKills[entry.CurrentKillsOffset] < entry.NeededKills) + .ToList() + : new List(); + if (candidates.Count == 0) + { + PluginLog.Information("Nothing in current expansion, looking globally"); + candidates = + this.MobHuntEntries.Values + .SelectMany(dict => dict.Values) + .SelectMany(l => l) + .Where(entry => this.MobHuntStruct->CurrentKills[entry.CurrentKillsOffset] < entry.NeededKills) + .ToList(); + } + if (candidates.Count > 1) + { + PluginLog.Information($"Found {candidates.Count} marks"); + chosen = candidates[new Random().Next(candidates.Count)]; + } + } + if (chosen != null) + { + PluginLog.Information($"Selected next hunt target: {chosen.Name}"); + Location.CreateMapMarker( + chosen.TerritoryType, + chosen.MapId, + chosen.MobHuntId, + chosen.Name, + openType); + } + } + break; + default: + this.OpenConfigUi(); + break; } }