From 5673272fac14f52f3001e0e62147d62c4ceb858d Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:38:32 +0800 Subject: [PATCH] Add player tracking in NavigateChatLink --- .../Patches/Dynamic/GameCamera_Patch.cs | 53 +++++++++++++++++++ .../Chat/ChatLinks/NavigateChatLinkHandler.cs | 16 ++++-- NebulaWorld/Player/GizmoManager.cs | 2 + 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs index 620fd7eb2..4acef5a87 100644 --- a/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs @@ -1,7 +1,10 @@ #region using HarmonyLib; +using NebulaModel.DataStructures.Chat; +using NebulaWorld; using NebulaWorld.GameStates; +using NebulaWorld.MonoBehaviours.Local.Chat; #endregion @@ -17,4 +20,54 @@ public static bool Logic_Prefix() // prevent NRE while doing a reconnect as a client issued through the chat command return !(GameStatesManager.DuringReconnect && GameMain.mainPlayer == null); } + + [HarmonyPostfix] + [HarmonyPatch(nameof(GameCamera.Logic))] + public static void Logic_Postfix(GameCamera __instance) + { + if (!Multiplayer.IsActive || GameStatesManager.DuringReconnect) return; + + var observingPlayerId = Multiplayer.Session.Gizmos.ObservingPlayerId; + if (observingPlayerId == 0) return; + + if (VFInput.escape) + { + Multiplayer.Session.Gizmos.ObservingPlayerId = 0; + ChatManager.Instance.SendChatMessage( + "Exit tracking mode".Translate(), + ChatMessageType.CommandOutputMessage); + return; + } + + if (observingPlayerId > 0) + { + TrackingPlayer(__instance, observingPlayerId); + } + } + + private static void TrackingPlayer(GameCamera cam, ushort playerId) + { + using (Multiplayer.Session.World.GetRemotePlayersModels(out var models)) + { + if (!models.TryGetValue(playerId, out var model)) + { + ChatManager.Instance.SendChatMessage( + string.Format("Can't find player {0}".Translate(), playerId), + ChatMessageType.CommandOutputMessage); + Multiplayer.Session.Gizmos.ObservingPlayerId = 0; + return; + } + var planetId = model.PlayerInstance.planetId; + if (planetId > 0 && planetId != GameMain.mainPlayer.planetId) + { + ChatManager.Instance.SendChatMessage( + string.Format("Player {0} is on a different planet".Translate(), playerId), + ChatMessageType.CommandOutputMessage); + Multiplayer.Session.Gizmos.ObservingPlayerId = 0; + return; + } + cam.rtsTarget.position = model.PlayerTransform.position; + cam.rtsTarget.eulerAngles = Maths.SphericalRotation(cam.rtsTarget.position, 0f).eulerAngles; + } + } } diff --git a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs index 165d3e563..76aaa849a 100644 --- a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs @@ -29,6 +29,16 @@ public void OnClick(string data) public void OnRightClick(string data) { + var substrings = data.Split(SplitSeparator); + switch (substrings.Length) + { + case 2: // PlayerId + if (!ushort.TryParse(substrings[0], out var playerId)) return; + Multiplayer.Session.Gizmos.ObservingPlayerId = playerId; + ChatManager.Instance.SendChatMessage("Start tracking to player (ESC to exit)".Translate(), + ChatMessageType.CommandOutputMessage); + break; + } } public void OnHover(string data, ChatLinkTrigger trigger, ref MonoBehaviour tipObject) @@ -65,7 +75,7 @@ private static void UpdateTip(ChatLinkTrigger trigger, ref MonoBehaviour tipObje if (buttonTip == null) { buttonTip = UIButtonTip.Create(false, "Navigate".Translate(), - "Click to create a navigate line to the target.".Translate(), 2, offset, 0, rect, "", ""); + "Left click to create a navigate line to the target.\nRight click to track the target.".Translate(), 2, offset, 0, rect, "", ""); if (tipObject != null) { Object.Destroy(tipObject.gameObject); @@ -77,13 +87,13 @@ private static void UpdateTip(ChatLinkTrigger trigger, ref MonoBehaviour tipObje if (!buttonTip.gameObject.activeSelf) { buttonTip.gameObject.SetActive(true); - buttonTip.SetTip(false, "Navigate".Translate(), "Click to create a navigate line to the target.".Translate(), 2, + buttonTip.SetTip(false, "Navigate".Translate(), "Left click to create a navigate line to the target.\nRight click to track the target.".Translate(), 2, offset, 0, rect, "", ""); } if (buttonTip.isActiveAndEnabled && !buttonTip.titleComp.text.Equals("Navigate")) { - buttonTip.SetTip(false, "Navigate".Translate(), "Click to create a navigate line to the target.".Translate(), 2, + buttonTip.SetTip(false, "Navigate".Translate(), "Left click to create a navigate line to the target.\nRight click to track the target.".Translate(), 2, offset, 0, rect, "", ""); } } diff --git a/NebulaWorld/Player/GizmoManager.cs b/NebulaWorld/Player/GizmoManager.cs index 212d5044f..9ba83e9bb 100644 --- a/NebulaWorld/Player/GizmoManager.cs +++ b/NebulaWorld/Player/GizmoManager.cs @@ -15,6 +15,8 @@ namespace NebulaWorld.Player; public class GizmoManager : IDisposable { + public ushort ObservingPlayerId { get; set; } + private ushort indicatorPlayerId; private int indicatorPlanetId; private Vector3 indicatorPos;