using System; using System.Globalization; using System.Numerics; using System.Runtime.CompilerServices; using Dalamud.Bindings.ImGui; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.Text; using Dalamud.Interface; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Control; using FFXIVClientStructs.FFXIV.Client.Game.Object; using Microsoft.Extensions.Logging; using Questionable.Controller; using Questionable.Data; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Common; namespace Questionable.Windows.QuestComponents; internal sealed class CreationUtilsComponent { private readonly MovementController _movementController; private readonly GameFunctions _gameFunctions; private readonly QuestFunctions _questFunctions; private readonly TerritoryData _territoryData; private readonly QuestData _questData; private readonly QuestSelectionWindow _questSelectionWindow; private readonly IClientState _clientState; private readonly ITargetManager _targetManager; private readonly ICondition _condition; private readonly IGameGui _gameGui; private readonly Configuration _configuration; private readonly ILogger _logger; public CreationUtilsComponent(MovementController movementController, GameFunctions gameFunctions, QuestFunctions questFunctions, TerritoryData territoryData, QuestData questData, QuestSelectionWindow questSelectionWindow, IClientState clientState, ITargetManager targetManager, ICondition condition, IGameGui gameGui, Configuration configuration, ILogger logger) { _movementController = movementController; _gameFunctions = gameFunctions; _questFunctions = questFunctions; _territoryData = territoryData; _questData = questData; _questSelectionWindow = questSelectionWindow; _clientState = clientState; _targetManager = targetManager; _condition = condition; _gameGui = gameGui; _configuration = configuration; _logger = logger; } public void Draw() { ImGui.Text(_territoryData.GetNameAndId(_clientState.TerritoryType)); if (_gameFunctions.IsFlyingUnlockedInCurrentZone()) { ImGui.SameLine(); ImGui.Text(SeIconChar.BotanistSprout.ToIconString()); } if (_configuration.Advanced.AdditionalStatusInformation) { QuestReference currentQuest = _questFunctions.GetCurrentQuest(); ImU8String text = new ImU8String(18, 2); text.AppendLiteral("Current Quest: "); text.AppendFormatted(currentQuest.CurrentQuest); text.AppendLiteral(" → "); text.AppendFormatted(currentQuest.Sequence); ImGui.Text(text); } if (_targetManager.Target != null) { DrawTargetDetails(_targetManager.Target); DrawInteractionButtons(_targetManager.Target); ImGui.SameLine(); DrawCopyButton(_targetManager.Target); } else { DrawCopyButton(); } ulong hoveredItem = _gameGui.HoveredItem; if (hoveredItem != 0L) { ImGui.Separator(); ImU8String text = new ImU8String(14, 1); text.AppendLiteral("Hovered Item: "); text.AppendFormatted(hoveredItem); ImGui.Text(text); } } private unsafe void DrawTargetDetails(IGameObject target) { string value = string.Empty; DefaultInterpolatedStringHandler handler; if (target is ICharacter { NameId: not 0u } character) { handler = new DefaultInterpolatedStringHandler(4, 1); handler.AppendLiteral("; n="); handler.AppendFormatted(character.NameId); value = handler.ToStringAndClear(); } ImGui.Separator(); IFormatProvider invariantCulture = CultureInfo.InvariantCulture; IFormatProvider provider = invariantCulture; handler = new DefaultInterpolatedStringHandler(14, 4, invariantCulture); handler.AppendLiteral("Target: "); handler.AppendFormatted(target.Name); handler.AppendLiteral(" ("); handler.AppendFormatted(target.ObjectKind); handler.AppendLiteral("; "); handler.AppendFormatted(target.BaseId); handler.AppendFormatted(value); handler.AppendLiteral(")"); ImGui.Text(string.Create(provider, ref handler)); if (_clientState.LocalPlayer != null) { invariantCulture = CultureInfo.InvariantCulture; IFormatProvider provider2 = invariantCulture; handler = new DefaultInterpolatedStringHandler(10, 1, invariantCulture); handler.AppendLiteral("Distance: "); handler.AppendFormatted((target.Position - _clientState.LocalPlayer.Position).Length(), "F2"); ImGui.Text(string.Create(provider2, ref handler)); ImGui.SameLine(); float value2 = target.Position.Y - _clientState.LocalPlayer.Position.Y; invariantCulture = CultureInfo.InvariantCulture; IFormatProvider provider3 = invariantCulture; handler = new DefaultInterpolatedStringHandler(3, 1, invariantCulture); handler.AppendLiteral("Y: "); handler.AppendFormatted(value2, "F2"); string text = string.Create(provider3, ref handler); if (Math.Abs(value2) >= 1.95f) { ImGui.TextColored(ImGuiColors.DalamudOrange, text); } else { ImGui.Text(text); } ImGui.SameLine(); } GameObject* address = (GameObject*)target.Address; ImU8String text2 = new ImU8String(4, 1); text2.AppendLiteral("QM: "); text2.AppendFormatted(address->NamePlateIconId); ImGui.Text(text2); } private unsafe void DrawInteractionButtons(IGameObject target) { ImGui.BeginDisabled(!_movementController.IsNavmeshReady || _gameFunctions.IsOccupied()); if (!_movementController.IsPathfinding) { if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Bullseye, "To Target")) { _movementController.NavigateTo(EMovementType.DebugWindow, target.BaseId, target.Position, _condition[ConditionFlag.Mounted] && _gameFunctions.IsFlyingUnlockedInCurrentZone(), sprint: true); } } else if (ImGui.Button("Cancel pathfinding")) { _movementController.ResetPathfinding(); } ImGui.EndDisabled(); ImGui.SameLine(); ImGui.BeginDisabled(!_questData.IsIssuerOfAnyQuest(target.BaseId)); bool num = ImGuiComponents.IconButton(FontAwesomeIcon.MapMarkerAlt); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Show all Quests starting with your current target."); } if (num) { _questSelectionWindow.OpenForTarget(_targetManager.Target); } ImGui.EndDisabled(); ImGui.BeginDisabled(_gameFunctions.IsOccupied()); ImGui.SameLine(); bool num2 = ImGuiComponents.IconButton(FontAwesomeIcon.MousePointer); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Interact with your current target."); } if (num2) { ulong num3 = TargetSystem.Instance()->InteractWithObject((GameObject*)target.Address, checkLineOfSight: false); _logger.LogInformation("XXXXX Interaction Result: {Result}", num3); } ImGui.EndDisabled(); } private unsafe void DrawCopyButton(IGameObject target) { GameObject* address = (GameObject*)target.Address; bool num = ImGuiComponents.IconButton(FontAwesomeIcon.Copy); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Left click: Copy target position as JSON.\nRight click: Copy target position as C# code."); } if (num) { ImU8String clipboardText; if (target.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.GatheringPoint) { clipboardText = new ImU8String(59, 4); clipboardText.AppendLiteral("\"DataId\": "); clipboardText.AppendFormatted(target.BaseId); clipboardText.AppendLiteral(",\n\"Position\": {\n \"X\": "); clipboardText.AppendFormatted(target.Position.X.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Y\": "); clipboardText.AppendFormatted(target.Position.Y.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Z\": "); clipboardText.AppendFormatted(target.Position.Z.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral("\n}"); ImGui.SetClipboardText(clipboardText); return; } string text; switch (address->NamePlateIconId) { case 71201u: case 71211u: case 71221u: case 71231u: case 71341u: case 71351u: text = "AcceptQuest"; break; case 71202u: case 71212u: case 71222u: case 71232u: case 71342u: case 71352u: text = "AcceptQuest"; break; case 71205u: case 71215u: case 71225u: case 71235u: case 71345u: case 71355u: text = "CompleteQuest"; break; default: text = "Interact"; break; } string value = text; clipboardText = new ImU8String(99, 6); clipboardText.AppendLiteral("\"DataId\": "); clipboardText.AppendFormatted(target.BaseId); clipboardText.AppendLiteral(",\n\"Position\": {\n \"X\": "); clipboardText.AppendFormatted(target.Position.X.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Y\": "); clipboardText.AppendFormatted(target.Position.Y.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Z\": "); clipboardText.AppendFormatted(target.Position.Z.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral("\n},\n\"TerritoryId\": "); clipboardText.AppendFormatted(_clientState.TerritoryType); clipboardText.AppendLiteral(",\n\"InteractionType\": \""); clipboardText.AppendFormatted(value); clipboardText.AppendLiteral("\""); ImGui.SetClipboardText(clipboardText); } else if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { DefaultInterpolatedStringHandler handler; if (target.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Aetheryte) { EAetheryteLocation baseId = (EAetheryteLocation)target.BaseId; IFormatProvider invariantCulture = CultureInfo.InvariantCulture; IFormatProvider provider = invariantCulture; handler = new DefaultInterpolatedStringHandler(36, 4, invariantCulture); handler.AppendLiteral("{EAetheryteLocation."); handler.AppendFormatted(baseId); handler.AppendLiteral(", new("); handler.AppendFormatted(target.Position.X); handler.AppendLiteral("f, "); handler.AppendFormatted(target.Position.Y); handler.AppendLiteral("f, "); handler.AppendFormatted(target.Position.Z); handler.AppendLiteral("f)},"); ImGui.SetClipboardText(string.Create(provider, ref handler)); } else { IFormatProvider invariantCulture = CultureInfo.InvariantCulture; IFormatProvider provider2 = invariantCulture; handler = new DefaultInterpolatedStringHandler(12, 3, invariantCulture); handler.AppendLiteral("new("); handler.AppendFormatted(target.Position.X); handler.AppendLiteral("f, "); handler.AppendFormatted(target.Position.Y); handler.AppendLiteral("f, "); handler.AppendFormatted(target.Position.Z); handler.AppendLiteral("f)"); ImGui.SetClipboardText(string.Create(provider2, ref handler)); } } } private void DrawCopyButton() { if (_clientState.LocalPlayer != null) { bool num = ImGuiComponents.IconButton(FontAwesomeIcon.Copy); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Left click: Copy your position as JSON.\nRight click: Copy your position as C# code."); } if (num) { ImU8String clipboardText = new ImU8String(87, 4); clipboardText.AppendLiteral("\"Position\": {\n \"X\": "); clipboardText.AppendFormatted(_clientState.LocalPlayer.Position.X.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Y\": "); clipboardText.AppendFormatted(_clientState.LocalPlayer.Position.Y.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral(",\n \"Z\": "); clipboardText.AppendFormatted(_clientState.LocalPlayer.Position.Z.ToString(CultureInfo.InvariantCulture)); clipboardText.AppendLiteral("\n},\n\"TerritoryId\": "); clipboardText.AppendFormatted(_clientState.TerritoryType); clipboardText.AppendLiteral(",\n\"InteractionType\": \"\""); ImGui.SetClipboardText(clipboardText); } else if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) { Vector3 position = _clientState.LocalPlayer.Position; IFormatProvider invariantCulture = CultureInfo.InvariantCulture; DefaultInterpolatedStringHandler handler = new DefaultInterpolatedStringHandler(12, 3, invariantCulture); handler.AppendLiteral("new("); handler.AppendFormatted(position.X); handler.AppendLiteral("f, "); handler.AppendFormatted(position.Y); handler.AppendLiteral("f, "); handler.AppendFormatted(position.Z); handler.AppendLiteral("f)"); ImGui.SetClipboardText(string.Create(invariantCulture, ref handler)); } } } }