mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Rework events and add ZoneInit event
This commit is contained in:
parent
d0c06b6105
commit
82b4ddc5c7
4 changed files with 242 additions and 94 deletions
|
|
@ -15,7 +15,6 @@ using Dalamud.Utility;
|
|||
|
||||
using FFXIVClientStructs.FFXIV.Application.Network;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Event;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||
using FFXIVClientStructs.FFXIV.Client.Network;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||
|
|
@ -37,7 +36,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
|
||||
private readonly GameLifecycle lifecycle;
|
||||
private readonly ClientStateAddressResolver address;
|
||||
private readonly Hook<EventFramework.Delegates.SetTerritoryTypeId> setupTerritoryTypeHook;
|
||||
private readonly Hook<HandleZoneInitPacketDelegate> handleZoneInitPacketHook;
|
||||
private readonly Hook<UIModule.Delegates.HandlePacket> uiModuleHandlePacketHook;
|
||||
private readonly Hook<SetCurrentInstanceDelegate> setCurrentInstanceHook;
|
||||
|
||||
|
|
@ -48,6 +47,11 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
private readonly NetworkHandlers networkHandlers = Service<NetworkHandlers>.Get();
|
||||
|
||||
private Hook<LogoutCallbackInterface.Delegates.OnLogout> onLogoutHook;
|
||||
private bool initialized;
|
||||
private ushort territoryTypeId;
|
||||
private bool isPvP;
|
||||
private uint mapId;
|
||||
private uint instance;
|
||||
private bool lastConditionNone = true;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
|
|
@ -61,17 +65,13 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
|
||||
this.ClientLanguage = (ClientLanguage)dalamud.StartInfo.Language;
|
||||
|
||||
var setTerritoryTypeAddr = EventFramework.Addresses.SetTerritoryTypeId.Value;
|
||||
Log.Verbose($"SetupTerritoryType address {Util.DescribeAddress(setTerritoryTypeAddr)}");
|
||||
|
||||
this.setupTerritoryTypeHook = Hook<EventFramework.Delegates.SetTerritoryTypeId>.FromAddress(setTerritoryTypeAddr, this.SetupTerritoryTypeDetour);
|
||||
this.handleZoneInitPacketHook = Hook<HandleZoneInitPacketDelegate>.FromAddress(this.AddressResolver.HandleZoneInitPacket, this.HandleZoneInitPacketDetour);
|
||||
this.uiModuleHandlePacketHook = Hook<UIModule.Delegates.HandlePacket>.FromAddress((nint)UIModule.StaticVirtualTablePointer->HandlePacket, this.UIModuleHandlePacketDetour);
|
||||
this.setCurrentInstanceHook = Hook<SetCurrentInstanceDelegate>.FromAddress(this.AddressResolver.SetCurrentInstance, this.SetCurrentInstanceDetour);
|
||||
|
||||
this.framework.Update += this.OnFrameworkUpdate;
|
||||
this.networkHandlers.CfPop += this.NetworkHandlersOnCfPop;
|
||||
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
this.handleZoneInitPacketHook.Enable();
|
||||
this.uiModuleHandlePacketHook.Enable();
|
||||
this.setCurrentInstanceHook.Enable();
|
||||
|
||||
|
|
@ -80,16 +80,21 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
|
||||
private unsafe delegate void ProcessPacketPlayerSetupDelegate(nint a1, nint packet);
|
||||
|
||||
private unsafe delegate void HandleZoneInitPacketDelegate(nint a1, uint localPlayerEntityId, nint packet, byte type);
|
||||
|
||||
private unsafe delegate void SetCurrentInstanceDelegate(NetworkModuleProxy* thisPtr, short instanceId);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<ZoneInitEventArgs> ZoneInit;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<ushort>? TerritoryChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<uint>? MapChanged;
|
||||
public event Action<uint>? MapIdChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<uint>? PublicInstanceChanged;
|
||||
public event Action<uint>? InstanceChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event IClientState.ClassJobChangeDelegate? ClassJobChanged;
|
||||
|
|
@ -116,13 +121,67 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
public ClientLanguage ClientLanguage { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort TerritoryType { get; private set; }
|
||||
public ushort TerritoryType
|
||||
{
|
||||
get => this.territoryTypeId;
|
||||
private set
|
||||
{
|
||||
if (this.territoryTypeId != value)
|
||||
{
|
||||
this.territoryTypeId = value;
|
||||
|
||||
if (this.initialized)
|
||||
{
|
||||
Log.Debug("TerritoryType changed: {0}", value);
|
||||
this.TerritoryChanged?.InvokeSafely(value);
|
||||
}
|
||||
|
||||
var rowRef = LuminaUtils.CreateRef<TerritoryType>(value);
|
||||
if (rowRef.IsValid)
|
||||
{
|
||||
this.IsPvP = rowRef.Value.IsPvpZone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint MapId { get; private set; }
|
||||
public uint MapId
|
||||
{
|
||||
get => this.mapId;
|
||||
private set
|
||||
{
|
||||
if (this.mapId != value)
|
||||
{
|
||||
this.mapId = value;
|
||||
|
||||
if (this.initialized)
|
||||
{
|
||||
Log.Debug("MapId changed: {0}", value);
|
||||
this.MapIdChanged?.InvokeSafely(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint PublicInstanceId { get; private set; }
|
||||
public uint Instance
|
||||
{
|
||||
get => this.instance;
|
||||
private set
|
||||
{
|
||||
if (this.instance != value)
|
||||
{
|
||||
this.instance = value;
|
||||
|
||||
if (this.initialized)
|
||||
{
|
||||
Log.Debug("Instance changed: {0}", value);
|
||||
this.InstanceChanged?.InvokeSafely(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlayerCharacter? LocalPlayer => Service<ObjectTable>.GetNullable()?[0] as IPlayerCharacter;
|
||||
|
|
@ -141,7 +200,31 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsPvP { get; private set; }
|
||||
public bool IsPvP
|
||||
{
|
||||
get => this.isPvP;
|
||||
private set
|
||||
{
|
||||
if (this.isPvP != value)
|
||||
{
|
||||
this.isPvP = value;
|
||||
|
||||
if (this.initialized)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Log.Debug("EnterPvP");
|
||||
this.EnterPvP?.InvokeSafely();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug("LeavePvP");
|
||||
this.LeavePvP?.InvokeSafely();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsPvPExcludingDen => this.IsPvP && this.TerritoryType != 250;
|
||||
|
|
@ -180,7 +263,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
/// </summary>
|
||||
void IInternalDisposableService.DisposeService()
|
||||
{
|
||||
this.setupTerritoryTypeHook.Dispose();
|
||||
this.handleZoneInitPacketHook.Dispose();
|
||||
this.uiModuleHandlePacketHook.Dispose();
|
||||
this.onLogoutHook.Dispose();
|
||||
this.setCurrentInstanceHook.Dispose();
|
||||
|
|
@ -195,43 +278,28 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
this.onLogoutHook.Enable();
|
||||
|
||||
this.TerritoryType = (ushort)GameMain.Instance()->CurrentTerritoryTypeId;
|
||||
this.MapId = AgentMap.Instance()->CurrentMapId;
|
||||
this.Instance = UIState.Instance()->PublicInstance.InstanceId;
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
this.framework.Update += this.OnFrameworkUpdate;
|
||||
}
|
||||
|
||||
private unsafe void SetupTerritoryTypeDetour(EventFramework* eventFramework, ushort territoryType)
|
||||
private void HandleZoneInitPacketDetour(nint a1, uint localPlayerEntityId, nint packet, byte type)
|
||||
{
|
||||
this.SetTerritoryType(territoryType);
|
||||
this.setupTerritoryTypeHook.Original(eventFramework, territoryType);
|
||||
}
|
||||
this.handleZoneInitPacketHook.Original(a1, localPlayerEntityId, packet, type);
|
||||
|
||||
private unsafe void SetTerritoryType(ushort territoryType)
|
||||
{
|
||||
if (this.TerritoryType == territoryType)
|
||||
return;
|
||||
|
||||
Log.Debug("TerritoryType changed: {0}", territoryType);
|
||||
|
||||
this.TerritoryType = territoryType;
|
||||
this.TerritoryChanged?.InvokeSafely(territoryType);
|
||||
|
||||
var rowRef = LuminaUtils.CreateRef<TerritoryType>(territoryType);
|
||||
if (rowRef.IsValid)
|
||||
try
|
||||
{
|
||||
var isPvP = rowRef.Value.IsPvpZone;
|
||||
if (isPvP != this.IsPvP)
|
||||
{
|
||||
this.IsPvP = isPvP;
|
||||
|
||||
if (this.IsPvP)
|
||||
{
|
||||
Log.Debug("EnterPvP");
|
||||
this.EnterPvP?.InvokeSafely();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Debug("LeavePvP");
|
||||
this.LeavePvP?.InvokeSafely();
|
||||
}
|
||||
}
|
||||
var eventArgs = ZoneInitEventArgs.Read(packet);
|
||||
Log.Debug($"ZoneInit: {eventArgs}");
|
||||
this.ZoneInit?.InvokeSafely(eventArgs);
|
||||
this.TerritoryType = (ushort)eventArgs.TerritoryType.RowId;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Exception during ZoneInit");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,23 +354,13 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
private unsafe void SetCurrentInstanceDetour(NetworkModuleProxy* thisPtr, short instanceId)
|
||||
{
|
||||
this.setCurrentInstanceHook.Original(thisPtr, instanceId);
|
||||
|
||||
if (this.PublicInstanceId == instanceId || instanceId < 0)
|
||||
return;
|
||||
|
||||
Log.Debug("Instance changed: {0}", instanceId);
|
||||
this.PublicInstanceId = (uint)instanceId;
|
||||
this.PublicInstanceChanged?.InvokeSafely((uint)instanceId);
|
||||
this.Instance = (uint)instanceId;
|
||||
}
|
||||
|
||||
private void OnFrameworkUpdate(IFramework framework)
|
||||
private unsafe void OnFrameworkUpdate(IFramework framework)
|
||||
{
|
||||
this.UpdateLogin();
|
||||
this.UpdateMapId();
|
||||
}
|
||||
this.MapId = AgentMap.Instance()->CurrentMapId;
|
||||
|
||||
private void UpdateLogin()
|
||||
{
|
||||
var condition = Service<Conditions.Condition>.GetNullable();
|
||||
var gameGui = Service<GameGui>.GetNullable();
|
||||
var data = Service<DataManager>.GetNullable();
|
||||
|
|
@ -321,26 +379,6 @@ 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<GameGui>.GetNullable();
|
||||
|
|
@ -404,9 +442,10 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
/// </summary>
|
||||
internal ClientStatePluginScoped()
|
||||
{
|
||||
this.clientStateService.ZoneInit += this.ZoneInitForward;
|
||||
this.clientStateService.TerritoryChanged += this.TerritoryChangedForward;
|
||||
this.clientStateService.MapChanged += this.MapChangedForward;
|
||||
this.clientStateService.PublicInstanceChanged += this.PublicInstanceChangedForward;
|
||||
this.clientStateService.MapIdChanged += this.MapIdChangedForward;
|
||||
this.clientStateService.InstanceChanged += this.InstanceChangedForward;
|
||||
this.clientStateService.ClassJobChanged += this.ClassJobChangedForward;
|
||||
this.clientStateService.LevelChanged += this.LevelChangedForward;
|
||||
this.clientStateService.Login += this.LoginForward;
|
||||
|
|
@ -416,14 +455,17 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
this.clientStateService.CfPop += this.ContentFinderPopForward;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<ZoneInitEventArgs> ZoneInit;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<ushort>? TerritoryChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<uint>? MapChanged;
|
||||
public event Action<uint>? MapIdChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event Action<uint>? PublicInstanceChanged;
|
||||
public event Action<uint>? InstanceChanged;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public event IClientState.ClassJobChangeDelegate? ClassJobChanged;
|
||||
|
|
@ -456,7 +498,7 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
public uint MapId => this.clientStateService.MapId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint PublicInstanceId => this.clientStateService.PublicInstanceId;
|
||||
public uint Instance => this.clientStateService.Instance;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlayerCharacter? LocalPlayer => this.clientStateService.LocalPlayer;
|
||||
|
|
@ -485,9 +527,10 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
/// <inheritdoc/>
|
||||
void IInternalDisposableService.DisposeService()
|
||||
{
|
||||
this.clientStateService.ZoneInit -= this.ZoneInitForward;
|
||||
this.clientStateService.TerritoryChanged -= this.TerritoryChangedForward;
|
||||
this.clientStateService.MapChanged -= this.MapChangedForward;
|
||||
this.clientStateService.PublicInstanceChanged -= this.PublicInstanceChangedForward;
|
||||
this.clientStateService.MapIdChanged -= this.MapIdChangedForward;
|
||||
this.clientStateService.InstanceChanged -= this.InstanceChangedForward;
|
||||
this.clientStateService.ClassJobChanged -= this.ClassJobChangedForward;
|
||||
this.clientStateService.LevelChanged -= this.LevelChangedForward;
|
||||
this.clientStateService.Login -= this.LoginForward;
|
||||
|
|
@ -496,9 +539,10 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
this.clientStateService.LeavePvP -= this.ExitPvPForward;
|
||||
this.clientStateService.CfPop -= this.ContentFinderPopForward;
|
||||
|
||||
this.ZoneInit = null;
|
||||
this.TerritoryChanged = null;
|
||||
this.MapChanged = null;
|
||||
this.PublicInstanceChanged = null;
|
||||
this.MapIdChanged = null;
|
||||
this.InstanceChanged = null;
|
||||
this.ClassJobChanged = null;
|
||||
this.LevelChanged = null;
|
||||
this.Login = null;
|
||||
|
|
@ -508,11 +552,13 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
|||
this.CfPop = null;
|
||||
}
|
||||
|
||||
private void ZoneInitForward(ZoneInitEventArgs eventArgs) => this.ZoneInit?.Invoke(eventArgs);
|
||||
|
||||
private void TerritoryChangedForward(ushort territoryId) => this.TerritoryChanged?.Invoke(territoryId);
|
||||
|
||||
private void MapChangedForward(uint mapId) => this.MapChanged?.Invoke(mapId);
|
||||
private void MapIdChangedForward(uint mapId) => this.MapIdChanged?.Invoke(mapId);
|
||||
|
||||
private void PublicInstanceChangedForward(uint instanceId) => this.PublicInstanceChanged?.Invoke(instanceId);
|
||||
private void InstanceChangedForward(uint instanceId) => this.InstanceChanged?.Invoke(instanceId);
|
||||
|
||||
private void ClassJobChangedForward(uint classJobId) => this.ClassJobChanged?.Invoke(classJobId);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver
|
|||
|
||||
// Functions
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the method that handles the ZoneInit packet.
|
||||
/// </summary>
|
||||
public nint HandleZoneInitPacket { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the method that sets the current public instance.
|
||||
/// </summary>
|
||||
|
|
@ -30,6 +35,7 @@ internal sealed class ClientStateAddressResolver : BaseAddressResolver
|
|||
/// <param name="sig">The signature scanner to facilitate setup.</param>
|
||||
protected override void Setup64Bit(ISigScanner sig)
|
||||
{
|
||||
this.HandleZoneInitPacket = sig.ScanText("E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 44 0F B6 45");
|
||||
this.SetCurrentInstance = sig.ScanText("E8 ?? ?? ?? ?? 0F B6 55 ?? 48 8D 0D ?? ?? ?? ?? C0 EA"); // NetworkModuleProxy.SetCurrentInstance
|
||||
|
||||
// These resolve to fixed offsets only, without the base address added in, so GetStaticAddressFromSig() can't be used.
|
||||
|
|
|
|||
90
Dalamud/Game/ClientState/ZoneInit.cs
Normal file
90
Dalamud/Game/ClientState/ZoneInit.cs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Dalamud.Data;
|
||||
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
namespace Dalamud.Game.ClientState;
|
||||
|
||||
/// <summary>
|
||||
/// Provides event data for when the game should initialize a zone.
|
||||
/// </summary>
|
||||
public class ZoneInitEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the territory type of the zone being entered.
|
||||
/// </summary>
|
||||
public TerritoryType TerritoryType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance number of the zone, used when multiple copies of an area are active.
|
||||
/// </summary>
|
||||
public ushort Instance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the associated content finder condition for the zone, if any.
|
||||
/// </summary>
|
||||
public ContentFinderCondition ContentFinderCondition { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current weather in the zone upon entry.
|
||||
/// </summary>
|
||||
public Weather Weather { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the set of active festivals in the zone.
|
||||
/// </summary>
|
||||
public Festival[] ActiveFestivals { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the phases corresponding to the active festivals.
|
||||
/// </summary>
|
||||
public ushort[] ActiveFestivalPhases { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Reads raw zone initialization data from a network packet and constructs the event arguments.
|
||||
/// </summary>
|
||||
/// <param name="packet">A pointer to the raw packet data.</param>
|
||||
/// <returns>A <see cref="ZoneInitEventArgs"/> populated from the packet.</returns>
|
||||
public static unsafe ZoneInitEventArgs Read(nint packet)
|
||||
{
|
||||
var dataManager = Service<DataManager>.Get();
|
||||
var eventArgs = new ZoneInitEventArgs();
|
||||
|
||||
var flags = *(byte*)(packet + 0x12);
|
||||
|
||||
eventArgs.TerritoryType = dataManager.GetExcelSheet<TerritoryType>().GetRow(*(ushort*)(packet + 0x02));
|
||||
eventArgs.Instance = flags >= 0 ? (ushort)0 : *(ushort*)(packet + 0x04);
|
||||
eventArgs.ContentFinderCondition = dataManager.GetExcelSheet<ContentFinderCondition>().GetRow(*(ushort*)(packet + 0x06));
|
||||
eventArgs.Weather = dataManager.GetExcelSheet<Weather>().GetRow(*(byte*)(packet + 0x10));
|
||||
|
||||
const int NumFestivals = 4;
|
||||
eventArgs.ActiveFestivals = new Festival[NumFestivals];
|
||||
eventArgs.ActiveFestivalPhases = new ushort[NumFestivals];
|
||||
|
||||
// There are also 4 festival ids and phases for PlayerState at +0x3E and +0x46 respectively,
|
||||
// but it's unclear why they exist as separate entries and why they would be different.
|
||||
for (var i = 0; i < NumFestivals; i++)
|
||||
{
|
||||
eventArgs.ActiveFestivals[i] = dataManager.GetExcelSheet<Festival>().GetRow(*(ushort*)(packet + 0x2E + (i * 2)));
|
||||
eventArgs.ActiveFestivalPhases[i] = *(ushort*)(packet + 0x36 + (i * 2));
|
||||
}
|
||||
|
||||
return eventArgs;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder("ZoneInitEventArgs { ");
|
||||
sb.Append($"TerritoryTypeId = {this.TerritoryType.RowId}, ");
|
||||
sb.Append($"Instance = {this.Instance}, ");
|
||||
sb.Append($"ContentFinderCondition = {this.ContentFinderCondition.RowId}, ");
|
||||
sb.Append($"Weather = {this.Weather.RowId}, ");
|
||||
sb.Append($"ActiveFestivals = [{string.Join(", ", this.ActiveFestivals.Select(f => f.RowId))}], ");
|
||||
sb.Append($"ActiveFestivalPhases = [{string.Join(", ", this.ActiveFestivalPhases)}]");
|
||||
sb.Append(" }");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
|
||||
|
|
@ -29,6 +30,11 @@ public interface IClientState
|
|||
/// <param name="code">The success/failure code.</param>
|
||||
public delegate void LogoutDelegate(int type, int code);
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when the game initializes a zone.
|
||||
/// </summary>
|
||||
public event Action<ZoneInitEventArgs> ZoneInit;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when the current Territory changes.
|
||||
/// </summary>
|
||||
|
|
@ -37,12 +43,12 @@ public interface IClientState
|
|||
/// <summary>
|
||||
/// Event that gets fired when the current Map changes.
|
||||
/// </summary>
|
||||
public event Action<uint> MapChanged;
|
||||
public event Action<uint> MapIdChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when the current zone Instance changes.
|
||||
/// </summary>
|
||||
public event Action<uint> PublicInstanceChanged;
|
||||
public event Action<uint> InstanceChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that fires when a characters ClassJob changed.
|
||||
|
|
@ -98,7 +104,7 @@ public interface IClientState
|
|||
/// <summary>
|
||||
/// Gets the instance number of the current zone, used when multiple copies of an area are active.
|
||||
/// </summary>
|
||||
public uint PublicInstanceId { get; }
|
||||
public uint Instance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local player character, if one is present.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue