Skip to content

Commit

Permalink
Merge branch 'main' into cn
Browse files Browse the repository at this point in the history
  • Loading branch information
wozaiha committed Oct 16, 2024
2 parents 1df8a18 + 77668c8 commit cafaf76
Show file tree
Hide file tree
Showing 25 changed files with 2,362 additions and 446 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public ref EquipmentModelId Equipment(EquipmentSlot slot) {
[MemberFunction("E8 ?? ?? ?? ?? 0F B6 55 C9")]
public partial void HideHeadgear(uint unk, bool hide);

[MemberFunction("44 0F B6 81 ?? ?? ?? ?? 41 0F B6 C0 41 80 E0 7F")]
public partial void HideLegacyTattoo(bool hide);

/// <summary>
/// Called when Manually Adjust Visor is toggled or /visor is used.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/Event/EventFramework.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Common.Lua;

namespace FFXIVClientStructs.FFXIV.Client.Game.Event;
Expand Down Expand Up @@ -32,10 +33,20 @@ public unsafe partial struct EventFramework {
[MemberFunction("E8 ?? ?? ?? ?? 48 85 C0 74 0B 0F B6 90")]
public partial PublicContentDirector* GetPublicContentDirector();

/// <summary>
/// When EventHandlerSelector is active, this function is used to select specific event handler to interact with.
/// </summary>
/// <param name="index">Index of the option in EventHandlerSelector singleton.</param>
[MemberFunction("E8 ?? ?? ?? ?? 44 89 A7 ?? ?? ?? ?? 44 38 A7")]
public partial void InteractWithHandlerFromSelector(int index);

[MemberFunction("E8 ?? ?? ?? ?? 48 85 C0 74 1B 66 83 78 ?? ??")]
public partial EventHandler* GetEventHandlerById(uint id);
public EventHandler* GetEventHandlerById(ushort id) => GetEventHandlerById((uint)(id | 0x10000));

[MemberFunction("40 53 57 41 56 48 83 EC 70 48 8B 02")]
public partial bool CheckInteractRange(GameObject* source, GameObject* target, byte interactionType, bool logErrorsToUser);

[MemberFunction("E8 ?? ?? ?? ?? 41 0F B7 4E ?? 3B C8")]
public static partial uint GetCurrentContentId();

Expand Down
3 changes: 3 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/Event/EventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public unsafe partial struct EventHandler {
[FieldOffset(0xC8)] public Utf8String UnkString0;
[FieldOffset(0x168)] public Utf8String UnkString1;

[VirtualFunction(154)]
public partial void CancelInteraction();

[VirtualFunction(197)]
public partial void GetTitle(Utf8String* outTitle);

Expand Down
27 changes: 27 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/Event/EventHandlerSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Component.GUI;

namespace FFXIVClientStructs.FFXIV.Client.Game.Event;

/// <summary>
/// Singleton that manages selecting one of the multiple event handlers (eg. one of the several shops provided by a single vendor).
/// </summary>
[GenerateInterop]
[Inherits<AtkModuleInterface.AtkEventInterface>]
[StructLayout(LayoutKind.Explicit, Size = 0x428)]
public unsafe partial struct EventHandlerSelector {
[StaticAddress("48 8D 0D ?? ?? ?? ?? 48 63 C2 48 C1 E0 05", 3)]
public static partial EventHandlerSelector* Instance();

[FieldOffset(0x010)] public GameObject* Target; // object corresponding to the active selection, null if selection is not active
[FieldOffset(0x018), FixedSizeArray] internal FixedSizeArray32<Option> _options;
[FieldOffset(0x418)] public int OptionsCount; // num valid elements in Options array

[StructLayout(LayoutKind.Explicit, Size = 0x20)]
public unsafe partial struct Option {
[FieldOffset(0x00)] public int GlobalIndex; // index in Options array
[FieldOffset(0x08)] public EventHandler* Handler;
[FieldOffset(0x18)] public ushort IconId;
[FieldOffset(0x1C)] public int LocalIndex; // sequence index for a single fill invocation, not sure what this is exactly
}
}
126 changes: 126 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/Event/ShopEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Common.Component.Excel;
using FFXIVClientStructs.FFXIV.Component.GUI;

namespace FFXIVClientStructs.FFXIV.Client.Game.Event;

[GenerateInterop]
[Inherits<EventHandler>]
[StructLayout(LayoutKind.Explicit, Size = 0x32F0)]
public unsafe partial struct ShopEventHandler {
// 0x210: second base class, related to context menu integration for selling items
// 0x218: third base class, related to buying items, not sure how it's used exactly

[FieldOffset(0x0220)] public Utf8String ShopName;
[FieldOffset(0x0288)] public uint ShopIcon;
[FieldOffset(0x028C)] public GameMain.Festival Festival;
[FieldOffset(0x0290)] public uint UnlockQuestId;
// 0x294: byte, col 5 in GilShop row
[FieldOffset(0x0298), FixedSizeArray] internal FixedSizeArray60<ShopItem> _items;
[FieldOffset(0x29F8)] public int ItemsCount; // num valid entries in Items array
[FieldOffset(0x29FC), FixedSizeArray] internal FixedSizeArray60<int> _visibleItems; // indices of items in Items array that are to be shown in shop
[FieldOffset(0x2AEC)] public int VisibleItemsCount; // num valid entries in VisibleItems array
[FieldOffset(0x2AF0)] public bool NeedSorting; // set after GilShopItem rows are loaded, used later when Item rows are loaded
// 0x2AF8: int, ???
[FieldOffset(0x2AFC)] public int SellPriceBuy; // the vendor buy price of the item being sold
[FieldOffset(0x2B00)] public int SellPrice; // the price vendor will pay for the item being sold (adjusted by materia etc)
[FieldOffset(0x2B04)] public int SellStackMax; // max stack size of the item being sold
[FieldOffset(0x2B08)] public bool SellIsUnique; // is item being sold unique?
[FieldOffset(0x2B09)] public bool SellIsUntradeable; // is item attempted to be sold untradeable?
[FieldOffset(0x2B0A)] public bool SellIsWithMateria; // is item being sold has attached materia?
[FieldOffset(0x2B0B)] public bool SellIsFullySpiritbound; // is item being sold has full spiritbound?
[FieldOffset(0x2B0C)] public bool SellIsCollectible; // is item being sold collectible?
[FieldOffset(0x2B10)] public Utf8String SellItemName;
[FieldOffset(0x2B78)] public int SellRarity;
[FieldOffset(0x2B80), FixedSizeArray] internal FixedSizeArray10<BuybackItem> _buyback;
[FieldOffset(0x32B0)] public int BuybackCount; // num valid entries in Buyback array
[FieldOffset(0x32B4)] public bool StartingSell; // set while waiting for Item sheet reader to complete before to continue sell transaction
[FieldOffset(0x32B5)] public bool StartingBuy; // set while waiting for Item sheet reader to complete before to continue buy transaction
[FieldOffset(0x32B6)] public bool UpdatingBuybackItems; // set while waiting for Item sheet reader to update buyback item details
[FieldOffset(0x32B7)] public bool BuybackTabActive;
[FieldOffset(0x32B8)] public bool WaitingForSellConfirm;
[FieldOffset(0x32B9)] public bool WaitingForTransactionToFinish;
[FieldOffset(0x32BA)] public bool IsTradingWithRetainer; // if set, eg. will warn about transaction exceeding gil cap
[FieldOffset(0x32BC)] public int CurrentMode; // 0 = none, 1 = normal, 2 = buyback
[FieldOffset(0x32C0)] public int TransactionType; // 0 = n/a, 1 = buying, 2 = selling
[FieldOffset(0x32C4)] public int BuyItemIndex; // index in Items or Buyback array, depending on mode
[FieldOffset(0x32C8)] public uint TransactionItemId; // in Item row; set during all types of transactions
[FieldOffset(0x32CC)] public int SellInventorySlot;
[FieldOffset(0x32D0)] public int TransactionItemCount; // num items being bought/sold
[FieldOffset(0x32D4)] public InventoryType SellInventoryType;
// 0x32D8: int, ??? - related to sound effects being played, etcs
[FieldOffset(0x32E0)] public void* SheetReader;
[FieldOffset(0x32E8)] public ExcelSheet* CurrentSheet;

[StructLayout(LayoutKind.Explicit, Size = 0xA8)]
public unsafe partial struct ShopItem {
[FieldOffset(0x00)] public uint ItemId;
[FieldOffset(0x04)] public int PriceBuy;
[FieldOffset(0x08)] public int PriceSell;
[FieldOffset(0x0C)] public int NumOwned;
[FieldOffset(0x10)] public int StackSize;
[FieldOffset(0x14)] public bool IsUnique;
[FieldOffset(0x18)] public uint CategoryIcon;
// 0x1C: byte, col 2 in GilShopItem row
// 0x1D: byte, col 3 in GilShopItem row
[FieldOffset(0x20)] public Utf8String ItemName;
[FieldOffset(0x88)] public bool IsHQ;
[FieldOffset(0x8C)] public uint QuestRequired1;
[FieldOffset(0x90)] public uint QuestRequired2;
// 0x94: byte, col 7 in GilShopItem row, something to do with showing items that aren't yet unlocked
[FieldOffset(0x98)] public uint SubRowId; // in GilShopItem sheet, corresponding to this item; note that items could be sorted after loading
[FieldOffset(0x9C)] public byte CategoryOrderMajor;
[FieldOffset(0x9D)] public byte CategoryOrderMinor;
// 0xA0: int, col 19 in Item row
[FieldOffset(0xA4)] public ushort StateRequired; // column in GilShopItem row
[FieldOffset(0xA6)] public ushort PatchAdded;
}

[GenerateInterop]
[StructLayout(LayoutKind.Explicit, Size = 0xB8)]
public unsafe partial struct BuybackItem {
[FieldOffset(0x00)] public uint ItemId;
[FieldOffset(0x04)] public int Quantity;
[FieldOffset(0x08)] public int Price;
[FieldOffset(0x0C)] public int NumOwned;
[FieldOffset(0x10)] public InventoryItem.ItemFlags Flags;
[FieldOffset(0x18)] public Utf8String ItemName;
// 0x80: byte, ???
[FieldOffset(0x84)] public uint CategoryIcon;
[FieldOffset(0x88)] public uint ShopId;
[FieldOffset(0x90)] public ulong CrafterContentId;
[FieldOffset(0x98), FixedSizeArray] internal FixedSizeArray5<ushort> _materia;
[FieldOffset(0xA2), FixedSizeArray] internal FixedSizeArray5<byte> _materiaGrades;
[FieldOffset(0xA8)] public ushort Condition;
[FieldOffset(0xAA)] public ushort Spiritbond;
[FieldOffset(0xAC), FixedSizeArray] internal FixedSizeArray2<byte> _stains;
[FieldOffset(0xB0)] public uint GlamourId;
[FieldOffset(0xB4)] public bool IsUnique;
}

// there's a global singleton of this type, it's referenced by AgentShop.EventReceiver when shop is activated
[GenerateInterop]
[Inherits<AtkModuleInterface.AtkEventInterface>]
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
public unsafe partial struct AgentProxy {
[FieldOffset(0x10)] public ShopEventHandler* Handler;
[FieldOffset(0x18)] public uint AddonId;
}

// there's a global singleton of this type, it's referenced by confirmation addons
[GenerateInterop]
[Inherits<AtkModuleInterface.AtkEventInterface>]
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
public unsafe partial struct YesNoProxy {
[FieldOffset(0x10)] public ShopEventHandler* Handler;
[FieldOffset(0x18)] public uint AddonId;
}

/// <summary>
/// Buy a bunch of items from the vendor.
/// Note: BuyItemIndex field must be set before calling this function!
/// </summary>
/// <param name="count">Number of items to buy.</param>
[MemberFunction("48 83 EC 38 80 B9 ?? ?? ?? ?? ?? C7 44 24")]
public partial void ExecuteBuy(int count);
}
1 change: 1 addition & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/GameMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public unsafe partial struct GameMain {
public static partial bool IsInPvPInstance();

[MemberFunction("E8 ?? ?? ?? ?? 84 C0 75 21 48 8B 4F 10")]
[Obsolete("Use TerritoryInfo.Instance()->InSanctuary instead. See https://github.com/aers/FFXIVClientStructs/pull/1123 for more information.")]
public static partial bool IsInSanctuary();

[MemberFunction("E8 ?? ?? ?? ?? 41 83 7F ?? ?? 4C 8D 2D")]
Expand Down
22 changes: 22 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/Object/GameObject.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.Game.Event;
using FFXIVClientStructs.FFXIV.Client.Graphics;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
using FFXIVClientStructs.FFXIV.Client.LayoutEngine.Group;
Expand Down Expand Up @@ -78,9 +79,17 @@ public unsafe partial struct GameObject {
[VirtualFunction(26)]
public partial void Highlight(ObjectHighlightColor color);

/// <param name="outHandlers">Should point to array that can fit up to 32 pointers.</param>
/// <returns>Num elements filled.</returns>
[VirtualFunction(30)]
public partial int GetEventHandlersImpl(EventHandler** outHandlers);

[VirtualFunction(34)]
public partial void SetReadyToDraw();

[VirtualFunction(46)]
public partial void GetCenterPosition(Vector3* outCenter);

[VirtualFunction(47)]
public partial uint GetNameId();

Expand All @@ -99,6 +108,16 @@ public unsafe partial struct GameObject {
[VirtualFunction(61)]
public partial bool IsCharacter();

/// <summary>
/// Determines whether a ray intersects with the game object, either by checking the model's geometry or the object's approximate center position.
/// </summary>
/// <param name="ray">The ray to test for intersection, containing both origin and direction.</param>
/// <param name="outHitPosition">The output position where the intersection occurs, if any.</param>
/// <param name="outModelChecked">A boolean output that indicates whether the intersection was checked against the model (<c>true</c>) or approximated via the object's center (<c>false</c>).</param>
/// <returns><c>true</c> if the ray intersects with the game object; otherwise, <c>false</c>.</returns>
[VirtualFunction(69)]
public partial bool IntersectsRay(Ray* ray, Vector3* outHitPosition, bool* outModelChecked);

[MemberFunction("E8 ?? ?? ?? ?? 0F 28 74 24 ?? 80 3D")]
public partial void SetDrawOffset(float x, float y, float z);

Expand All @@ -110,6 +129,9 @@ public unsafe partial struct GameObject {

[MemberFunction("E8 ?? ?? ?? ?? 84 C0 74 ?? 48 8B 17 45 33 C9")]
public partial bool IsReadyToDraw();

[MemberFunction("E8 ?? ?? ?? ?? 0F 5A C7")]
public partial Vector3* GetPosition();
}

// if (EntityId == 0xE0000000)
Expand Down
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/CharaCard.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::CharaCard
[StructLayout(LayoutKind.Explicit, Size = 0x1C8)]
[StructLayout(LayoutKind.Explicit, Size = 0x1E8)]
public struct CharaCard;
// contains temporary data when sending banner updates to the server
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/FishRecord.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::FishRecord
[StructLayout(LayoutKind.Explicit, Size = 0x2E0)]
[StructLayout(LayoutKind.Explicit, Size = 0x338)]
public struct FishRecord;
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/FishingNote.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::FishingNote
[StructLayout(LayoutKind.Explicit, Size = 0x50)]
[StructLayout(LayoutKind.Explicit, Size = 0xE0)]
public struct FishingNote;
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/GatheringNote.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::GatheringNote
[StructLayout(LayoutKind.Explicit, Size = 0x628)]
[StructLayout(LayoutKind.Explicit, Size = 0x6A0)]
public struct GatheringNote;
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/Journal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::Journal
// Client::Game::UI::ScenarioTextReader
[StructLayout(LayoutKind.Explicit, Size = 0x4748)]
[StructLayout(LayoutKind.Explicit, Size = 0x4768)]
public struct Journal;
23 changes: 17 additions & 6 deletions FFXIVClientStructs/FFXIV/Client/Game/UI/Loot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,36 @@ public unsafe partial struct Loot {
}

[StructLayout(LayoutKind.Explicit, Size = 0x40)]
public unsafe struct LootItem {
public struct LootItem {
[FieldOffset(0x00)] public uint ChestObjectId;
[FieldOffset(0x04)] public uint ChestItemIndex; // This loot item's index in the chest it came from
[FieldOffset(0x08)] public uint ItemId;
[FieldOffset(0x0C)] public ushort ItemCount;
[FieldOffset(0x0E), FixedSizeArray] internal FixedSizeArray2<LootItemMateria> _materia;
[FieldOffset(0x18), FixedSizeArray] internal FixedSizeArray2<byte> _glamourStainIds;

[FieldOffset(0x1C)] public uint GlamourItemId;
[FieldOffset(0x20)] public RollState RollState;
[FieldOffset(0x24)] public RollResult RollResult;
[FieldOffset(0x28)] public uint RollValue;
[FieldOffset(0x2C)] public float Time;
[FieldOffset(0x30)] public float MaxTime;

[FieldOffset(0x38)] public LootMode LootMode;
}

public enum RollState {
UpToNeed = 0, //Can roll up to Need
UpToGreed = 1,//Can roll up to Gree
UpToPass = 2, //Can only pass
[StructLayout(LayoutKind.Explicit, Size = 2)]
public struct LootItemMateria {
[FieldOffset(0x00)] public byte MateriaId;
[FieldOffset(0x01)] public byte MateriaGrade;
}

public enum RollState { // TODO: underlying type should be byte
UpToNeed = 0, // Can roll up to Need
UpToGreed = 1,// Can roll up to Gree
UpToPass = 2, // Can only pass
Rolled = 17,
Unavailable = 21, //Lootmaster undecided?
Unavailable = 21, // Lootmaster undecided?
Unknown = 28, // Default value
}

Expand Down
33 changes: 32 additions & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/NpcTrade.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
using FFXIVClientStructs.FFXIV.Client.System.String;

namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::NpcTrade
[GenerateInterop]
[StructLayout(LayoutKind.Explicit, Size = 0x328)]
public struct NpcTrade;
public partial struct NpcTrade {
[FieldOffset(0x008)] public ItemRequests Requests;

[GenerateInterop]
[StructLayout(LayoutKind.Explicit, Size = 0x90)]
public partial struct Item {
[FieldOffset(0x00)] public uint ItemId;
[FieldOffset(0x04)] public int RequiredQuantity;
[FieldOffset(0x08)] public uint IconId;
[FieldOffset(0x10)] public Utf8String ItemName;
[FieldOffset(0x78)] public bool WantHQ;
[FieldOffset(0x7A), FixedSizeArray] internal FixedSizeArray5<ushort> _wantMateriaIds;
[FieldOffset(0x84), FixedSizeArray] internal FixedSizeArray5<byte> _wantMateriaGrades;
[FieldOffset(0x89)] public byte WantMateriaFilledSlots;
[FieldOffset(0x8A)] public ushort MinCollectibility;
[FieldOffset(0x8C)] public bool WantCollectible;
[FieldOffset(0x8D)] public bool Stackable;
}

[GenerateInterop]
[StructLayout(LayoutKind.Explicit, Size = 0x2D8)]
public partial struct ItemRequests {
[FieldOffset(0)] public byte Count;
[FieldOffset(8), FixedSizeArray] internal FixedSizeArray5<Item> _items;
}

[VirtualFunction(0)]
public partial void Dtor(byte freeFlags);
}
2 changes: 1 addition & 1 deletion FFXIVClientStructs/FFXIV/Client/Game/UI/QuestUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ namespace FFXIVClientStructs.FFXIV.Client.Game.UI;

// Client::Game::UI::QuestUI
// Client::Game::UI::ScenarioTextReader
[StructLayout(LayoutKind.Explicit, Size = 0xFD0)]
[StructLayout(LayoutKind.Explicit, Size = 0xFF0)]
public struct QuestUI;
3 changes: 3 additions & 0 deletions FFXIVClientStructs/FFXIV/Client/Game/UI/TerritoryInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public unsafe partial struct TerritoryInfo {
[StaticAddress("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? F3 0F 5C 05", 3)]
public static partial TerritoryInfo* Instance();

/// <summary>For example, used for housing subdivisions.</summary>
[FieldOffset(0x14)] public uint MapIdOverride;
[FieldOffset(0x18)] public uint ChatLinkMapIdOverride;
[FieldOffset(0x1C)] public bool InSanctuary;

[FieldOffset(0x24)] public uint AreaPlaceNameId;
Expand Down
Loading

0 comments on commit cafaf76

Please sign in to comment.