v1.0.0.13: User-placed map notes with Title/Description; custom icon; notes on minimap

Made-with: Cursor
This commit is contained in:
2026-03-01 00:12:37 -05:00
parent b1c833ebcf
commit 542da3a71b
12 changed files with 383 additions and 17 deletions
+70
View File
@@ -0,0 +1,70 @@
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<Map>().GetRow(Map);
public TerritoryType GetTerritoryType() => Service.DataManager.GetExcelSheet<TerritoryType>().GetRow(Territory);
public string GetIdString() => $"{Territory}_{Map}_{X}_{Y}_{Title.GetHashCode()}";
/// <summary>Tooltip text for map/minimap: Title with Description on second line if present.</summary>
public string GetTooltipText()
{
var t = Title ?? "";
var d = Description ?? "";
return string.IsNullOrWhiteSpace(d) ? t : $"{t}\n{d}";
}
public Vector2 GetCoordinate() => new(X, Y);
/// <summary>Returns the stored map coordinates for display (same space as Place Note/Flag).</summary>
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<MapNote> Notes { get; set; } = [];
public int MaxNotes { get; set; } = 100;
public static MapNoteConfig Load() => Service.PluginInterface.LoadConfigFile<MapNoteConfig>("MapNotes.data.json");
public void Save() => Service.PluginInterface.SaveConfigFile("MapNotes.data.json", System.MapNoteConfig);
/// <summary>Finds a note at or near the given map coordinates (same space as Place Note).</summary>
/// <param name="threshold">Distance in map coordinate space; typical icon is ~200500 units, so 500 covers right-clicks on the icon.</param>
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;
}
}