diff --git a/Mappy/Controllers/IntegrationsController.cs b/Mappy/Controllers/IntegrationsController.cs index ebf8403..d053446 100644 --- a/Mappy/Controllers/IntegrationsController.cs +++ b/Mappy/Controllers/IntegrationsController.cs @@ -113,11 +113,9 @@ public unsafe class IntegrationsController : IDisposable try { AgentMap.Instance()->Hide(); } catch { } SilentRefreshInProgress = false; } + // Do NOT update quest/temp baselines here: if the user accepts a quest or advances a step during + // these frames, we would overwrite the baseline and never trigger a refresh for that change. _wasBetweenAreas = Service.Condition.IsBetweenAreas(); - _lastQuestCount = GetActiveQuestCount(); - try { _lastTempMarkerCount = (int)AgentMap.Instance()->TempMapMarkerCount; } catch { } - _lastQuestSequenceSnapshot = GetQuestSequenceSnapshot(); - _lastTempMarkerSnapshot = GetTempMarkerSnapshot(); return; } diff --git a/Mappy/MapRenderer/MapRenderer.Core.cs b/Mappy/MapRenderer/MapRenderer.Core.cs index 0b9b543..8e94cf2 100644 --- a/Mappy/MapRenderer/MapRenderer.Core.cs +++ b/Mappy/MapRenderer/MapRenderer.Core.cs @@ -175,6 +175,7 @@ public unsafe partial class MapRenderer : IDisposable if (string.IsNullOrEmpty(idStr)) return false; // Try several path conventions so the minimap can show without ever requiring the user to open the Area Map. + // Prefer TextureProvider.GetFromGame (same as Area Map) so path resolution and mods match; fall back to Lumina GetTexFile. var fileName = idStr.Replace("/", ""); var pathsToTry = new[] { @@ -185,17 +186,24 @@ public unsafe partial class MapRenderer : IDisposable $"ui/uld/areamap/{fileName}.tex", }; + string? gamePath = null; IDalamudTextureWrap? texture = null; foreach (var path in pathsToTry) { + var wrap = Service.TextureProvider.GetFromGame(path).GetWrapOrDefault(); + if (wrap is not null && wrap.Handle != IntPtr.Zero && wrap.Size.X > 0 && wrap.Size.Y > 0) { + gamePath = path; + break; + } texture = LoadSingleTexture(path); if (texture is not null) break; } - if (texture is null) return false; + + if (gamePath is null && texture is null) return false; TrimMinimapCacheToLimit(); var entry = _minimapCache[mapId] = new MinimapCacheEntry(); - entry.PathKey = $"lumina:{mapId}"; - entry.Texture = texture; + entry.PathKey = gamePath is not null ? $"game:{gamePath}" : $"lumina:{mapId}"; + entry.Texture = texture; // null when using game path (looked up each frame) entry.ScaleFactor = map.SizeFactor / 100f; entry.OffsetX = map.OffsetX; entry.OffsetY = map.OffsetY; @@ -251,14 +259,23 @@ public unsafe partial class MapRenderer : IDisposable TryEnsureLuminaCacheFor(currentMapId); // Draw from cache if we have it for the current map. - if (!_minimapCache.TryGetValue(currentMapId, out var cached) || cached.Texture is null) + if (!_minimapCache.TryGetValue(currentMapId, out var cached)) + return; + + // Resolve texture: use cached texture, or for "game:" path look up via TextureProvider each frame (same as Area Map). + IDalamudTextureWrap? textureToDraw = cached.Texture; + if (textureToDraw is null && cached.PathKey.StartsWith("game:", StringComparison.Ordinal)) { + var path = cached.PathKey.Substring(5); + textureToDraw = Service.TextureProvider.GetFromGame(path).GetWrapOrDefault(); + } + if (textureToDraw is null) return; // Use the size passed by the minimap window (window size) so zoom/center is stable. if (size.X <= 0 || size.Y <= 0) return; var zoom = Math.Clamp(System.SystemConfig.MinimapZoom, 0.03f, 0.112f); - var mapSize = cached.Texture.Size.X; + var mapSize = textureToDraw.Size.X; // Scale so the map COVERS the view at zoom=1 (use max so no black bands at max zoom out). var fitScale = Math.Max(size.X, size.Y) / mapSize; var scale = fitScale / zoom; @@ -270,11 +287,11 @@ public unsafe partial class MapRenderer : IDisposable var drawOffset = (-playerCoord + new Vector2(cached.OffsetX, cached.OffsetY)) * cached.ScaleFactor; var centerOffset = size / 2.0f; - var mapCenterOffset = (cached.Texture.Size / 2f) * scale; + var mapCenterOffset = (textureToDraw.Size / 2f) * scale; var drawPosition = centerOffset - mapCenterOffset + drawOffset * scale; // Clamp so the map always fills the view (no black), but when zoomed in allow full pan so the player tracks. - var texSize = cached.Texture.Size * scale; + var texSize = textureToDraw.Size * scale; if (texSize.X > size.X && texSize.Y > size.Y) { // Zoomed in: allow full pan range so the map can shift in any direction and the player stays at center. drawPosition.X = Math.Clamp(drawPosition.X, size.X - texSize.X, texSize.X - size.X); @@ -287,7 +304,7 @@ public unsafe partial class MapRenderer : IDisposable // Content top-left in screen space so player is drawn at the true center of the minimap (not offset by title bar). var contentTopLeft = ImGui.GetCursorScreenPos(); - DrawMinimapCachedTextureAt(drawPosition, scale, cached.Texture); + DrawMinimapCachedTextureAt(drawPosition, scale, textureToDraw); var centerScreen = contentTopLeft + centerOffset; // Draw cone under markers so quest/FATE/POI markers stay visible on top of the cone. DrawMinimapConeAtCenter(centerScreen, scale); diff --git a/Mappy/Mappy.csproj b/Mappy/Mappy.csproj index 55f8a22..4ec3530 100644 --- a/Mappy/Mappy.csproj +++ b/Mappy/Mappy.csproj @@ -4,7 +4,7 @@ HSMappy HSMappy Knack117 - 1.0.0.19 + 1.0.0.20 A more versatile in-game map. Replaces the in-game map with an ImGui implementation with several additional features. Fork with minimap improvements, quest radius on minimap, and more. http://brassnet.ddns.net:33983/KnackAtNite/HSMappy diff --git a/Mappy/pluginmaster.json b/Mappy/pluginmaster.json index bbf5e4e..034349a 100644 --- a/Mappy/pluginmaster.json +++ b/Mappy/pluginmaster.json @@ -1 +1 @@ -[{"Author":"Knack117","Name":"HSMappy","Punchline":"A more versatile in-game map.","Description":"Replaces the in-game map with an ImGui implementation with several additional features. Fork with minimap improvements, quest radius on minimap, white gradient player cone, and more.","Changelog":"1.0.0.19: Minimap quest area circles refresh when multi-step objective progresses (1/3 -> 2/3, etc.). 1.0.0.18: Minimap automations (Desynth, Extract, Repair, Equip, Coffers); player movement cancels automation; >> button with tooltip. 1.0.0.17: Minimap stays visible during dialogue (NPC/quest); rest of hide behavior unchanged. 1.0.0.16: Draw minimap underneath other UI (HSUI etc); Draw Under Other UI config option. 1.0.0.15: Top/Bottom Info Bars: renamed from Map Info/Coordinate; configurable order for both; Repair % (most damaged item); font, size, color, background for both bars; right-align last bottom bar element. 1.0.0.14: Movement Trail (Carbonite-style) - red dots show where you've been on map and minimap; configurable distance, fade time, max points; Clear Trail in context menu. 1.0.0.13: User-placed map notes with Title/Description; custom white-page icon; notes on minimap; Remove Note via context menu; Note List layout fix. 1.0.0.12: Other players on minimap use distinct icon (60403) from party markers. 1.0.0.11: Player/NPC tracking on minimap with Show Players and NPCs toggle. 1.0.0.10: Release build. Suppress silent refresh at start of OnOpenMapHook; remove debug logging. 1.0.0.9: Duty List quest click: don't Hide() when viewing quest map (SelectedMapId != CurrentMapId). 1.0.0.8: Cancel silent refresh when opening map from Duty List so it doesn't immediately close. 1.0.0.7: Duty List quest click opens Area Map even when Hide With Game GUI would block it. 1.0.0.6: Minimap stays open after client restart (restore on login). 1.0.0.5: Fix crash when map texture path is invalid (ArgumentOutOfRangeException in Lumina GetFileHash). 1.0.0.4: Temp marker circle refreshes when quest objective is progressed. 1.0.0.3: Fix marker cache refresh after quest turn-in; invalidate temp cache so old markers don't persist. 1.0.0.2: Red direction arrow on minimap pointing to player flag. 1.0.0.1: Duty List quest click keeps Area Map open; player flags show on minimap. 1.0.0.0: Initial HSMappy release. Minimap: quest radius circle (orange, transparent), tooltip; cone drawn under markers; white gradient cone; /hsmappy commands.","InternalName":"HSMappy","AssemblyVersion":"1.0.0.19","RepoUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy","ApplicableVersion":"any","Tags":["map","mapping","overlay","utility"],"CategoryTags":["jobs"],"DalamudApiLevel":14,"DownloadLinkInstall":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.19/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.19/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.19/latest.zip","LastUpdate":"1772407702"}] +[{"Author":"Knack117","Name":"HSMappy","Punchline":"A more versatile in-game map.","Description":"Replaces the in-game map with an ImGui implementation with several additional features. Fork with minimap improvements, quest radius on minimap, white gradient player cone, and more.","Changelog":"1.0.0.20: Fix marker refresh sometimes not running when accepting a quest or advancing a quest step. 1.0.0.19: Minimap quest area circles refresh when multi-step objective progresses (1/3 -> 2/3, etc.). 1.0.0.18: Minimap automations (Desynth, Extract, Repair, Equip, Coffers); player movement cancels automation; >> button with tooltip. 1.0.0.17: Minimap stays visible during dialogue (NPC/quest); rest of hide behavior unchanged. 1.0.0.16: Draw minimap underneath other UI (HSUI etc); Draw Under Other UI config option. 1.0.0.15: Top/Bottom Info Bars: renamed from Map Info/Coordinate; configurable order for both; Repair % (most damaged item); font, size, color, background for both bars; right-align last bottom bar element. 1.0.0.14: Movement Trail (Carbonite-style) - red dots show where you've been on map and minimap; configurable distance, fade time, max points; Clear Trail in context menu. 1.0.0.13: User-placed map notes with Title/Description; custom white-page icon; notes on minimap; Remove Note via context menu; Note List layout fix. 1.0.0.12: Other players on minimap use distinct icon (60403) from party markers. 1.0.0.11: Player/NPC tracking on minimap with Show Players and NPCs toggle. 1.0.0.10: Release build. Suppress silent refresh at start of OnOpenMapHook; remove debug logging. 1.0.0.9: Duty List quest click: don't Hide() when viewing quest map (SelectedMapId != CurrentMapId). 1.0.0.8: Cancel silent refresh when opening map from Duty List so it doesn't immediately close. 1.0.0.7: Duty List quest click opens Area Map even when Hide With Game GUI would block it. 1.0.0.6: Minimap stays open after client restart (restore on login). 1.0.0.5: Fix crash when map texture path is invalid (ArgumentOutOfRangeException in Lumina GetFileHash). 1.0.0.4: Temp marker circle refreshes when quest objective is progressed. 1.0.0.3: Fix marker cache refresh after quest turn-in; invalidate temp cache so old markers don't persist. 1.0.0.2: Red direction arrow on minimap pointing to player flag. 1.0.0.1: Duty List quest click keeps Area Map open; player flags show on minimap. 1.0.0.0: Initial HSMappy release. Minimap: quest radius circle (orange, transparent), tooltip; cone drawn under markers; white gradient cone; /hsmappy commands.","InternalName":"HSMappy","AssemblyVersion":"1.0.0.20","RepoUrl":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy","ApplicableVersion":"any","Tags":["map","mapping","overlay","utility"],"CategoryTags":["jobs"],"DalamudApiLevel":14,"DownloadLinkInstall":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.20/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.20/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.20/latest.zip","LastUpdate":"1772591258"}]