using System.Collections.Generic; using System.Linq; using System.Numerics; using Dalamud.Interface.Textures.TextureWraps; using FFXIVClientStructs.FFXIV.Client.UI.Agent; using KamiLib.Configuration; using Lumina.Excel.Sheets; using Mappy.Classes.SelectionWindowComponents; namespace Mappy.Data; public unsafe record MapNote(uint Territory, uint Map, float X, float Y, string Title, string Description) { public IDalamudTextureWrap? GetMapTexture() => MapDrawableOption.GetMapTexture(Map); public Map GetMap() => Service.DataManager.GetExcelSheet().GetRow(Map); public TerritoryType GetTerritoryType() => Service.DataManager.GetExcelSheet().GetRow(Territory); public string GetIdString() => $"{Territory}_{Map}_{X}_{Y}_{Title.GetHashCode()}"; /// Tooltip text for map/minimap: Title with Description on second line if present. public string GetTooltipText() { var t = Title ?? ""; var d = Description ?? ""; return string.IsNullOrWhiteSpace(d) ? t : $"{t}\n{d}"; } public Vector2 GetCoordinate() => new(X, Y); /// Returns the stored map coordinates for display (same space as Place Note/Flag). public Vector2 GetMapCoordinate() => new(X, Y); public void Focus() { System.SystemConfig.FollowPlayer = false; System.IntegrationsController.OpenMap(Map); System.MapRenderer.CenterOnCoordinate(GetCoordinate()); } } public class MapNoteConfig { public List Notes { get; set; } = []; public int MaxNotes { get; set; } = 100; public static MapNoteConfig Load() => Service.PluginInterface.LoadConfigFile("MapNotes.data.json"); public void Save() => Service.PluginInterface.SaveConfigFile("MapNotes.data.json", System.MapNoteConfig); /// Finds a note at or near the given map coordinates (same space as Place Note). /// Distance in map coordinate space; typical icon is ~200–500 units, so 500 covers right-clicks on the icon. public MapNote? FindNoteAt(uint territoryId, uint mapId, float x, float y, float threshold = 500f) { MapNote? closest = null; var minDistSq = threshold * threshold; foreach (var n in Notes.Where(n => n.Territory == territoryId && n.Map == mapId)) { var dx = x - n.X; var dy = y - n.Y; var distSq = dx * dx + dy * dy; if (distSq < minDistSq) { minDistSq = distSq; closest = n; } } return closest; } }