diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs index 407b54060..05b194f82 100644 --- a/Dalamud/Game/ClientState/ClientState.cs +++ b/Dalamud/Game/ClientState/ClientState.cs @@ -65,7 +65,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState this.setupTerritoryTypeHook = Hook.FromAddress(setTerritoryTypeAddr, this.SetupTerritoryTypeDetour); this.uiModuleHandlePacketHook = Hook.FromAddress((nint)UIModule.StaticVirtualTablePointer->HandlePacket, this.UIModuleHandlePacketDetour); - this.framework.Update += this.FrameworkOnOnUpdateEvent; + this.framework.Update += this.OnFrameworkUpdate; this.networkHandlers.CfPop += this.NetworkHandlersOnCfPop; this.setupTerritoryTypeHook.Enable(); @@ -79,6 +79,9 @@ internal sealed class ClientState : IInternalDisposableService, IClientState /// public event Action? TerritoryChanged; + /// + public event Action? MapChanged; + /// public event IClientState.ClassJobChangeDelegate? ClassJobChanged; @@ -107,14 +110,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState public ushort TerritoryType { get; private set; } /// - public unsafe uint MapId - { - get - { - var agentMap = AgentMap.Instance(); - return agentMap != null ? agentMap->CurrentMapId : 0; - } - } + public uint MapId { get; private set; } /// public IPlayerCharacter? LocalPlayer => Service.GetNullable()?[0] as IPlayerCharacter; @@ -176,7 +172,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState this.uiModuleHandlePacketHook.Dispose(); this.onLogoutHook.Dispose(); - this.framework.Update -= this.FrameworkOnOnUpdateEvent; + this.framework.Update -= this.OnFrameworkUpdate; this.networkHandlers.CfPop -= this.NetworkHandlersOnCfPop; } @@ -274,7 +270,13 @@ internal sealed class ClientState : IInternalDisposableService, IClientState } } - private void FrameworkOnOnUpdateEvent(IFramework framework1) + private void OnFrameworkUpdate(IFramework framework) + { + this.UpdateLogin(); + this.UpdateMapId(); + } + + private void UpdateLogin() { var condition = Service.GetNullable(); var gameGui = Service.GetNullable(); @@ -294,6 +296,26 @@ internal sealed class ClientState : IInternalDisposableService, IClientState } } + private unsafe void UpdateMapId() + { + var agentMap = AgentMap.Instance(); + + if (agentMap == null) + { + if (this.MapId != 0) + this.MapId = 0; + return; + } + + var mapId = agentMap->CurrentMapId; + if (this.MapId == mapId) + return; + + Log.Debug("Map changed: {0}", mapId); + this.MapId = mapId; + this.MapChanged?.InvokeSafely(mapId); + } + private unsafe void OnLogoutDetour(LogoutCallbackInterface* thisPtr, LogoutCallbackInterface.LogoutParams* logoutParams) { var gameGui = Service.GetNullable(); @@ -358,6 +380,7 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat internal ClientStatePluginScoped() { this.clientStateService.TerritoryChanged += this.TerritoryChangedForward; + this.clientStateService.MapChanged += this.MapChangedForward; this.clientStateService.ClassJobChanged += this.ClassJobChangedForward; this.clientStateService.LevelChanged += this.LevelChangedForward; this.clientStateService.Login += this.LoginForward; @@ -370,6 +393,9 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat /// public event Action? TerritoryChanged; + /// + public event Action? MapChanged; + /// public event IClientState.ClassJobChangeDelegate? ClassJobChanged; @@ -428,6 +454,7 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat void IInternalDisposableService.DisposeService() { this.clientStateService.TerritoryChanged -= this.TerritoryChangedForward; + this.clientStateService.MapChanged -= this.MapChangedForward; this.clientStateService.ClassJobChanged -= this.ClassJobChangedForward; this.clientStateService.LevelChanged -= this.LevelChangedForward; this.clientStateService.Login -= this.LoginForward; @@ -446,6 +473,8 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat private void TerritoryChangedForward(ushort territoryId) => this.TerritoryChanged?.Invoke(territoryId); + private void MapChangedForward(uint mapId) => this.MapChanged?.Invoke(mapId); + private void ClassJobChangedForward(uint classJobId) => this.ClassJobChanged?.Invoke(classJobId); private void LevelChangedForward(uint classJobId, uint level) => this.LevelChanged?.Invoke(classJobId, level); diff --git a/Dalamud/Plugin/Services/IClientState.cs b/Dalamud/Plugin/Services/IClientState.cs index 60d8a17e2..06ec0a6f0 100644 --- a/Dalamud/Plugin/Services/IClientState.cs +++ b/Dalamud/Plugin/Services/IClientState.cs @@ -34,6 +34,11 @@ public interface IClientState /// public event Action TerritoryChanged; + /// + /// Event that gets fired when the current Map changes. + /// + public event Action MapChanged; + /// /// Event that fires when a characters ClassJob changed. ///