diff --git a/.jules/scribe.md b/.jules/scribe.md index 5c64f07..f0fe9e0 100644 --- a/.jules/scribe.md +++ b/.jules/scribe.md @@ -9,3 +9,5 @@ ## 2026-07-15 - [ProductPatterns] Learning: Multi-region memory support is implemented via a central registry that maps regional identifiers (Global, China, Korea) to product-specific pattern dictionaries. Action: When documenting pattern-related types, clarify that these strings are raw signatures used by the assembly loader to resolve memory offsets across different game versions. ## 2026-06-24 - [RemoteAgents] Learning: "Dawn" is the internal game name for the Duty Support and Trust systems. Action: When documenting "Dawn" related agents or offsets, explicitly reference both Duty Support and Trust to ensure clarity for developers familiar with the in-game terminology. ## 2026-06-25 - [AetherialWheel] Learning: FC Aetherial Wheel data includes multiple item IDs (Starting, Current, Resulting) to track the transformation of a wheel as it primes. Action: When documenting aetherial wheel structures, distinguish between the unprimed source item and the final primed result to clarify the priming lifecycle. +## 2026-08-01 - [Build Integrity] Learning: Using `` for generic methods defined in external libraries (e.g., `ff14bot`) can cause CS1574 (unresolved cref) warnings if the generic signature is not correctly resolved. Action: Avoid `cref` for external generic wrappers and instead use plain text to describe function calls to ensure build stability. +## 2026-08-02 - [Scribe Constraints] Learning: Identifying functional bugs (like missing vendor registry entries) during documentation exploration is common, but fixing them violates the "Never modify functional logic" boundary. Action: Document the existing state accurately and record the bug in memory or a separate task, but do not include functional fixes in a Scribe PR. diff --git a/RemoteAgents/AgentBankaCraftworksSupply.cs b/RemoteAgents/AgentBankaCraftworksSupply.cs index 7d22a3b..d14aa8c 100644 --- a/RemoteAgents/AgentBankaCraftworksSupply.cs +++ b/RemoteAgents/AgentBankaCraftworksSupply.cs @@ -1,4 +1,4 @@ -using System; +using System; using ff14bot; using ff14bot.Managers; using LlamaLibrary.Memory; @@ -6,26 +6,39 @@ namespace LlamaLibrary.RemoteAgents; - +/// +/// Remote agent for the Banka Craftworks supply interface. +/// Handles the exchange of crafted items for rewards within the Banka Craftworks system. +/// public class AgentBankaCraftworksSupply : AgentInterface, IAgent { - - + /// + /// Initializes a new instance of the class. + /// + /// The memory address of the agent. protected AgentBankaCraftworksSupply(IntPtr pointer) : base(pointer) { } + /// public IntPtr RegisteredVtable => AgentBankaCraftworksSupplyOffsets.Vtable; + /// + /// Gets the primary memory pointer for the agent instance. + /// public IntPtr InstancePointer { get { - var temp1 = Core.Memory.Read(Pointer ) ; + var temp1 = Core.Memory.Read(Pointer); return temp1; } } + /// + /// Gets the memory pointer for the agent instance adjusted by its internal offset. + /// Used as the target for hand-in function calls. + /// public IntPtr InstancePointerWithOffset { get @@ -35,6 +48,13 @@ public IntPtr InstancePointerWithOffset } } + /// + /// Hands in the specified to the Banka Craftworks interface. + /// + /// The inventory slot containing the item to be handed in. + /// + /// This method calls an internal game function using the offset-adjusted instance pointer and the target slot's index and bag ID. + /// public void HandIn(BagSlot slot) { //var instance = Core.Memory.Read(Pointer) + Offsets.PointerOffset; diff --git a/RemoteAgents/AgentDeepDungeonStatus.cs b/RemoteAgents/AgentDeepDungeonStatus.cs index f40c1b9..5d0d2a2 100644 --- a/RemoteAgents/AgentDeepDungeonStatus.cs +++ b/RemoteAgents/AgentDeepDungeonStatus.cs @@ -1,21 +1,35 @@ -using System; +using System; using ff14bot.Managers; using LlamaLibrary.Memory; namespace LlamaLibrary.RemoteAgents; -public class AgentDeepDungeonStatus: AgentInterface +/// +/// Remote agent for the Deep Dungeon status and progress interface. +/// Manages information about current Deep Dungeon floor, score, and state. +/// +public class AgentDeepDungeonStatus : AgentInterface { + /// public IntPtr RegisteredVtable => AgentDeepDungeonStatusOffsets.VTable; private static AgentInterface? _instance; + /// + /// Gets the raw agent ID for the Deep Dungeon status agent by looking up its VTable. + /// public static int IdRaw { get; } = AgentModule.FindAgentIdByVtable(AgentDeepDungeonStatusOffsets.VTable); + /// + /// Gets the singleton instance of the by resolving its pointer from the . + /// public static AgentInterface Instance => _instance ??= new AgentDeepDungeonStatus(AgentModule.AgentPointers[AgentModule.FindAgentIdByVtable(AgentDeepDungeonStatusOffsets.VTable)]); + /// + /// Initializes a new instance of the class. + /// + /// The memory address of the agent. protected AgentDeepDungeonStatus(IntPtr pointer) : base(pointer) { } - -} \ No newline at end of file +} diff --git a/RemoteAgents/AgentFishGuide2.cs b/RemoteAgents/AgentFishGuide2.cs index 96371ca..0fa009c 100644 --- a/RemoteAgents/AgentFishGuide2.cs +++ b/RemoteAgents/AgentFishGuide2.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Runtime.InteropServices; using System.Threading.Tasks; using Buddy.Coroutines; @@ -10,38 +10,82 @@ namespace LlamaLibrary.RemoteAgents { + /// + /// Remote agent for the Fishing Guide (Fishing Log) interface. + /// Provides access to the player's catch history and facilitates interaction with the fishing log UI. + /// public class AgentFishGuide2 : AgentInterface, IAgent { + /// public IntPtr RegisteredVtable => AgentFishGuide2Offsets.Vtable; + /// + /// The total number of tabs (categories) available in the fishing guide. + /// public const int TabCount = 37; - - + /// + /// Initializes a new instance of the class. + /// + /// The memory address of the agent. protected AgentFishGuide2(IntPtr pointer) : base(pointer) { } + /// + /// Gets the pointer to the internal information structure for the fishing guide. + /// public IntPtr InfoPointer => Core.Memory.Read(Pointer + AgentFishGuide2Offsets.InfoOffset); + /// + /// Gets the pointer to the start of the fish list array in memory. + /// public IntPtr StartingPointer => Core.Memory.Read(InfoPointer + AgentFishGuide2Offsets.StartingPointer); + /// + /// Gets the pointer to the end of the fish list array in memory. + /// public IntPtr EndingPointer => Core.Memory.Read(InfoPointer + AgentFishGuide2Offsets.EndingPointer); + /// + /// Retrieves the memory pointer for a specific fish entry in the list. + /// + /// The zero-based index of the fish entry. + /// The memory pointer to the fish entry. public IntPtr FishListPointer(int start = 0) => Core.Memory.Read(StartingPointer + (8 * start)); + /// + /// Gets the total number of fish slots available in the current log context. + /// public int SlotCount => (int)((EndingPointer.ToInt64() - StartingPointer.ToInt64()) / 8); + /// + /// Reads all fish entries from the current fishing log context. + /// + /// An array of structures. public FishGuide2Item[] GetFishListRaw() { return Core.Memory.ReadArray(Core.Memory.Read(StartingPointer), SlotCount); //.Select(x => x.FishItem) as List; } + /// + /// Reads a specific range of fish entries from the fishing log. + /// + /// The zero-based starting index. + /// The number of entries to read. + /// An array of structures. public FishGuide2Item[] GetFishListRaw(int start, int count) { return Core.Memory.ReadArray(FishListPointer(start), count); //.Select(x => x.FishItem) as List; } + /// + /// Asynchronously opens the fishing log UI, refreshes its state, and retrieves the specified fish entries. + /// Closes the window when finished. + /// + /// The zero-based starting index to retrieve. + /// The number of entries to retrieve. If 0, retrieves all available entries. + /// A task representing the asynchronous operation, containing the array of fish entries. public async Task GetFishList(int start = 0, int count = 0) { if (!FishGuide2.Instance.IsOpen) @@ -71,38 +115,57 @@ public async Task GetFishList(int start = 0, int count = 0) } } + /// + /// Represents a single fish entry within the Fishing Guide memory structure. + /// [StructLayout(LayoutKind.Explicit, Size = 0x14)] public struct FishGuide2Item { - //0 + /// + /// Gets the item ID of the fish. + /// [FieldOffset(0x0)] public uint FishItem; - //0x4 + /// + /// Gets the zero-based index of the fish within the log. + /// [FieldOffset(0X4)] public ushort Index; - //0x6 + /// + /// An unknown value at offset 0x6. + /// [FieldOffset(0x6)] public ushort Unknown; - //0x8 + /// + /// An unknown value at offset 0x8. + /// [FieldOffset(0x8)] public ushort Unknown2; - //0xA + /// + /// An unknown value at offset 0xA. + /// [FieldOffset(0xA)] public ushort Unknown5; - //0xE + /// + /// The raw status byte indicating if the fish has been caught. + /// [FieldOffset(0xE)] public byte bHasCaught; + /// + /// Gets a value indicating whether the fish has been caught by the player. + /// public bool HasCaught => bHasCaught == 1; + /// public override string ToString() { return $"{DataManager.GetItem(FishItem)} : {HasCaught}"; } } -} \ No newline at end of file +} diff --git a/Utilities/GilShopping.cs b/Utilities/GilShopping.cs index f16fe66..2b934ab 100644 --- a/Utilities/GilShopping.cs +++ b/Utilities/GilShopping.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Media; @@ -26,6 +26,7 @@ public class GilShopping /// /// Maps material item IDs to the NPC ID of the vendor that sells them. + /// Includes items for Anden, Margrat, Nitowikwe, and Tiisol Ja. /// public static Dictionary ItemVendors = new() { @@ -148,4 +149,4 @@ public static async Task PurchaseIngredients(uint itemId, uint amount) return ConditionParser.HasAtLeast(itemId, (int)amount); } -} \ No newline at end of file +}