diff --git a/FFXIVClientStructs/FFXIV/Client/Game/WKS/WKSManager.cs b/FFXIVClientStructs/FFXIV/Client/Game/WKS/WKSManager.cs index 97b79fbd9..fda02e598 100644 --- a/FFXIVClientStructs/FFXIV/Client/Game/WKS/WKSManager.cs +++ b/FFXIVClientStructs/FFXIV/Client/Game/WKS/WKSManager.cs @@ -13,6 +13,8 @@ public unsafe partial struct WKSManager { public static partial WKSManager* Instance(); [FieldOffset(0x18)] public ushort TerritoryId; + /// Set to 1 when WKS territory loads; cleared on unload. Checked by . + [FieldOffset(0x1A)] public bool IsLoaded; [FieldOffset(0x50)] public WKSState State; @@ -54,6 +56,12 @@ public unsafe partial struct WKSManager { [FieldOffset(0x1150)] private void* UnkStruct1150; [FieldOffset(0x1158)] public StdVector> Modules; + [MemberFunction("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B7 DA 48 8B F9 E8 ?? ?? ?? ?? 8B CB")] + public partial void Load(ushort territoryId); + + [MemberFunction("E8 ?? ?? ?? ?? 0F B6 F8 49 8B 4E")] + public partial bool IsFunctionUnlocked(byte functionRowId); + public bool IsMissionCompleted(uint missionUnitId) => State.MissionCompletionFlags.CheckBitInSpan(missionUnitId); public bool IsMissionGolded(uint missionUnitId) => State.MissionGoldFlags.CheckBitInSpan(missionUnitId); @@ -66,17 +74,52 @@ public enum MissionRank { Failed = 5, } + [StructLayout(LayoutKind.Explicit, Size = 0xC)] + public struct WKSMissionState { + [FieldOffset(0x00)] public ushort MissionUnitId; + /// Used by AgentWKSMission to set silver/gold mission flags when this is 1 or 2. + [FieldOffset(0x04)] public uint MissionFlag; + [FieldOffset(0x08)] private ushort Unk8; + [FieldOffset(0x0A)] public byte Condition; // Needs more testing, but was set to 1 when Critical Mission was abandoned. Could be a bool for showing locked out status? + } + + /// Per-job state block. WKSState contains 11 of these (one per cosmic class job). + [StructLayout(LayoutKind.Explicit, Size = 0x148)] + public struct WKSJobState { + [FieldOffset(0xB0)] public WKSMissionState ExtraBasicMission; // This held a single extra A-rank mission entry. Emitted by AgentWKSMission.GetBasicMissions. Purpose yet unclear. + [FieldOffset(0xC0)] public StdVector SequentialMissions; + [FieldOffset(0xD8)] public StdVector ProvisionalMissions; + [FieldOffset(0xF0)] public StdVector CriticalMissions; + [FieldOffset(0x108)] public uint CriticalMissionData; // All jobs with currently open critical missions hold the same value. (e.g. 1779307018). Purpose yet unclear. + } + [GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x1088)] public partial struct WKSState { - /// RowId of WKSDevGrade sheet. + [FieldOffset(0x00)] private ushort Unk00; + [FieldOffset(0x04)] private byte Unk04; + [FieldOffset(0x08)] private ushort Unk08; + + /// RowId of WKSDevGrade sheet. [FieldOffset(0x0A)] public ushort DevGrade; - /// For Hub upgrades. RowId of WKSFateControl sheet. + [FieldOffset(0x0C)] private uint Unk0C; + + /// For Hub upgrades. RowId of WKSFateControl sheet. [FieldOffset(0x10)] public ushort CurrentFateControlRowId; - /// For Hub upgrades. Id of Fate in FateManager. + /// For Hub upgrades. Id of Fate in FateManager. [FieldOffset(0x12)] public ushort CurrentFateId; + [FieldOffset(0x14)] private byte Unk14; // Seems like some state flags which are checked in IsFunctionUnlocked. Bit 0 seems like "hub is built/active" + + /// 0-based WKSPioneeringTrail row index for the currently visited planet (sheet row = this + 1). + [FieldOffset(0x15)] public byte CurrentPlanetIndex; // Full row is highest subrow where WKSPioneeringTrail[row][sub].ActivationStage <= WKSState.DevGrade + + /// 0-based WKSPioneeringTrail row index for the latest unlocked planet. (sheet row = this + 1) + [FieldOffset(0x16)] public byte LatestPlanetIndex; + + [FieldOffset(0x18), FixedSizeArray] internal FixedSizeArray11 _jobStates; + /// RowId of WKSMissionUnit sheet. [FieldOffset(0xE30)] public ushort CurrentMissionUnitRowId; diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMission.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMission.cs index 4e682cce6..5f23c7c23 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMission.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMission.cs @@ -11,7 +11,9 @@ public unsafe partial struct AgentWKSMission { [FieldOffset(0x28)] public MissionData* Data; [FieldOffset(0x30)] public uint SelectedEntry; [FieldOffset(0x34)] public byte SelectedTab; + [FieldOffset(0x35)] private bool HasSavedTab; [FieldOffset(0x38)] public Utf8String MapTitle; + [FieldOffset(0xA0)] private bool BypassItemLevelCheck; // Wild guess as no low level gatherer/crafter was available. Gets set if ReceiveVent EventKind is 3. See MissionData.StartStep [MemberFunction("40 53 48 83 EC ?? 8B DA E8 ?? ?? ?? ?? 48 85 C0 74 ?? E8 ?? ?? ?? ?? 48 83 B8 ?? ?? ?? ?? ?? 74 ?? E8 ?? ?? ?? ?? 0F B7 D3")] public partial void StartMission(ushort missionUnitId); @@ -25,6 +27,9 @@ public unsafe partial struct AgentWKSMission { [MemberFunction("E8 ?? ?? ?? ?? EB ?? 48 81 C2")] public partial bool GetProvisionalMissions(StdVector* list); + [MemberFunction("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 83 EC ?? 48 8B EA E8")] + public partial bool GetCriticalMissions(StdVector* list); + [MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 0F B6 4A ?? 85 C9")] public partial bool GetMissionLog(StdVector* list); @@ -33,6 +38,8 @@ public struct MissionData { [FieldOffset(0x01)] public byte SelectedJobIndex; [FieldOffset(0x02)] public byte SelectedTabIndex; [FieldOffset(0x03)] public byte SelectedFilterIndex; + [FieldOffset(0x04)] private byte StartStep; // This gets set if ReceiveVent EventKind is 3 and somewho involved with ControlFlags and missions average item level + [FieldOffset(0x05)] public bool IsMissionLog; [FieldOffset(0x08)] public uint SelectedMissionUnitId; [FieldOffset(0x0C)] public MissionFlags SelectedMissionFlags; @@ -46,7 +53,9 @@ public struct MissionData { [FieldOffset(0x90)] public Utf8String ItemLevelWarningText; [FieldOffset(0xF8)] public StdVector MissionList; + [FieldOffset(0x115)] private byte MissionLogTabIndex; // used instead of SelectedTabIndex when IsMissionLog is set [FieldOffset(0x118)] public byte UpdateFlags; + [FieldOffset(0x119)] private byte ControlFlags; // Bit 2 gets set when Addon closes } [StructLayout(LayoutKind.Explicit, Size = 0x20)] @@ -54,7 +63,7 @@ public struct MissionEntry { [FieldOffset(0x00)] public uint MissionUnitId; [FieldOffset(0x04)] public uint IconId; - [FieldOffset(0x14)] public MissionFlags Flags; // maybe byte? + [FieldOffset(0x14)] public MissionFlags Flags; /// /// 1,2,3,4 = D,C,B,A (LevelGroup)
/// 12 = Weather-restricted
@@ -63,6 +72,8 @@ public struct MissionEntry { /// 15 = Critical (IsSpecialQuest)
///
[FieldOffset(0x18)] public byte MissionGroup; + /// ClassJob index derived from WKSMissionUnit.ClassJobCategory. + [FieldOffset(0x19)] public byte ClassJobIndex; } [Flags] @@ -73,6 +84,8 @@ public enum MissionFlags { Silver = 1 << 2, Gold = 1 << 3, WeatherRestricted = 1 << 4, - Locked = 1 << 5 + Locked = 1 << 5, + //WeatherActive = 1 << 7, // Couldn't check enough due to large timespans between missions + //CurrentlyActive = 1 << 11, // Couldn't check enough due to large timespans between missions } } diff --git a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMissionInfomation.cs b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMissionInfomation.cs index db300c672..7e949768b 100644 --- a/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMissionInfomation.cs +++ b/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentWKSMissionInfomation.cs @@ -14,6 +14,7 @@ public unsafe partial struct AgentWKSMissionInfomation { [StructLayout(LayoutKind.Explicit, Size = 0x18)] public struct MissionInfo { [FieldOffset(0x00)] public long ServerTime; + [FieldOffset(0x08)] public uint AddonId; // AbandonAddon [FieldOffset(0x0C)] public uint CurrentMissionUnitId; [FieldOffset(0x10)] public byte State; [FieldOffset(0x14)] public byte Flags;