diff --git a/PlayerTags/GameInterface/ContextMenus/ContextMenu.cs b/PlayerTags/GameInterface/ContextMenus/ContextMenu.cs index e182f3c..0240136 100644 --- a/PlayerTags/GameInterface/ContextMenus/ContextMenu.cs +++ b/PlayerTags/GameInterface/ContextMenus/ContextMenu.cs @@ -319,7 +319,7 @@ namespace PlayerTags.GameInterface.ContextMenus ContextMenuOpenedDelegate contextMenuOpenedDelegate = ContextMenuOpened; if (m_CurrentSelectedItem is OpenSubContextMenuItem openSubContextMenuItem) { - contextMenuOpenedDelegate = openSubContextMenuItem.OpenedAction; + contextMenuOpenedDelegate = openSubContextMenuItem.Opened; } // Read the context menu items from the game, then allow subscribers to modify them @@ -442,7 +442,7 @@ namespace PlayerTags.GameInterface.ContextMenus objectName = GameInterfaceHelper.ReadSeString((IntPtr)agentContext->ObjectName.StringPtr); } - gameObjectContext = new GameObjectContext(agentContext->ObjectId, agentContext->ObjectContentIdLower, objectName, agentContext->ObjectWorldId); + gameObjectContext = new GameObjectContext(agentContext->GameObjectId, agentContext->GameObjectContentIdLower, objectName, agentContext->GameObjectWorldId); } var contextMenuOpenedArgs = new ContextMenuOpenedArgs(addon, agent, parentAddonName, initialContextMenuItems) diff --git a/PlayerTags/GameInterface/ContextMenus/ContextMenuItem.cs b/PlayerTags/GameInterface/ContextMenus/ContextMenuItem.cs index 9e66199..7258889 100644 --- a/PlayerTags/GameInterface/ContextMenus/ContextMenuItem.cs +++ b/PlayerTags/GameInterface/ContextMenus/ContextMenuItem.cs @@ -3,18 +3,35 @@ using System; namespace PlayerTags.GameInterface.ContextMenus { + /// + /// An item in a context menu. + /// public abstract class ContextMenuItem { + /// + /// The name of the item. + /// public SeString Name { get; set; } + /// + /// Whether the item is enabled. When enabled, an item is selectable. + /// public bool IsEnabled { get; set; } = true; - public bool HasPreviousArrow { get; set; } = false; - - public bool HasNextArrow { get; set; } = false; + /// + /// The indicator of the item. + /// + public ContextMenuItemIndicator Indicator { get; set; } = ContextMenuItemIndicator.None; + /// + /// The agent of the item. + /// internal IntPtr Agent { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The name of the item. public ContextMenuItem(SeString name) { Name = name; diff --git a/PlayerTags/GameInterface/ContextMenus/ContextMenuItemIndicator.cs b/PlayerTags/GameInterface/ContextMenus/ContextMenuItemIndicator.cs new file mode 100644 index 0000000..4fac0bf --- /dev/null +++ b/PlayerTags/GameInterface/ContextMenus/ContextMenuItemIndicator.cs @@ -0,0 +1,21 @@ +namespace PlayerTags.GameInterface.ContextMenus +{ + /// + /// An indicator displayed on a context menu item. + /// + public enum ContextMenuItemIndicator + { + /// + /// The item has no indicator. + /// + None, + /// + /// The item has a previous indicator. + /// + Previous, + /// + /// The item has a next indicator. + /// + Next + } +} diff --git a/PlayerTags/GameInterface/ContextMenus/ContextMenuReaderWriter.cs b/PlayerTags/GameInterface/ContextMenus/ContextMenuReaderWriter.cs index eae16bc..2ac32a5 100644 --- a/PlayerTags/GameInterface/ContextMenus/ContextMenuReaderWriter.cs +++ b/PlayerTags/GameInterface/ContextMenus/ContextMenuReaderWriter.cs @@ -65,7 +65,7 @@ namespace PlayerTags.GameInterface.ContextMenus } } - public int HasPreviousArrowFlagsIndex + public int HasPreviousIndicatorFlagsIndex { get { @@ -78,7 +78,7 @@ namespace PlayerTags.GameInterface.ContextMenus } } - public int HasNextArrowFlagsIndex + public int HasNextIndicatorFlagsIndex { get { @@ -254,25 +254,34 @@ namespace PlayerTags.GameInterface.ContextMenus } byte action = *(actions + contextMenuItemAtkValueBaseIndex); - // Get the has previous arrow flag - var hasPreviousArrowFlagsAtkValue = &m_AtkValues[HasPreviousArrowFlagsIndex]; - var hasPreviousArrow = HasFlag(hasPreviousArrowFlagsAtkValue->UInt, contextMenuItemIndex); + // Get the has previous indicator flag + var hasPreviousIndicatorFlagsAtkValue = &m_AtkValues[HasPreviousIndicatorFlagsIndex]; + var hasPreviousIndicator = HasFlag(hasPreviousIndicatorFlagsAtkValue->UInt, contextMenuItemIndex); - // Get the has next arrow flag - var hasNextArrowFlagsAtkValue = &m_AtkValues[HasNextArrowFlagsIndex]; - var hasNextArrow = HasFlag(hasNextArrowFlagsAtkValue->UInt, contextMenuItemIndex); + // Get the has next indicator flag + var hasNextIndicatorlagsAtkValue = &m_AtkValues[HasNextIndicatorFlagsIndex]; + var hasNextIndicator = HasFlag(hasNextIndicatorlagsAtkValue->UInt, contextMenuItemIndex); + + ContextMenuItemIndicator indicator = ContextMenuItemIndicator.None; + if (hasPreviousIndicator) + { + indicator = ContextMenuItemIndicator.Previous; + } + else if (hasNextIndicator) + { + indicator = ContextMenuItemIndicator.Next; + } var gameContextMenuItem = new GameContextMenuItem(name, action) { Agent = m_Agent, IsEnabled = isEnabled, - HasPreviousArrow = hasPreviousArrow, - HasNextArrow = hasNextArrow + Indicator = indicator }; gameContextMenuItems.Add(gameContextMenuItem); - PluginLog.Debug($"Read Name={gameContextMenuItem.Name} Action={gameContextMenuItem.Action} IsEnabled={gameContextMenuItem.IsEnabled} HasPreviousArrow={gameContextMenuItem.HasPreviousArrow} HasNextArrow={gameContextMenuItem.HasNextArrow}"); + PluginLog.Debug($"Read Name={gameContextMenuItem.Name} Action={gameContextMenuItem.ItemSelectedAction} IsEnabled={gameContextMenuItem.IsEnabled} Indicator={gameContextMenuItem.Indicator}"); } return gameContextMenuItems.ToArray(); @@ -327,12 +336,12 @@ namespace PlayerTags.GameInterface.ContextMenus contextMenuItemCountAtkValue->UInt = (uint)contextMenuOpenedArgs.ContextMenuItems.Count(); // Clear the previous arrow flags - var hasPreviousArrowAtkValue = &m_AtkValues[HasPreviousArrowFlagsIndex]; - hasPreviousArrowAtkValue->UInt = 0; + var hasPreviousIndicatorAtkValue = &m_AtkValues[HasPreviousIndicatorFlagsIndex]; + hasPreviousIndicatorAtkValue->UInt = 0; // Clear the next arrow flags - var subContextMenusFlagsAtkValue = &m_AtkValues[HasNextArrowFlagsIndex]; - subContextMenusFlagsAtkValue->UInt = 0; + var hasNextIndiactorFlagsAtkValue = &m_AtkValues[HasNextIndicatorFlagsIndex]; + hasNextIndiactorFlagsAtkValue->UInt = 0; for (int contextMenuItemIndex = 0; contextMenuItemIndex < contextMenuOpenedArgs.ContextMenuItems.Count(); ++contextMenuItemIndex) { @@ -357,7 +366,7 @@ namespace PlayerTags.GameInterface.ContextMenus byte action = 0; if (contextMenuItem is GameContextMenuItem gameContextMenuItem) { - action = gameContextMenuItem.Action; + action = gameContextMenuItem.ItemSelectedAction; } else if (contextMenuItem is CustomContextMenuItem customContextMenuItem) { @@ -393,10 +402,16 @@ namespace PlayerTags.GameInterface.ContextMenus } *(actions + FirstContextMenuItemIndex + contextMenuItemIndex) = action; - SetFlag(ref hasPreviousArrowAtkValue->UInt, contextMenuItemIndex, contextMenuItem.HasPreviousArrow); - SetFlag(ref subContextMenusFlagsAtkValue->UInt, contextMenuItemIndex, contextMenuItem.HasNextArrow); + if (contextMenuItem.Indicator == ContextMenuItemIndicator.Previous) + { + SetFlag(ref hasPreviousIndicatorAtkValue->UInt, contextMenuItemIndex, true); + } + else if (contextMenuItem.Indicator == ContextMenuItemIndicator.Next) + { + SetFlag(ref hasNextIndiactorFlagsAtkValue->UInt, contextMenuItemIndex, true); + } - PluginLog.Debug($"Write Name={contextMenuItem.Name} Action={action} IsEnabled={contextMenuItem.IsEnabled} HasPreviousArrow={contextMenuItem.HasPreviousArrow} HasNextArrow={contextMenuItem.HasNextArrow}"); + PluginLog.Debug($"Write Name={contextMenuItem.Name} Action={action} IsEnabled={contextMenuItem.IsEnabled} Indicator={contextMenuItem.Indicator}"); } Print(); diff --git a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItem.cs b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItem.cs index 8d6e404..b87ec47 100644 --- a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItem.cs +++ b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItem.cs @@ -2,10 +2,21 @@ namespace PlayerTags.GameInterface.ContextMenus { + /// + /// An item in a context menu with a user defined action. + /// public class CustomContextMenuItem : ContextMenuItem { + /// + /// The action that will be called when the item is selected. + /// public CustomContextMenuItemSelectedDelegate ItemSelected { get; } + /// + /// Initializes a new instance of the class. + /// + /// The name of the item. + /// The action that will be called when the item is selected. internal CustomContextMenuItem(SeString name, CustomContextMenuItemSelectedDelegate itemSelected) : base(name) { diff --git a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedArgs.cs b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedArgs.cs index 5cca9d4..75ba640 100644 --- a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedArgs.cs +++ b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedArgs.cs @@ -1,7 +1,7 @@ namespace PlayerTags.GameInterface.ContextMenus { /// - /// Provides data for events. + /// Provides data for methods. /// public class CustomContextMenuItemSelectedArgs { @@ -15,6 +15,11 @@ /// public CustomContextMenuItem SelectedItem { get; init; } + /// + /// Initializes a new instance of the class. + /// + /// The currently opened context menu. + /// The selected item within the currently opened context menu. public CustomContextMenuItemSelectedArgs(ContextMenuOpenedArgs contextMenuOpenedArgs, CustomContextMenuItem selectedItem) { ContextMenuOpenedArgs = contextMenuOpenedArgs; diff --git a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedDelegate.cs b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedDelegate.cs index 4040cf9..53fc6c3 100644 --- a/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedDelegate.cs +++ b/PlayerTags/GameInterface/ContextMenus/CustomContextMenuItemSelectedDelegate.cs @@ -1,4 +1,8 @@ namespace PlayerTags.GameInterface.ContextMenus { + /// + /// Represents the method that handles when a is selected. + /// + /// The data associated with the selected . public delegate void CustomContextMenuItemSelectedDelegate(CustomContextMenuItemSelectedArgs args); } diff --git a/PlayerTags/GameInterface/ContextMenus/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentContext.cs b/PlayerTags/GameInterface/ContextMenus/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentContext.cs index 3f36c12..a175fb8 100644 --- a/PlayerTags/GameInterface/ContextMenus/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentContext.cs +++ b/PlayerTags/GameInterface/ContextMenus/FFXIVClientStructs/FFXIV/Client/UI/Agent/AgentContext.cs @@ -16,9 +16,9 @@ namespace FFXIVClientStructs.FFXIV.Client.UI.Agent [FieldOffset(0xD08)] public byte* SubContextMenuTitle; [FieldOffset(0xD18)] public unsafe AgentContextItemData* ItemData; [FieldOffset(0xE08)] public Utf8String ObjectName; - [FieldOffset(0xEE0)] public uint ObjectContentIdLower; - [FieldOffset(0xEF0)] public uint ObjectId; - [FieldOffset(0xF00)] public ushort ObjectWorldId; + [FieldOffset(0xEE0)] public uint GameObjectContentIdLower; + [FieldOffset(0xEF0)] public uint GameObjectId; + [FieldOffset(0xF00)] public ushort GameObjectWorldId; [FieldOffset(0x1740)] public bool IsSubContextMenu; } } diff --git a/PlayerTags/GameInterface/ContextMenus/GameContextMenuItem.cs b/PlayerTags/GameInterface/ContextMenus/GameContextMenuItem.cs index 180ed91..a3edc3b 100644 --- a/PlayerTags/GameInterface/ContextMenus/GameContextMenuItem.cs +++ b/PlayerTags/GameInterface/ContextMenus/GameContextMenuItem.cs @@ -1,16 +1,26 @@ using Dalamud.Game.Text.SeStringHandling; -using System; namespace PlayerTags.GameInterface.ContextMenus { + /// + /// An item in a context menu that with a specific game action. + /// public class GameContextMenuItem : ContextMenuItem { - public byte Action { get; } + /// + /// The game action that will be handled when the item is selected. + /// + public byte ItemSelectedAction { get; } - public GameContextMenuItem(SeString name, byte action) + /// + /// Initializes a new instance of the class. + /// + /// The name of the item. + /// The game action that will be handled when the item is selected. + public GameContextMenuItem(SeString name, byte itemSelectedAction) : base(name) { - Action = action; + ItemSelectedAction = itemSelectedAction; } } } \ No newline at end of file diff --git a/PlayerTags/GameInterface/ContextMenus/GameObjectContext.cs b/PlayerTags/GameInterface/ContextMenus/GameObjectContext.cs index 4322d25..da8fa0f 100644 --- a/PlayerTags/GameInterface/ContextMenus/GameObjectContext.cs +++ b/PlayerTags/GameInterface/ContextMenus/GameObjectContext.cs @@ -2,20 +2,42 @@ namespace PlayerTags.GameInterface.ContextMenus { + /// + /// Provides game object context to a context menu. + /// public class GameObjectContext { + /// + /// The id of the game object. + /// public uint Id { get; } - public uint ContentIdLower { get; } + /// + /// The lower content id of the game object. + /// + public uint LowerContentId { get; } + /// + /// The name of the game object. + /// public SeString? Name { get; } + /// + /// The world id of the game object. + /// public ushort WorldId { get; } - public GameObjectContext(uint id, uint contentIdLower, SeString name, ushort worldId) + /// + /// Initializes a new instance of the class. + /// + /// The id of the game object. + /// The lower content id of the game object. + /// The name of the game object. + /// The world id of the game object. + public GameObjectContext(uint id, uint lowerContentId, SeString name, ushort worldId) { Id = id; - ContentIdLower = contentIdLower; + LowerContentId = lowerContentId; Name = name; WorldId = worldId; } diff --git a/PlayerTags/GameInterface/ContextMenus/ItemContext.cs b/PlayerTags/GameInterface/ContextMenus/ItemContext.cs index 6aaa50b..df197ab 100644 --- a/PlayerTags/GameInterface/ContextMenus/ItemContext.cs +++ b/PlayerTags/GameInterface/ContextMenus/ItemContext.cs @@ -1,13 +1,31 @@ namespace PlayerTags.GameInterface.ContextMenus { + /// + /// Provides item context to a context menu. + /// public class ItemContext { + /// + /// The id of the item. + /// public uint Id { get; } + /// + /// The count of the item in the stack. + /// public uint Count { get; } + /// + /// Whether the item is high quality. + /// public bool IsHighQuality { get; } + /// + /// Initializes a new instance of the class. + /// + /// The id of the item. + /// The count of the item in the stack. + /// Whether the item is high quality. public ItemContext(uint id, uint count, bool isHighQuality) { Id = id; diff --git a/PlayerTags/GameInterface/ContextMenus/OpenSubContextMenuItem.cs b/PlayerTags/GameInterface/ContextMenus/OpenSubContextMenuItem.cs index fde0e12..160ad0d 100644 --- a/PlayerTags/GameInterface/ContextMenus/OpenSubContextMenuItem.cs +++ b/PlayerTags/GameInterface/ContextMenus/OpenSubContextMenuItem.cs @@ -2,15 +2,26 @@ namespace PlayerTags.GameInterface.ContextMenus { + /// + /// An item in a context menu that can open a sub context menu. + /// public class OpenSubContextMenuItem : ContextMenuItem { - public ContextMenuOpenedDelegate OpenedAction { get; set; } + /// + /// The action that will be called when the item is selected. + /// + public ContextMenuOpenedDelegate Opened { get; set; } - internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate openedAction) + /// + /// Initializes a new instance of the class. + /// + /// The name of the item. + /// The action that will be called when the item is selected. + internal OpenSubContextMenuItem(SeString name, ContextMenuOpenedDelegate opened) : base(name) { - OpenedAction = openedAction; - HasNextArrow = true; + Opened = opened; + Indicator = ContextMenuItemIndicator.Next; } } } \ No newline at end of file diff --git a/PlayerTags/GameInterface/GameInterfaceHelper.cs b/PlayerTags/GameInterface/GameInterfaceHelper.cs index 2fc710a..607f589 100644 --- a/PlayerTags/GameInterface/GameInterfaceHelper.cs +++ b/PlayerTags/GameInterface/GameInterfaceHelper.cs @@ -121,6 +121,7 @@ namespace PlayerTags.GameInterface } IMemorySpace.Free((void*)ptr, size); + ptr = IntPtr.Zero; } } } diff --git a/PlayerTags/RandomNameGenerator.cs b/PlayerTags/RandomNameGenerator.cs index 1d32a3f..384548d 100644 --- a/PlayerTags/RandomNameGenerator.cs +++ b/PlayerTags/RandomNameGenerator.cs @@ -7,7 +7,7 @@ using System.Reflection; namespace PlayerTags { /// - /// Generates names based on an existing list of words. + /// Generates names based on existing lists of words. /// public static class RandomNameGenerator { @@ -94,7 +94,7 @@ namespace PlayerTags } /// - /// Gets a deterministic hash code for the given string/ + /// Gets a deterministic hash code for the given string. /// /// The string to hash. /// A deterministic hash code.