diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index dd40218..8c2b03c 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -1,4 +1,5 @@ using Dalamud.ContextMenu; +using Dalamud.Game.ClientState.Objects; using Dalamud.Interface.ImGuiFileDialog; using Dalamud.Interface.Windowing; using Dalamud.Plugin; @@ -33,7 +34,7 @@ public sealed class Plugin : IDalamudPlugin public Plugin(DalamudPluginInterface pluginInterface, ICommandManager commandManager, IDataManager gameData, IFramework framework, IObjectTable objectTable, IClientState clientState, ICondition condition, IChatGui chatGui, - IGameGui gameGui, IDtrBar dtrBar, IPluginLog pluginLog) + IGameGui gameGui, IDtrBar dtrBar, IPluginLog pluginLog, ITargetManager targetManager) { _hostBuilderRunTask = new HostBuilder() .UseContentRoot(pluginInterface.ConfigDirectory.FullName) @@ -77,7 +78,7 @@ public sealed class Plugin : IDalamudPlugin collection.AddSingleton(); collection.AddSingleton((s) => new DalamudContextMenu(pluginInterface)); collection.AddSingleton((s) => new DalamudUtilService(s.GetRequiredService>(), - clientState, objectTable, framework, gameGui, condition, gameData, + clientState, objectTable, framework, gameGui, condition, gameData, targetManager, s.GetRequiredService(), s.GetRequiredService())); collection.AddSingleton((s) => new DtrEntry(s.GetRequiredService>(), dtrBar, s.GetRequiredService(), s.GetRequiredService(), s.GetRequiredService(), s.GetRequiredService())); diff --git a/MareSynchronos/Services/DalamudUtilService.cs b/MareSynchronos/Services/DalamudUtilService.cs index 0306e1c..72f3fce 100644 --- a/MareSynchronos/Services/DalamudUtilService.cs +++ b/MareSynchronos/Services/DalamudUtilService.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Conditions; +using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Game.Character; @@ -15,7 +16,7 @@ using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; namespace MareSynchronos.Services; -public class DalamudUtilService : IHostedService +public class DalamudUtilService : IHostedService, IMediatorSubscriber { private readonly List _classJobIdsIgnoredForPets = [30]; private readonly IClientState _clientState; @@ -23,7 +24,6 @@ public class DalamudUtilService : IHostedService private readonly IFramework _framework; private readonly IGameGui _gameGui; private readonly ILogger _logger; - private readonly MareMediator _mediator; private readonly IObjectTable _objectTable; private readonly PerformanceCollectorService _performanceCollector; private uint? _classJobId = 0; @@ -35,7 +35,7 @@ public class DalamudUtilService : IHostedService private bool _sentBetweenAreas = false; public DalamudUtilService(ILogger logger, IClientState clientState, IObjectTable objectTable, IFramework framework, - IGameGui gameGui, ICondition condition, IDataManager gameData, MareMediator mediator, PerformanceCollectorService performanceCollector) + IGameGui gameGui, ICondition condition, IDataManager gameData, ITargetManager targetManager, MareMediator mediator, PerformanceCollectorService performanceCollector) { _logger = logger; _clientState = clientState; @@ -43,7 +43,7 @@ public class DalamudUtilService : IHostedService _framework = framework; _gameGui = gameGui; _condition = condition; - _mediator = mediator; + Mediator = mediator; _performanceCollector = performanceCollector; WorldData = new(() => { @@ -51,6 +51,17 @@ public class DalamudUtilService : IHostedService .Where(w => w.IsPublic && !w.Name.RawData.IsEmpty) .ToDictionary(w => (ushort)w.RowId, w => w.Name.ToString()); }); + mediator.Subscribe(this, async (msg) => + { + var name = msg.Pair.PlayerName; + if (string.IsNullOrEmpty(name)) return; + var addr = _playerCharas.FirstOrDefault(f => string.Equals(f.Value.Name, name, StringComparison.Ordinal)).Value.Address; + if (addr == nint.Zero) return; + await RunOnFrameworkThread(() => + { + targetManager.Target = CreateGameObject(addr); + }).ConfigureAwait(false); + }); } public unsafe GameObject* GposeTarget => TargetSystem.Instance()->GPoseTarget; @@ -64,6 +75,8 @@ public class DalamudUtilService : IHostedService public Lazy> WorldData { get; private set; } + public MareMediator Mediator { get; } + public Dalamud.Game.ClientState.Objects.Types.GameObject? CreateGameObject(IntPtr reference) { EnsureIsOnFramework(); @@ -279,6 +292,7 @@ public class DalamudUtilService : IHostedService { _logger.LogTrace("Stopping {type}", GetType()); + Mediator.UnsubscribeAll(this); _framework.Update -= FrameworkOnUpdate; return Task.CompletedTask; } @@ -433,31 +447,31 @@ public class DalamudUtilService : IHostedService { _logger.LogDebug("Gpose start"); IsInGpose = true; - _mediator.Publish(new GposeStartMessage()); + Mediator.Publish(new GposeStartMessage()); } else if (GposeTarget == null && IsInGpose) { _logger.LogDebug("Gpose end"); IsInGpose = false; - _mediator.Publish(new GposeEndMessage()); + Mediator.Publish(new GposeEndMessage()); } if (_condition[ConditionFlag.WatchingCutscene] && !IsInCutscene) { _logger.LogDebug("Cutscene start"); IsInCutscene = true; - _mediator.Publish(new CutsceneStartMessage()); - _mediator.Publish(new HaltScanMessage("Cutscene")); + Mediator.Publish(new CutsceneStartMessage()); + Mediator.Publish(new HaltScanMessage("Cutscene")); } else if (!_condition[ConditionFlag.WatchingCutscene] && IsInCutscene) { _logger.LogDebug("Cutscene end"); IsInCutscene = false; - _mediator.Publish(new CutsceneEndMessage()); - _mediator.Publish(new ResumeScanMessage("Cutscene")); + Mediator.Publish(new CutsceneEndMessage()); + Mediator.Publish(new ResumeScanMessage("Cutscene")); } - if (IsInCutscene) { _mediator.Publish(new CutsceneFrameworkUpdateMessage()); return; } + if (IsInCutscene) { Mediator.Publish(new CutsceneFrameworkUpdateMessage()); return; } if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]) { @@ -469,8 +483,8 @@ public class DalamudUtilService : IHostedService { _logger.LogDebug("Zone switch/Gpose start"); _sentBetweenAreas = true; - _mediator.Publish(new ZoneSwitchStartMessage()); - _mediator.Publish(new HaltScanMessage("Zone switch")); + Mediator.Publish(new ZoneSwitchStartMessage()); + Mediator.Publish(new HaltScanMessage("Zone switch")); } } @@ -481,11 +495,11 @@ public class DalamudUtilService : IHostedService { _logger.LogDebug("Zone switch/Gpose end"); _sentBetweenAreas = false; - _mediator.Publish(new ZoneSwitchEndMessage()); - _mediator.Publish(new ResumeScanMessage("Zone switch")); + Mediator.Publish(new ZoneSwitchEndMessage()); + Mediator.Publish(new ResumeScanMessage("Zone switch")); } - _mediator.Publish(new FrameworkUpdateMessage()); + Mediator.Publish(new FrameworkUpdateMessage()); if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1)) return; @@ -496,16 +510,16 @@ public class DalamudUtilService : IHostedService _logger.LogDebug("Logged in"); IsLoggedIn = true; _lastZone = _clientState.TerritoryType; - _mediator.Publish(new DalamudLoginMessage()); + Mediator.Publish(new DalamudLoginMessage()); } else if (localPlayer == null && IsLoggedIn) { _logger.LogDebug("Logged out"); IsLoggedIn = false; - _mediator.Publish(new DalamudLogoutMessage()); + Mediator.Publish(new DalamudLogoutMessage()); } - _mediator.Publish(new DelayedFrameworkUpdateMessage()); + Mediator.Publish(new DelayedFrameworkUpdateMessage()); _delayedFrameworkUpdateCheck = DateTime.Now; } diff --git a/MareSynchronos/Services/Mediator/Messages.cs b/MareSynchronos/Services/Mediator/Messages.cs index 3d2f6f4..d5f8c02 100644 --- a/MareSynchronos/Services/Mediator/Messages.cs +++ b/MareSynchronos/Services/Mediator/Messages.cs @@ -77,6 +77,7 @@ public record OpenSyncshellAdminPanel(GroupFullInfoDto GroupInfo) : MessageBase; public record OpenPermissionWindow(Pair Pair) : MessageBase; public record DownloadLimitChangedMessage() : SameThreadMessage; public record CensusUpdateMessage(byte Gender, byte RaceId, byte TribeId) : MessageBase; +public record TargetPairMessage(Pair Pair) : MessageBase; #pragma warning restore S2094 #pragma warning restore MA0048 // File name must match type name \ No newline at end of file diff --git a/MareSynchronos/UI/Components/DrawUserPair.cs b/MareSynchronos/UI/Components/DrawUserPair.cs index dbb8466..fd66a09 100644 --- a/MareSynchronos/UI/Components/DrawUserPair.cs +++ b/MareSynchronos/UI/Components/DrawUserPair.cs @@ -208,7 +208,11 @@ public class DrawUserPair else if (_pair.IsVisible) { UiSharedService.NormalizedIcon(FontAwesomeIcon.Eye, ImGuiColors.ParsedGreen); - userPairText = _pair.UserData.AliasOrUID + " is visible: " + _pair.PlayerName; + userPairText = _pair.UserData.AliasOrUID + " is visible: " + _pair.PlayerName + Environment.NewLine + "Click to target this player"; + if (ImGui.IsItemClicked()) + { + _mediator.Publish(new TargetPairMessage(_pair)); + } } else { @@ -243,6 +247,7 @@ public class DrawUserPair return "Paired through " + groupString; })); } + UiSharedService.AttachToolTip(userPairText); ImGui.SameLine();