Initial HSMappy release (fork of Mappy)

Made-with: Cursor
This commit is contained in:
2026-02-26 03:54:51 -05:00
commit 9659f7a7d1
72 changed files with 6625 additions and 0 deletions
@@ -0,0 +1,18 @@
using KamiLib.Classes;
using KamiLib.Extensions;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.Caches;
public class AetheryteAethernetCache : Cache<uint, Aetheryte?>
{
protected override Aetheryte? LoadValue(uint key)
{
if (Service.DataManager.GetExcelSheet<Aetheryte>().FirstOrNull(aetheryte => aetheryte.AethernetName.RowId == key) is not { AethernetGroup: var aethernetGroup })
return null;
if (Service.DataManager.GetExcelSheet<Aetheryte>().FirstOrNull(aetheryte => aetheryte.IsAetheryte && aetheryte.AethernetGroup == aethernetGroup) is not { } targetAetheryte)
return null;
return targetAetheryte;
}
}
+23
View File
@@ -0,0 +1,23 @@
using System.Linq;
using KamiLib.Classes;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.Caches;
public class CardRewardCache : Cache<uint, string>
{
protected override string LoadValue(uint key)
{
if (Service.DataManager.GetExcelSheet<TripleTriad>().GetRow(key) is { RowId: not 0 } triadInfo) {
var cardRewards = triadInfo.ItemPossibleReward
.Where(reward => reward.RowId is not 0)
.Select(reward => reward.Value)
.Where(item => item.RowId is not 0)
.Select(item => item.Name.ExtractText());
return string.Join("\n", cardRewards);
}
return string.Empty;
}
}
@@ -0,0 +1,24 @@
using System;
using KamiLib.Classes;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.Caches;
public class GatheringPointIconCache : Cache<uint, uint>
{
protected override uint LoadValue(uint key)
{
var gatheringPoint = Service.DataManager.GetExcelSheet<GatheringPoint>().GetRow(key);
var gatheringPointBase = Service.DataManager.GetExcelSheet<GatheringPointBase>().GetRow(gatheringPoint.GatheringPointBase.RowId);
return gatheringPointBase.GatheringType.RowId switch
{
0 => 60438,
1 => 60437,
2 => 60433,
3 => 60432,
5 => 60445,
_ => throw new Exception($"Unknown Gathering Type: {gatheringPointBase.GatheringType.RowId}"),
};
}
}
@@ -0,0 +1,15 @@
using KamiLib.Classes;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.Caches;
public class GatheringPointNameCache : Cache<(uint dataId, string name), string>
{
protected override string LoadValue((uint dataId, string name) key)
{
var gatheringPoint = Service.DataManager.GetExcelSheet<GatheringPoint>().GetRow(key.dataId);
var gatheringPointBase = Service.DataManager.GetExcelSheet<GatheringPointBase>().GetRow(gatheringPoint.GatheringPointBase.RowId);
return $"Lv. {gatheringPointBase.GatheringLevel.ToString()} {key.name}";
}
}
+18
View File
@@ -0,0 +1,18 @@
using KamiLib.Classes;
using Lumina.Excel.Sheets;
using Lumina.Extensions;
namespace Mappy.Classes.Caches;
public class TooltipCache : Cache<uint, string>
{
protected override string LoadValue(uint key)
{
var mapMarker = Service.DataManager.GetExcelSheet<MapSymbol>().FirstOrNull(marker => marker.Icon == key);
if (mapMarker is null) return string.Empty;
if (!mapMarker.Value.PlaceName.IsValid) return string.Empty;
return mapMarker.Value.PlaceName.Value.Name.ExtractText();
}
}
+9
View File
@@ -0,0 +1,9 @@
using KamiLib.Classes;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.Caches;
public class TripleTriadCache : Cache<uint, bool>
{
protected override bool LoadValue(uint key) => Service.DataManager.GetExcelSheet<TripleTriad>().HasRow(key);
}
+275
View File
@@ -0,0 +1,275 @@
using System;
using System.Drawing;
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using KamiLib.Classes;
using Mappy.Data;
using SeString = Dalamud.Game.Text.SeStringHandling.SeString;
namespace Mappy.Classes;
public class MarkerInfo
{
public required Vector2 Position { get; set; }
public required Vector2 Offset { get; set; }
public required float Scale { get; set; }
public uint? ObjectiveId { get; init; }
public uint? DataId { get; set; }
public MarkerType MarkerType { get; set; }
public uint IconId { get; set; }
public Func<string?>? PrimaryText { get; set; }
public Func<string?>? SecondaryText { get; set; }
public float? Radius { get; set; }
public Vector4 RadiusColor { get; set; } = KnownColor.CornflowerBlue.Vector();
public Vector4 RadiusOutlineColor { get; set; } = KnownColor.CornflowerBlue.Vector();
public Action? OnRightClicked { get; set; }
public Action? OnLeftClicked { get; set; }
public bool IsDynamicMarker { get; init; }
}
public static class DrawHelpers
{
private static bool DebugMode => System.SystemConfig.DebugMode;
public const uint QuestionMarkIcon = 60071;
/// <summary>
/// Offset Vector of SelectedX, SelectedY, scaled with SelectedSizeFactor
/// </summary>
public static Vector2 GetMapOffsetVector() => GetRawMapOffsetVector() * GetMapScaleFactor();
/// <summary>
/// Unscaled Vector of SelectedX, SelectedY
/// </summary>
public static unsafe Vector2 GetRawMapOffsetVector() => new(AgentMap.Instance()->SelectedOffsetX, AgentMap.Instance()->SelectedOffsetY);
/// <summary>
/// Selected Scale Factor
/// </summary>
public static unsafe float GetMapScaleFactor() => AgentMap.Instance()->SelectedMapSizeFactorFloat;
/// <summary>
/// 1024 vector, center offset vector
/// </summary>
public static Vector2 GetMapCenterOffsetVector() => new(1024.0f, 1024.0f);
/// <summary>
/// Offset for the top left corner of the drawn map
/// </summary>
public static Vector2 GetCombinedOffsetVector() => -GetMapOffsetVector() + GetMapCenterOffsetVector();
public static void DrawMapMarker(MarkerInfo markerInfo)
{
if (markerInfo.IconId is 0) return;
// Don't draw markers that are positioned off the map texture
if (markerInfo.Position.X < 0.0f || markerInfo.Position.X > 2048.0f * markerInfo.Scale || markerInfo.Position.Y < 0.0f ||
markerInfo.Position.Y > 2048.0f * markerInfo.Scale)
return;
markerInfo.IconId = markerInfo.IconId switch
{
// Translate circle markers that don't have icons, into [?] icon
>= 60483 and <= 60494 => QuestionMarkIcon,
// Translate Gemstone Trader Icon into smaller version... why square, why.
60091 => 61731,
// Leave all other icons as they were
_ => markerInfo.IconId,
};
if (DebugMode) {
markerInfo.SecondaryText = markerInfo.PrimaryText;
markerInfo.PrimaryText = () => $"[Debug] IconId: {markerInfo.IconId}";
}
// If this is the first time we have seen this iconId, save it
if (System.IconConfig.IconSettingMap.TryAdd(markerInfo.IconId, new IconSetting { IconId = markerInfo.IconId, })) {
System.IconConfig.Save();
}
// If this icon is disabled, don't even process it
if (System.IconConfig.IconSettingMap[markerInfo.IconId] is { Hide: true }) {
return;
}
// Only process modules for Dynamic Markers
if (markerInfo.IsDynamicMarker) {
foreach (var module in System.Modules) {
if (module.ProcessMarker(markerInfo)) {
break;
}
}
}
DrawRadiusUnderlay(markerInfo);
DrawIcon(markerInfo);
ProcessInteractions(markerInfo);
DrawTooltip(markerInfo);
}
private static unsafe void DrawRadiusUnderlay(MarkerInfo markerInfo)
{
if (markerInfo is not { Radius: { } markerRadius and > 1.0f }) return;
var center = markerInfo.Position + markerInfo.Offset + ImGui.GetWindowPos();
DrawRadiusCircle(center, markerRadius, markerInfo.Scale, AgentMap.Instance()->SelectedMapSizeFactorFloat,
markerInfo.RadiusColor with { W = System.SystemConfig.AreaColor.W },
markerInfo.RadiusOutlineColor with { W = System.SystemConfig.AreaOutlineColor.W });
}
/// <summary>
/// Draw the quest/area radius circle using the same formula as the area map.
/// Used by both the area map (DrawRadiusUnderlay) and the minimap so behavior is identical.
/// </summary>
public static unsafe void DrawRadiusCircle(Vector2 centerScreen, float markerRadius, float mapScale, float sizeFactor, Vector4? fillColor = null, Vector4? outlineColor = null)
{
if (markerRadius <= 1.0f) return;
var radiusPixels = markerRadius * mapScale * sizeFactor;
if (radiusPixels < 0.5f) return;
var fill = ImGui.GetColorU32(fillColor ?? System.SystemConfig.AreaColor);
var outline = ImGui.GetColorU32(outlineColor ?? System.SystemConfig.AreaOutlineColor);
var drawList = ImGui.GetWindowDrawList();
drawList.AddCircleFilled(centerScreen, radiusPixels, fill);
drawList.AddCircle(centerScreen, radiusPixels, outline, 0, 3.0f);
}
private static void DrawIcon(MarkerInfo markerInfo)
{
var texture = Service.TextureProvider.GetFromGameIcon(markerInfo.IconId).GetWrapOrEmpty();
var scale = System.SystemConfig.ScaleWithZoom ? markerInfo.Scale : 1.0f;
var iconScale = System.SystemConfig.IconScale;
if (markerInfo.IconId is 60401 or 60402) {
scale *= 2.0f;
}
// Fixed scale not supported for map region markers
if (IsRegionIcon(markerInfo.IconId)) {
scale = markerInfo.Scale;
iconScale = 0.42f;
}
ImGui.SetCursorPos(markerInfo.Position + markerInfo.Offset - texture.Size * iconScale / 2.0f * scale * System.IconConfig.IconSettingMap[markerInfo.IconId].Scale);
var cursorScreenPos = ImGui.GetCursorScreenPos();
var iconSize = texture.Size * scale * iconScale * System.IconConfig.IconSettingMap[markerInfo.IconId].Scale;
ImGui.Image(texture.Handle, iconSize, Vector2.Zero, Vector2.One, System.IconConfig.IconSettingMap[markerInfo.IconId].Color);
if (DebugMode) {
foreach (var x in Enumerable.Range(-1, 3)) {
foreach (var y in Enumerable.Range(-1, 3)) {
ImGui.GetWindowDrawList().AddRect(cursorScreenPos + new Vector2(x, y), cursorScreenPos + iconSize, ImGui.GetColorU32(KnownColor.White.Vector()), 3.0f);
}
}
ImGui.GetWindowDrawList().AddRect(cursorScreenPos, cursorScreenPos + iconSize, ImGui.GetColorU32(KnownColor.Red.Vector()), 3.0f);
}
}
public static void DrawText(MarkerInfo markerInfo, SeString text) => DrawText(markerInfo, text.ToString());
public static void DrawText(MarkerInfo markerInfo, string text)
{
using var largeFont = System.LargeAxisFontHandle.Push();
ImGui.SetWindowFontScale(markerInfo.Scale);
var textSize = ImGui.CalcTextSize(text);
var drawPosition = markerInfo.Position + markerInfo.Offset + ImGui.GetWindowPos() - textSize / 2.0f;
drawPosition = new Vector2(MathF.Round(drawPosition.X), MathF.Round(drawPosition.Y));
if (System.SystemConfig.DebugMode) {
ImGui.GetWindowDrawList().AddCircleFilled(markerInfo.Position + markerInfo.Offset + ImGui.GetWindowPos(), 5.0f, ImGui.GetColorU32(KnownColor.Red.Vector()));
ImGui.GetWindowDrawList().AddRect(drawPosition, drawPosition + textSize, ImGui.GetColorU32(KnownColor.Green.Vector()), 3.0f);
}
foreach (var x in Enumerable.Range(-1, 3)) {
foreach (var y in Enumerable.Range(-1, 3)) {
if (x is 0 && y is 0) continue;
ImGui.SetCursorScreenPos(drawPosition + new Vector2(x, y));
ImGui.TextColored(KnownColor.Black.Vector(), text);
}
}
ImGui.SetCursorScreenPos(drawPosition);
ImGui.TextColored(KnownColor.White.Vector(), text);
ImGui.SetWindowFontScale(1.0f);
}
private static void ProcessInteractions(MarkerInfo markerInfo)
{
if (System.IconConfig.IconSettingMap[markerInfo.IconId] is not { AllowClick: true }) return;
if (markerInfo is { OnRightClicked: { } rightClickAction } && ImGui.IsItemClicked(ImGuiMouseButton.Right)) {
rightClickAction.Invoke();
}
if (markerInfo is { OnLeftClicked: { } leftClickAction } && ImGui.IsItemClicked(ImGuiMouseButton.Left)) {
leftClickAction.Invoke();
}
}
private static unsafe void DrawTooltip(MarkerInfo markerInfo)
{
if (System.IconConfig.IconSettingMap[markerInfo.IconId] is { AllowTooltip: false } && !DebugMode) {
return;
}
var isActivatedViaRadius = false;
if (markerInfo is { Radius: { } sameRadius and > 1.0f }) {
var center = markerInfo.Position + markerInfo.Offset + ImGui.GetWindowPos();
var radius = sameRadius * markerInfo.Scale * AgentMap.Instance()->SelectedMapSizeFactorFloat;
if (Vector2.Distance(ImGui.GetMousePos() - System.MapWindow.MapDrawOffset + ImGui.GetWindowPos(), center) <= radius && System.MapWindow.HoveredFlags.Any()) {
isActivatedViaRadius = true;
}
}
if (isActivatedViaRadius || ImGui.IsItemHovered()) {
if (markerInfo.PrimaryText?.Invoke() is { Length: > 0 } primaryText) {
using var tooltip = ImRaii.Tooltip();
ImGui.Image(Service.TextureProvider.GetFromGameIcon(markerInfo.IconId).GetWrapOrEmpty().Handle, ImGuiHelpers.ScaledVector2(32.0f, 32.0f));
ImGui.SameLine();
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 7.5f * ImGuiHelpers.GlobalScale);
var cursorPosition = ImGui.GetCursorPos();
ImGui.Text(primaryText);
if (markerInfo.SecondaryText?.Invoke() is { Length: > 0 } secondaryText) {
ImGui.SameLine();
ImGui.SetCursorPos(cursorPosition);
ImGuiTweaks.TextColoredUnformatted(KnownColor.Gray.Vector(), $"\n{secondaryText}");
}
}
}
}
public static bool IsDisallowedIcon(uint iconId) =>
iconId switch
{
60091 => true,
_ when IsRegionIcon(iconId) => true,
_ => false,
};
public static bool IsRegionIcon(uint iconId) =>
iconId switch
{
>= 63200 and < 63900 => true,
>= 62620 and < 62800 => true,
_ => false,
};
}
+19
View File
@@ -0,0 +1,19 @@
using System;
namespace Mappy.Classes;
[Flags]
public enum HoverFlags
{
Nothing = 0,
MapTexture = 1 << 0,
Toolbar = 1 << 1,
CoordinateBar = 1 << 2,
Window = 1 << 3,
WindowInnerFrame = 1 << 4,
}
public static class HoverFlagsExtensions
{
public static bool Any(this HoverFlags flags) => flags != HoverFlags.Nothing;
}
@@ -0,0 +1,69 @@
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using KamiLib.Window;
using Mappy.Data;
using Mappy.Windows;
namespace Mappy.Classes.MapWindowComponents;
public unsafe class MapContextMenu
{
public void Draw(Vector2 mapDrawOffset)
{
using var contextMenu = ImRaii.ContextPopup("Mappy_Context_Menu");
if (!contextMenu) return;
if (ImGui.MenuItem("Place Flag")) {
var cursorPosition = ImGui.GetMousePosOnOpeningCurrentPopup(); // Get initial cursor position (screen relative)
var mapChildOffset = mapDrawOffset; // Get the screen position we started drawing the map at
var mapDrawPositionOffset = System.MapRenderer.DrawPosition; // Get the map texture top left offset vector
var textureClickLocation = (cursorPosition - mapChildOffset - mapDrawPositionOffset) / MapRenderer.MapRenderer.Scale; // Math
var result = textureClickLocation - new Vector2(1024.0f, 1024.0f); // One of our vectors made the map centered, undo it.
var scaledResult = result / DrawHelpers.GetMapScaleFactor() + DrawHelpers.GetRawMapOffsetVector(); // Apply offset x/y and scalefactor
AgentMap.Instance()->FlagMarkerCount = 0;
AgentMap.Instance()->SetFlagMapMarker(AgentMap.Instance()->SelectedTerritoryId, AgentMap.Instance()->SelectedMapId, scaledResult.X, scaledResult.Y);
AgentChatLog.Instance()->InsertTextCommandParam(1048, false);
}
if (ImGui.MenuItem("Remove Flag", false, AgentMap.Instance()->FlagMarkerCount is not 0)) {
AgentMap.Instance()->FlagMarkerCount = 0;
}
ImGuiHelpers.ScaledDummy(5.0f);
if (ImGui.MenuItem("Center on Player", false, Service.ObjectTable.LocalPlayer is not null) && Service.ObjectTable.LocalPlayer is not null) {
System.IntegrationsController.OpenOccupiedMap();
System.MapRenderer.CenterOnGameObject(Service.ObjectTable.LocalPlayer);
}
if (ImGui.MenuItem("Center on Map")) {
System.SystemConfig.FollowPlayer = false;
System.MapRenderer.DrawOffset = Vector2.Zero;
}
ImGuiHelpers.ScaledDummy(5.0f);
if (ImGui.MenuItem("Lock Zoom", "", ref System.SystemConfig.ZoomLocked)) {
SystemConfig.Save();
}
ImGuiHelpers.ScaledDummy(5.0f);
if (ImGui.MenuItem("Open Quest List", false, System.WindowManager.GetWindow<QuestListWindow>() is null)) {
System.WindowManager.AddWindow(new QuestListWindow(), WindowFlags.OpenImmediately | WindowFlags.RequireLoggedIn);
}
if (ImGui.MenuItem("Open Fate List", false, System.WindowManager.GetWindow<FateListWindow>() is null)) {
System.WindowManager.AddWindow(new FateListWindow(), WindowFlags.OpenImmediately | WindowFlags.RequireLoggedIn);
}
if (ImGui.MenuItem("Open Flag List", false, System.WindowManager.GetWindow<FlagHistoryWindow>() is null)) {
System.WindowManager.AddWindow(new FlagHistoryWindow(), WindowFlags.OpenImmediately | WindowFlags.RequireLoggedIn);
}
}
}
@@ -0,0 +1,52 @@
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
namespace Mappy.Classes.MapWindowComponents;
public unsafe class MapCoordinateBar
{
public void Draw(bool isMapHovered, Vector2 mapDrawOffset)
{
var coordinateBarSize = new Vector2(ImGui.GetContentRegionMax().X, 20.0f * ImGuiHelpers.GlobalScale);
ImGui.SetCursorPos(ImGui.GetContentRegionMax() - coordinateBarSize);
using var childBackgroundStyle = ImRaii.PushColor(ImGuiCol.ChildBg, Vector4.Zero with { W = System.SystemConfig.CoordinateBarFade });
using var coordinateChild = ImRaii.Child("coordinate_child", coordinateBarSize);
if (!coordinateChild) return;
var offsetX = -AgentMap.Instance()->SelectedOffsetX;
var offsetY = -AgentMap.Instance()->SelectedOffsetY;
var scale = AgentMap.Instance()->SelectedMapSizeFactor;
var characterMapPosition = MapUtil.WorldToMap(Service.ObjectTable.LocalPlayer?.Position ?? Vector3.Zero, offsetX, offsetY, 0, (uint)scale);
var characterPosition = $"Character {characterMapPosition.X:F1} {characterMapPosition.Y:F1}";
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 2.0f * ImGuiHelpers.GlobalScale);
var characterStringSize = ImGui.CalcTextSize(characterPosition);
ImGui.SetCursorPosX(ImGui.GetContentRegionMax().X / 3.0f - characterStringSize.X / 2.0f);
if (AgentMap.Instance()->SelectedMapId == AgentMap.Instance()->CurrentMapId) {
ImGui.TextColored(System.SystemConfig.CoordinateTextColor, characterPosition);
}
if (isMapHovered) {
var cursorPosition = ImGui.GetMousePos() - mapDrawOffset;
cursorPosition -= System.MapRenderer.DrawPosition;
cursorPosition /= MapRenderer.MapRenderer.Scale;
cursorPosition -= new Vector2(1024.0f, 1024.0f);
cursorPosition -= new Vector2(offsetX, offsetY);
cursorPosition /= AgentMap.Instance()->SelectedMapSizeFactorFloat;
var cursorMapPosition = MapUtil.WorldToMap(new Vector3(cursorPosition.X, 0.0f, cursorPosition.Y), offsetX, offsetY, 0, (uint)scale);
var cursorPositionString = $"Cursor {cursorMapPosition.X:F1} {cursorMapPosition.Y:F1}";
var cursorStringSize = ImGui.CalcTextSize(characterPosition);
ImGui.SameLine(ImGui.GetContentRegionMax().X * 2.0f / 3.0f - cursorStringSize.X / 2.0f);
ImGui.TextColored(System.SystemConfig.CoordinateTextColor, cursorPositionString);
}
}
}
@@ -0,0 +1,162 @@
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using KamiLib.Extensions;
using KamiLib.Window;
using Lumina.Excel.Sheets;
using Mappy.Windows;
using MapType = Lumina.Excel.Sheets.MapType;
namespace Mappy.Classes.MapWindowComponents;
public unsafe class MapToolbar
{
public void Draw()
{
var toolbarSize = new Vector2(ImGui.GetContentRegionMax().X, 33.0f * ImGuiHelpers.GlobalScale);
using var childBackgroundStyle = ImRaii.PushColor(ImGuiCol.ChildBg, Vector4.Zero with { W = System.SystemConfig.ToolbarFade });
using var toolbarChild = ImRaii.Child("toolbar_child", toolbarSize);
if (!toolbarChild) return;
ImGui.SetCursorPos(new Vector2(5.0f, 5.0f));
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.ArrowUp, "up", "Open Parent Map")) {
var valueArgs = new AtkValue
{
Type = ValueType.Int, Int = 5,
};
var returnValue = new AtkValue();
AgentMap.Instance()->ReceiveEvent(&returnValue, &valueArgs, 1, 0);
}
ImGui.SameLine();
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.LayerGroup, "layers", "Show Map Layers")) {
ImGui.OpenPopup("Mappy_Show_Layers");
}
DrawLayersContextMenu();
ImGui.SameLine();
using (var _ = ImRaii.PushColor(ImGuiCol.Button, ImGui.GetStyle().GetColor(ImGuiCol.ButtonActive), System.SystemConfig.FollowPlayer)) {
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.LocationArrow, "follow", "Toggle Follow Player")) {
System.SystemConfig.FollowPlayer = !System.SystemConfig.FollowPlayer;
if (System.SystemConfig.FollowPlayer) {
System.IntegrationsController.OpenOccupiedMap();
}
}
}
ImGui.SameLine();
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.ArrowsToCircle, "centerPlayer", "Center on Player") && Service.ObjectTable.LocalPlayer is not null) {
// Don't center on player if we are already following the player.
if (!System.SystemConfig.FollowPlayer) {
System.IntegrationsController.OpenOccupiedMap();
System.MapRenderer.CenterOnGameObject(Service.ObjectTable.LocalPlayer);
}
}
ImGui.SameLine();
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.MapMarked, "centerMap", "Center on Map")) {
System.SystemConfig.FollowPlayer = false;
System.MapRenderer.DrawOffset = Vector2.Zero;
}
ImGui.SameLine();
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.Search, "search", "Search for Map")) {
System.WindowManager.AddWindow(new MapSelectionWindow
{
SingleSelectionCallback = selection =>
{
if (selection?.Map != null) {
if (AgentMap.Instance()->SelectedMapId != selection.Map.RowId) {
System.IntegrationsController.OpenMap(selection.Map.RowId);
}
if (selection.MarkerLocation is { } location) {
System.SystemConfig.FollowPlayer = false;
System.MapRenderer.DrawOffset = -location + DrawHelpers.GetMapCenterOffsetVector();
}
}
},
}, WindowFlags.OpenImmediately | WindowFlags.RequireLoggedIn);
}
var offset = System.SystemConfig.HideWindowFrame ? 50.0f : 25.0f;
ImGui.SameLine();
ImGui.SetCursorPosX(ImGui.GetContentRegionMax().X - offset * ImGuiHelpers.GlobalScale - ImGui.GetStyle().ItemSpacing.X);
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.Cog, "settings", "Open Settings")) {
System.ConfigWindow.UnCollapseOrShow();
ImGui.SetWindowFocus(System.ConfigWindow.WindowName);
}
if (!System.SystemConfig.HideWindowFrame) return;
ImGui.SameLine();
if (MappyGuiTweaks.IconButton(FontAwesomeIcon.Times, "closeMap", "Close Map"))
{
System.MapWindow.Close();
}
}
private void DrawLayersContextMenu()
{
using var contextMenu = ImRaii.Popup("Mappy_Show_Layers");
if (!contextMenu) return;
var currentMap = Service.DataManager.GetExcelSheet<Map>().GetRow(AgentMap.Instance()->SelectedMapId);
if (currentMap.RowId is 0) return;
// If this is a region map
if (currentMap.MapType.RowId == 3) {
foreach (var marker in AgentMap.Instance()->MapMarkers) {
if (!DrawHelpers.IsRegionIcon(marker.MapMarker.IconId)) continue;
var label = marker.MapMarker.Subtext.AsDalamudSeString();
if (ImGui.MenuItem(label.ToString())) {
System.IntegrationsController.OpenMap(marker.DataKey);
System.SystemConfig.FollowPlayer = false;
System.MapRenderer.DrawOffset = Vector2.Zero;
}
}
}
// Any other map
else {
var layers = Service.DataManager.GetExcelSheet<Map>()
.Where(eachMap => eachMap.PlaceName.RowId == currentMap.PlaceName.RowId)
.Where(eachMap => eachMap.MapIndex != 0)
.OrderBy(eachMap => eachMap.MapIndex)
.ToList();
if (layers.Count is 0) {
ImGui.Text("No layers for this map");
}
foreach (var layer in layers) {
if (ImGui.MenuItem(layer.PlaceNameSub.Value.Name.ExtractText(), "", AgentMap.Instance()->SelectedMapId == layer.RowId)) {
System.IntegrationsController.OpenMap(layer.RowId);
System.SystemConfig.FollowPlayer = false;
System.MapRenderer.DrawOffset = Vector2.Zero;
}
}
}
}
}
+25
View File
@@ -0,0 +1,25 @@
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
namespace Mappy.Classes;
public static class MappyGuiTweaks
{
public static bool IconButton(FontAwesomeIcon icon, string id, string? tooltip)
{
using var imRaiiId = ImRaii.PushId(id);
bool result;
using (Service.PluginInterface.UiBuilder.IconFontFixedWidthHandle.Push()) {
result = ImGui.Button($"{icon.ToIconString()}");
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && tooltip is not null) {
ImGui.SetTooltip(tooltip);
}
return result;
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Mappy.Classes;
public enum MarkerType
{
Unknown = 0,
Fate = 1,
Stellar = 6,
}
@@ -0,0 +1,53 @@
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility.Raii;
using KamiLib.Extensions;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.SelectionWindowComponents;
public class AetheryteDrawableOption : DrawableOption
{
public required Aetheryte Aetheryte { get; set; }
public override string ExtraLineLong => GetName();
public override Map Map => GetAetheryteMap()!.Value; // Probably a bad idea
protected override string[] GetAdditionalFilterStrings() =>
[
Aetheryte.PlaceName.Value.Name.ExtractText(),
Aetheryte.AethernetName.Value.Name.ExtractText(),
];
protected override void DrawIcon()
{
using var imageFrame = ImRaii.Child($"image_frame{Aetheryte.RowId}#{MarkerLocation}#{ExtraLineLong}", new Vector2(Width, Height), false, ImGuiWindowFlags.NoInputs);
if (!imageFrame) return;
var xOffset = (Width - Height) / 2.0f;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + xOffset);
ImGui.Image(Service.TextureProvider.GetFromGameIcon(Aetheryte.IsAetheryte ? 60453 : 60430).GetWrapOrEmpty().Handle, new Vector2(Height, Height));
}
private Map? GetAetheryteMap()
{
if (Aetheryte.Map.RowId is not 0) return Aetheryte.Map.Value;
if (Service.DataManager.GetExcelSheet<Aetheryte>().FirstOrNull(aetheryte => aetheryte.IsAetheryte && aetheryte.AethernetGroup == Aetheryte.AethernetGroup) is not
{ } targetAetheryte)
return null;
return targetAetheryte.Map.Value;
}
private string GetName()
{
if (Aetheryte.AethernetName.RowId is not 0) return Aetheryte.AethernetName.Value.Name.ExtractText();
if (Aetheryte.PlaceName.RowId is not 0) return Aetheryte.PlaceName.Value.Name.ExtractText();
return string.Empty;
}
public override string GetElementKey() => base.GetElementKey() + $"{Aetheryte.RowId}";
}
@@ -0,0 +1,97 @@
using System.Drawing;
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.SelectionWindowComponents;
public abstract class DrawableOption
{
protected virtual string[] GetAdditionalFilterStrings() => [];
public virtual Map Map { get; set; }
protected static float Width => 133.5f * ImGuiHelpers.GlobalScale;
protected static float Height => 75.0f * ImGuiHelpers.GlobalScale;
protected abstract void DrawIcon();
public virtual string ExtraLineLong => string.Empty;
public virtual string ExtraLineShort => string.Empty;
public virtual Vector2? MarkerLocation => null;
public virtual string GetElementKey() => $"{Map.RowId}{MarkerLocation}{ExtraLineShort}{ExtraLineLong}";
public string[] GetFilterStrings()
{
if (Map.RowId is 0) return [];
var baseStrings = new[]
{
Map.PlaceNameRegion.ValueNullable?.Name.ExtractText() ?? string.Empty, Map.PlaceName.ValueNullable?.Name.ExtractText() ?? string.Empty,
Map.PlaceNameSub.ValueNullable?.Name.ExtractText() ?? string.Empty, Map.TerritoryType.ValueNullable?.Name.ExtractText() ?? string.Empty, Map.Id.ExtractText(),
};
return baseStrings.Concat(GetAdditionalFilterStrings()).ToArray();
}
public void Draw()
{
using var id = ImRaii.PushId(Map.RowId.ToString());
DrawIcon();
ImGui.SameLine();
using var contentsFrame = ImRaii.Child($"contents_frame#{GetElementKey()}", new Vector2(ImGui.GetContentRegionAvail().X, Height), false, ImGuiWindowFlags.NoInputs);
if (!contentsFrame) return;
ImGuiHelpers.ScaledDummy(1.0f);
using var table = ImRaii.Table("data_table", 2, ImGuiTableFlags.SizingStretchProp);
if (!table) return;
ImGui.TableSetupColumn("##column1", ImGuiTableColumnFlags.None, 2.0f);
ImGui.TableSetupColumn("##column2", ImGuiTableColumnFlags.None, 1.0f);
var placeName = Map.PlaceName.ValueNullable?.Name.ExtractText() ?? string.Empty;
var zoneName = Map.PlaceNameSub.ValueNullable?.Name.ExtractText() ?? string.Empty;
var regionName = Map.PlaceNameRegion.ValueNullable?.Name.ExtractText() ?? string.Empty;
ImGui.TableNextColumn();
ImGui.TextUnformatted(placeName);
ImGui.TableNextColumn();
ImGui.TextUnformatted(Map.RowId.ToString());
ImGui.TableNextRow();
ImGui.TableNextColumn();
using var grayColor = ImRaii.PushColor(ImGuiCol.Text, KnownColor.DarkGray.Vector());
if (!zoneName.IsNullOrEmpty() && !regionName.IsNullOrEmpty()) {
ImGui.TextUnformatted($"{regionName}, {zoneName}");
}
else if (!zoneName.IsNullOrEmpty()) {
ImGui.TextUnformatted($"{zoneName}");
}
else if (!regionName.IsNullOrEmpty()) {
ImGui.TextUnformatted($"{regionName}");
}
ImGui.TableNextColumn();
ImGui.TextUnformatted($"{Map.Id}");
ImGui.TableNextColumn();
ImGui.TextUnformatted(ExtraLineLong);
ImGui.TableNextColumn();
ImGui.TextUnformatted(ExtraLineShort);
}
}
@@ -0,0 +1,42 @@
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.SelectionWindowComponents;
public class MapDrawableOption : DrawableOption
{
protected override void DrawIcon()
{
var option = Map.TerritoryType.Value;
using var imageFrame = ImRaii.Child($"image_frame{option}", new Vector2(Width, Height), false, ImGuiWindowFlags.NoInputs);
if (!imageFrame) return;
var texture = GetMapTexture(Map.RowId);
if (texture is not null) {
ImGui.Image(texture.Handle, new Vector2(Width, Height), new Vector2(0.15f, 0.15f), new Vector2(0.85f, 0.85f));
}
else {
ImGuiHelpers.ScaledDummy(Width, Height);
}
}
public static IDalamudTextureWrap? GetMapTexture(uint mapId)
{
if (mapId is 0) return null;
var map = Service.DataManager.GetExcelSheet<Map>().GetRow(mapId);
var territory = map.TerritoryType;
if (!territory.IsValid) return null;
var loadingImage = territory.Value.LoadingImage;
if (!loadingImage.IsValid) return null;
var texturePath = $"ui/loadingimage/{loadingImage.Value.FileName}_hr1.tex";
return Service.TextureProvider.GetFromGame(texturePath).GetWrapOrDefault();
}
}
@@ -0,0 +1,35 @@
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility.Raii;
using Lumina.Excel.Sheets;
namespace Mappy.Classes.SelectionWindowComponents;
public class PoiDrawableOption : DrawableOption
{
public required MapMarker MapMarker { get; set; }
public override Vector2? MarkerLocation => new Vector2(MapMarker.X, MapMarker.Y);
public override Map Map => Service.DataManager.GetExcelSheet<Map>().FirstOrDefault(map => map.MapMarkerRange == MapMarker.RowId);
public override string ExtraLineLong => MapMarker.PlaceNameSubtext.Value.Name.ExtractText();
protected override void DrawIcon()
{
using var imageFrame = ImRaii.Child($"image_frame{MapMarker.RowId}#{MarkerLocation}", new Vector2(Width, Height), false, ImGuiWindowFlags.NoInputs);
if (!imageFrame) return;
var xOffset = (Width - Height) / 2.0f;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + xOffset);
ImGui.Image(Service.TextureProvider.GetFromGameIcon((uint)MapMarker.Icon).GetWrapOrEmpty().Handle, new Vector2(Height, Height));
}
protected override string[] GetAdditionalFilterStrings() =>
[
MapMarker.PlaceNameSubtext.Value.Name.ExtractText(),
];
public override string GetElementKey() => base.GetElementKey() + $"{MapMarker.RowId}";
}