v1.0.0.2: Red direction arrow on minimap pointing to player flag

Made-with: Cursor
This commit is contained in:
2026-02-26 21:23:17 -05:00
parent 4b2c337695
commit 31ab36d645
6 changed files with 69 additions and 10 deletions
@@ -150,14 +150,7 @@ public partial class MapRenderer
list.Add((tx, ty, tooltip, iconId));
}
if (agent->FlagMarkerCount > 0) {
ref var flag = ref agent->FlagMapMarkers[0];
if (flag.TerritoryId == agent->CurrentMapId || flag.TerritoryId == agent->CurrentTerritoryId) {
var tooltip = System.TooltipCache.GetValue(flag.MapMarker.IconId);
if (string.IsNullOrEmpty(tooltip)) tooltip = "Flag";
AddIfNew(1024.0f + (flag.XFloat - offsetX) * scaleFactor, 1024.0f + (flag.YFloat - offsetY) * scaleFactor, tooltip, flag.MapMarker.IconId);
}
}
// Flag excluded: drawn separately with red arrow via DrawMinimapFlagDirectionArrow
if (agent->TempMapMarkerCount > 0) {
var span = new Span<TempMapMarker>(Unsafe.AsPointer(ref agent->TempMapMarkers[0]), agent->TempMapMarkerCount);
@@ -290,6 +283,65 @@ public partial class MapRenderer
}
}
/// <summary>Draws a red direction arrow at the edge of the minimap pointing toward the player flag. Only shown when the flag is off the minimap.</summary>
private unsafe void DrawMinimapFlagDirectionArrow(
Vector2 contentTopLeft,
Vector2 drawPosition,
float scale,
Vector2 size,
Vector2 centerOffset,
float offsetX,
float offsetY,
float scaleFactor)
{
var agent = AgentMap.Instance();
if (agent->FlagMarkerCount is 0) return;
ref var flag = ref agent->FlagMapMarkers[0];
if (flag.TerritoryId != agent->CurrentTerritoryId || flag.MapId != agent->CurrentMapId) return;
var radius = Math.Min(size.X, size.Y) * 0.5f;
var arrowDist = radius - 4f;
var centerScreen = contentTopLeft + centerOffset;
var drawList = ImGui.GetWindowDrawList();
var tx = 1024.0f + (flag.XFloat - offsetX) * scaleFactor;
var ty = 1024.0f + (flag.YFloat - offsetY) * scaleFactor;
var targetInContent = drawPosition + new Vector2(tx, ty) * scale;
var toTarget = targetInContent - centerOffset;
var distToTarget = toTarget.Length();
if (distToTarget < 0.01f) return;
if (distToTarget <= radius) return; // Flag visible on minimap, no arrow
const float arrowSize = 20f;
const float baseHalf = 8f;
const float headDepth = 5f;
var colorHead = ImGui.GetColorU32(new Vector4(0.92f, 0.2f, 0.2f, 0.95f));
var colorOutline = ImGui.GetColorU32(new Vector4(0.45f, 0.08f, 0.08f, 1f));
var direction = toTarget / distToTarget;
var arrowPos = centerScreen + direction * arrowDist;
var cos = MathF.Cos(MathF.Atan2(direction.Y, direction.X));
var sin = MathF.Sin(MathF.Atan2(direction.Y, direction.X));
var perpX = -sin;
var perpY = cos;
var tipScreen = arrowPos + new Vector2(cos * arrowSize, sin * arrowSize);
var baseBack = arrowPos - new Vector2(cos * headDepth, sin * headDepth);
var base1Screen = baseBack + new Vector2(perpX * baseHalf, perpY * baseHalf);
var base2Screen = baseBack - new Vector2(perpX * baseHalf, perpY * baseHalf);
drawList.AddTriangleFilled(tipScreen, base1Screen, base2Screen, colorHead);
drawList.AddTriangle(tipScreen, base1Screen, base2Screen, colorOutline, 2f);
var tooltip = System.TooltipCache.GetValue(flag.MapMarker.IconId);
if (string.IsNullOrEmpty(tooltip)) tooltip = "Flag";
var minX = Math.Min(tipScreen.X, Math.Min(base1Screen.X, base2Screen.X)) - 4f;
var minY = Math.Min(tipScreen.Y, Math.Min(base1Screen.Y, base2Screen.Y)) - 4f;
var maxX = Math.Max(tipScreen.X, Math.Max(base1Screen.X, base2Screen.X)) + 4f;
var maxY = Math.Max(tipScreen.Y, Math.Max(base1Screen.Y, base2Screen.Y)) + 4f;
if (ImGui.IsMouseHoveringRect(new Vector2(minX, minY), new Vector2(maxX, maxY)))
ImGui.SetTooltip(tooltip);
}
private static bool IsInMinimapBounds(Vector2 contentPos, Vector2 size, float margin)
{
// Use a large margin so we don't cull markers that are panned slightly off (zoomed in).