4 Commits

5 changed files with 39 additions and 15 deletions
@@ -102,7 +102,6 @@ public unsafe class AddonAreaMapController : IDisposable
return; return;
} }
// If the window actually considered closed by the agent.
if (AgentMap.Instance()->AddonId is 0) if (AgentMap.Instance()->AddonId is 0)
{ {
System.WindowManager.GetWindow<MapWindow>()?.Close(); System.WindowManager.GetWindow<MapWindow>()?.Close();
+37 -11
View File
@@ -35,6 +35,8 @@ public unsafe class IntegrationsController : IDisposable
private int _silentRefreshHideFramesRemaining; private int _silentRefreshHideFramesRemaining;
/// <summary>Frames to skip quest/temp-marker-triggered silent refresh after user opened map via Duty List (quest/gathering/flag/teleport).</summary> /// <summary>Frames to skip quest/temp-marker-triggered silent refresh after user opened map via Duty List (quest/gathering/flag/teleport).</summary>
private int _suppressSilentRefreshFramesRemaining; private int _suppressSilentRefreshFramesRemaining;
/// <summary>Frames after user opened map via Duty List; OnShowHook should not Hide() during this window (ProcessingCommand is cleared when MapWindow opens).</summary>
private int _userOpenedMapFramesRemaining;
/// <summary>True while we're doing a silent refresh; OnAreaMapPreShow should not open the MapWindow.</summary> /// <summary>True while we're doing a silent refresh; OnAreaMapPreShow should not open the MapWindow.</summary>
public static bool SilentRefreshInProgress { get; private set; } public static bool SilentRefreshInProgress { get; private set; }
@@ -142,6 +144,9 @@ public unsafe class IntegrationsController : IDisposable
if (_suppressSilentRefreshFramesRemaining > 0) { if (_suppressSilentRefreshFramesRemaining > 0) {
_suppressSilentRefreshFramesRemaining--; _suppressSilentRefreshFramesRemaining--;
} }
if (_userOpenedMapFramesRemaining > 0) {
_userOpenedMapFramesRemaining--;
}
var skipQuestTempRefresh = _suppressSilentRefreshFramesRemaining > 0; var skipQuestTempRefresh = _suppressSilentRefreshFramesRemaining > 0;
var questCount = GetActiveQuestCount(); var questCount = GetActiveQuestCount();
@@ -189,9 +194,11 @@ public unsafe class IntegrationsController : IDisposable
} }
} }
/// <summary>Call when user opens map via Duty List (quest/gathering/flag/teleport). Suppresses quest/temp-marker-triggered silent refresh for ~1s so we don't close the map.</summary> /// <summary>Call when user opens map via Duty List (quest/gathering/flag/teleport). Cancels any in-progress silent refresh so we never Hide() the map. Suppresses new quest/temp-marker-triggered refresh for ~1s. Must be called BEFORE openMapHook.Original so OnFrameworkUpdate cannot call Hide() first.</summary>
private void SuppressSilentRefreshForUserMapOpen() private void SuppressSilentRefreshForUserMapOpen()
{ {
_silentRefreshHideFramesRemaining = 0; // Cancel in-progress silent refresh so we never Hide() the map the user just opened
SilentRefreshInProgress = false;
_suppressSilentRefreshFramesRemaining = 30; // ~1 second at typical framerate _suppressSilentRefreshFramesRemaining = 30; // ~1 second at typical framerate
} }
@@ -259,8 +266,19 @@ public unsafe class IntegrationsController : IDisposable
{ {
Service.Log.Verbose("[OnShow] Beginning Show"); Service.Log.Verbose("[OnShow] Beginning Show");
// If you managed to open the window while the agent says it should be closed // When user just opened via Duty List / gathering / flag / teleport, pass through immediately.
if (System.MapWindow.IsOpen && AgentMap.Instance()->AddonId is 0) var userRequestedMap = System.MapWindow.ProcessingCommand || _userOpenedMapFramesRemaining > 0;
if (userRequestedMap)
{
showMapHook!.Original(agent, a1, a2);
return;
}
var addonId = AgentMap.Instance()->AddonId;
var currentMapId = AgentMap.Instance()->CurrentMapId;
var selectedMapId = AgentMap.Instance()->SelectedMapId;
if (System.MapWindow.IsOpen && addonId is 0)
{ {
Service.Log.Debug("[OnShow] MapWindow can not be open now."); Service.Log.Debug("[OnShow] MapWindow can not be open now.");
System.MapWindow.Close(); System.MapWindow.Close();
@@ -272,15 +290,10 @@ public unsafe class IntegrationsController : IDisposable
return; return;
} }
if (AgentMap.Instance()->AddonId is not 0 && // CurrentMapId != SelectedMapId = viewing quest map in different zone; pass through, don't Hide()
AgentMap.Instance()->CurrentMapId != AgentMap.Instance()->SelectedMapId) if (addonId is not 0 && currentMapId != selectedMapId)
{ {
if (!System.SystemConfig.KeepOpen) showMapHook!.Original(agent, a1, a2);
{
AgentMap.Instance()->Hide();
}
Service.Log.Verbose("[OnShow] Vanilla tried to return to current map, aborted.");
return; return;
} }
@@ -293,9 +306,22 @@ public unsafe class IntegrationsController : IDisposable
showMapHook!.Original(agent, a1, a2); showMapHook!.Original(agent, a1, a2);
}, Service.Log, "Exception during OnShowHook"); }, Service.Log, "Exception during OnShowHook");
private static bool IsUserInitiatedMapOpen(MapType type) =>
type is MapType.QuestLog or MapType.GatheringLog or MapType.FlagMarker or MapType.Bozja
or MapType.MobHunt or MapType.SharedFate or MapType.Teleport or MapType.Treasure;
private void OnOpenMapHook(AgentMap* agent, OpenMapInfo* mapInfo) => private void OnOpenMapHook(AgentMap* agent, OpenMapInfo* mapInfo) =>
HookSafety.ExecuteSafe(() => HookSafety.ExecuteSafe(() =>
{ {
// MUST run before Original: cancel any in-progress silent refresh so OnFrameworkUpdate won't call Hide()
// after the game opens the map. Also set flags for OnShowHook pass-through.
if (IsUserInitiatedMapOpen(mapInfo->Type))
{
SuppressSilentRefreshForUserMapOpen();
System.MapWindow.ProcessingCommand = true;
_userOpenedMapFramesRemaining = 30; // Persists after ProcessingCommand cleared by MapWindow.OnOpen
}
openMapHook!.Original(agent, mapInfo); openMapHook!.Original(agent, mapInfo);
switch (mapInfo->Type) switch (mapInfo->Type)
+1 -1
View File
@@ -4,7 +4,7 @@
<Name>HSMappy</Name> <Name>HSMappy</Name>
<InternalName>HSMappy</InternalName> <InternalName>HSMappy</InternalName>
<Author>Knack117</Author> <Author>Knack117</Author>
<Version>1.0.0.6</Version> <Version>1.0.0.10</Version>
<Punchline>A more versatile in-game map.</Punchline> <Punchline>A more versatile in-game map.</Punchline>
<Description>Replaces the in-game map with an ImGui implementation with several additional features. Fork with minimap improvements, quest radius on minimap, and more.</Description> <Description>Replaces the in-game map with an ImGui implementation with several additional features. Fork with minimap improvements, quest radius on minimap, and more.</Description>
<RepoUrl>http://brassnet.ddns.net:33983/KnackAtNite/HSMappy</RepoUrl> <RepoUrl>http://brassnet.ddns.net:33983/KnackAtNite/HSMappy</RepoUrl>
-1
View File
@@ -48,7 +48,6 @@ public class MapWindow : Window
public override unsafe void PreOpenCheck() public override unsafe void PreOpenCheck()
{ {
// If you managed to open the window while the agent says it should be closed
if (System.MapWindow.IsOpen && AgentMap.Instance()->AddonId is 0) if (System.MapWindow.IsOpen && AgentMap.Instance()->AddonId is 0)
{ {
Service.Log.Debug("[OnShow] MapWindow can not be open now."); Service.Log.Debug("[OnShow] MapWindow can not be open now.");
+1 -1
View File
@@ -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.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.6","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.6/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.6/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.6/latest.zip","LastUpdate":"1772228578"}] [{"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.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.10","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.10/latest.zip","IsHide":false,"IsTestingExclusive":false,"DownloadLinkTesting":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.10/latest.zip","DownloadLinkUpdate":"http://brassnet.ddns.net:33983/KnackAtNite/HSMappy/releases/download/v1.0.0.10/latest.zip","LastUpdate":"1772237531"}]