diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index 59c136416..0235bef5a 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -7,6 +7,7 @@ using Dalamud.Hooking; using Dalamud.Interface; using Dalamud.IoC; using Dalamud.IoC.Internal; +using Dalamud.Plugin.Services; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.System.String; @@ -28,7 +29,10 @@ namespace Dalamud.Game.Gui; [PluginInterface] [InterfaceVersion("1.0")] [ServiceManager.BlockingEarlyLoadedService] -public sealed unsafe class GameGui : IDisposable, IServiceType +#pragma warning disable SA1015 +[ResolveVia] +#pragma warning restore SA1015 +public sealed unsafe class GameGui : IDisposable, IServiceType, IGameGui { private readonly GameGuiAddressResolver address; @@ -112,43 +116,26 @@ public sealed unsafe class GameGui : IDisposable, IServiceType [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte); - - /// - /// Event which is fired when the game UI hiding is toggled. - /// + + /// public event EventHandler UiHideToggled; - /// - /// Event that is fired when the currently hovered item changes. - /// + /// public event EventHandler HoveredItemChanged; - /// - /// Event that is fired when the currently hovered action changes. - /// + /// public event EventHandler HoveredActionChanged; - /// - /// Gets a value indicating whether the game UI is hidden. - /// + /// public bool GameUiHidden { get; private set; } - /// - /// Gets or sets the item ID that is currently hovered by the player. 0 when no item is hovered. - /// If > 1.000.000, subtract 1.000.000 and treat it as HQ. - /// + /// public ulong HoveredItem { get; set; } - /// - /// Gets the action ID that is current hovered by the player. 0 when no action is hovered. - /// + /// public HoveredAction HoveredAction { get; } = new HoveredAction(); - /// - /// Opens the in-game map with a flag on the location of the parameter. - /// - /// Link to the map to be opened. - /// True if there were no errors and it could open the map. + /// public bool OpenMapWithMapLink(MapLinkPayload mapLink) { var uiModule = this.GetUIModule(); @@ -178,22 +165,11 @@ public sealed unsafe class GameGui : IDisposable, IServiceType return this.openMapWithFlag(uiMapObjectPtr, mapLinkString); } - /// - /// Converts in-world coordinates to screen coordinates (upper left corner origin). - /// - /// Coordinates in the world. - /// Converted coordinates. - /// True if worldPos corresponds to a position in front of the camera and screenPos is in the viewport. + /// public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos) => this.WorldToScreen(worldPos, out screenPos, out var inView) && inView; - /// - /// Converts in-world coordinates to screen coordinates (upper left corner origin). - /// - /// Coordinates in the world. - /// Converted coordinates. - /// True if screenPos corresponds to a position inside the camera viewport. - /// True if worldPos corresponds to a position in front of the camera. + /// public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView) { // Get base object with matrices @@ -220,13 +196,7 @@ public sealed unsafe class GameGui : IDisposable, IServiceType return inFront; } - /// - /// Converts screen coordinates to in-world coordinates via raycasting. - /// - /// Screen coordinates. - /// Converted coordinates. - /// How far to search for a collision. - /// True if successful. On false, worldPos's contents are undefined. + /// public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f) { // The game is only visible in the main viewport, so if the cursor is outside @@ -290,10 +260,7 @@ public sealed unsafe class GameGui : IDisposable, IServiceType return isSuccess; } - /// - /// Gets a pointer to the game's UI module. - /// - /// IntPtr pointing to UI module. + /// public IntPtr GetUIModule() { var framework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance(); @@ -307,12 +274,7 @@ public sealed unsafe class GameGui : IDisposable, IServiceType return (IntPtr)uiModule; } - /// - /// Gets the pointer to the Addon with the given name and index. - /// - /// Name of addon to find. - /// Index of addon to find (1-indexed). - /// IntPtr.Zero if unable to find UI, otherwise IntPtr pointing to the start of the addon. + /// public IntPtr GetAddonByName(string name, int index = 1) { var atkStage = AtkStage.GetSingleton(); @@ -330,29 +292,17 @@ public sealed unsafe class GameGui : IDisposable, IServiceType return (IntPtr)addon; } - /// - /// Find the agent associated with an addon, if possible. - /// - /// The addon name. - /// A pointer to the agent interface. + /// public IntPtr FindAgentInterface(string addonName) { var addon = this.GetAddonByName(addonName); return this.FindAgentInterface(addon); } - /// - /// Find the agent associated with an addon, if possible. - /// - /// The addon address. - /// A pointer to the agent interface. + /// public IntPtr FindAgentInterface(void* addon) => this.FindAgentInterface((IntPtr)addon); - - /// - /// Find the agent associated with an addon, if possible. - /// - /// The addon address. - /// A pointer to the agent interface. + + /// public IntPtr FindAgentInterface(IntPtr addonPtr) { if (addonPtr == IntPtr.Zero) diff --git a/Dalamud/Plugin/Services/IGameGui.cs b/Dalamud/Plugin/Services/IGameGui.cs new file mode 100644 index 000000000..ddb0ec67c --- /dev/null +++ b/Dalamud/Plugin/Services/IGameGui.cs @@ -0,0 +1,112 @@ +using System; +using System.Numerics; + +using Dalamud.Game.Gui; +using Dalamud.Game.Text.SeStringHandling.Payloads; + +namespace Dalamud.Plugin.Services; + +/// +/// A class handling many aspects of the in-game UI. +/// +public unsafe interface IGameGui +{ + /// + /// Event which is fired when the game UI hiding is toggled. + /// + public event EventHandler UiHideToggled; + + /// + /// Event that is fired when the currently hovered item changes. + /// + public event EventHandler HoveredItemChanged; + + /// + /// Event that is fired when the currently hovered action changes. + /// + public event EventHandler HoveredActionChanged; + + /// + /// Gets a value indicating whether the game UI is hidden. + /// + public bool GameUiHidden { get; } + + /// + /// Gets or sets the item ID that is currently hovered by the player. 0 when no item is hovered. + /// If > 1.000.000, subtract 1.000.000 and treat it as HQ. + /// + public ulong HoveredItem { get; set; } + + /// + /// Gets the action ID that is current hovered by the player. 0 when no action is hovered. + /// + public HoveredAction HoveredAction { get; } + + /// + /// Opens the in-game map with a flag on the location of the parameter. + /// + /// Link to the map to be opened. + /// True if there were no errors and it could open the map. + public bool OpenMapWithMapLink(MapLinkPayload mapLink); + + /// + /// Converts in-world coordinates to screen coordinates (upper left corner origin). + /// + /// Coordinates in the world. + /// Converted coordinates. + /// True if worldPos corresponds to a position in front of the camera and screenPos is in the viewport. + public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos); + + /// + /// Converts in-world coordinates to screen coordinates (upper left corner origin). + /// + /// Coordinates in the world. + /// Converted coordinates. + /// True if screenPos corresponds to a position inside the camera viewport. + /// True if worldPos corresponds to a position in front of the camera. + public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView); + + /// + /// Converts screen coordinates to in-world coordinates via raycasting. + /// + /// Screen coordinates. + /// Converted coordinates. + /// How far to search for a collision. + /// True if successful. On false, worldPos's contents are undefined. + public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f); + + /// + /// Gets a pointer to the game's UI module. + /// + /// IntPtr pointing to UI module. + public nint GetUIModule(); + + /// + /// Gets the pointer to the Addon with the given name and index. + /// + /// Name of addon to find. + /// Index of addon to find (1-indexed). + /// nint.Zero if unable to find UI, otherwise nint pointing to the start of the addon. + public nint GetAddonByName(string name, int index = 1); + + /// + /// Find the agent associated with an addon, if possible. + /// + /// The addon name. + /// A pointer to the agent interface. + public nint FindAgentInterface(string addonName); + + /// + /// Find the agent associated with an addon, if possible. + /// + /// The addon address. + /// A pointer to the agent interface. + public nint FindAgentInterface(void* addon); + + /// + /// Find the agent associated with an addon, if possible. + /// + /// The addon address. + /// A pointer to the agent interface. + public IntPtr FindAgentInterface(IntPtr addonPtr); +}