From 846717ad663e15b6bbc1dbb62ff89ae8800a32c7 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Thu, 29 Feb 2024 02:36:01 +0800 Subject: [PATCH 1/8] Add GizmoManager and update NavigateChatLinkHandler --- .../PlayerControlGizmo_Transpiler.cs | 69 --------- .../Chat/ChatLinks/NavigateChatLinkHandler.cs | 26 ++-- .../Chat/Commands/NavigateCommandHandler.cs | 10 +- .../Chat/Commands/WhoCommandHandler.cs | 2 +- .../Local/LocalPlayerMovement.cs | 3 + .../Remote/RemotePlayerMovement.cs | 45 ------ NebulaWorld/MultiplayerSession.cs | 5 + NebulaWorld/Player/GizmoManager.cs | 134 ++++++++++++++++++ 8 files changed, 164 insertions(+), 130 deletions(-) delete mode 100644 NebulaPatcher/Patches/Transpilers/PlayerControlGizmo_Transpiler.cs create mode 100644 NebulaWorld/Player/GizmoManager.cs diff --git a/NebulaPatcher/Patches/Transpilers/PlayerControlGizmo_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/PlayerControlGizmo_Transpiler.cs deleted file mode 100644 index 04a5a197c..000000000 --- a/NebulaPatcher/Patches/Transpilers/PlayerControlGizmo_Transpiler.cs +++ /dev/null @@ -1,69 +0,0 @@ -#region - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Reflection.Emit; -using HarmonyLib; -using NebulaWorld; -// ReSharper disable RedundantTypeArgumentsOfMethod -// ReSharper disable InconsistentNaming - -#endregion - -namespace NebulaPatcher.Patches.Transpilers; - -[HarmonyPatch(typeof(PlayerControlGizmo))] -[SuppressMessage("Style", "IDE1006:Naming Styles")] -public class PlayerControlGizmo_Transpiler -{ - [HarmonyTranspiler] - [HarmonyPatch(nameof(PlayerControlGizmo.GameTick))] - public static IEnumerable GameTick_Transpiler(IEnumerable instructions) - { - var matcher = new CodeMatcher(instructions) - .MatchForward(true, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerControlGizmo), "player")), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_controller"), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_modelVisible"), - new CodeMatch(OpCodes.Brfalse)); - var jmpPos = matcher.Operand; - matcher.Advance(1) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)) - .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate>(_this => - Multiplayer.IsActive && _this.player.navigation.indicatorAstroId > 100000)) - .Insert(new CodeInstruction(OpCodes.Brtrue, jmpPos)); - - matcher.MatchForward(true, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerControlGizmo), "player")), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_navigation"), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_indicatorAstroId"), - new CodeMatch(OpCodes.Ldc_I4_0), - new CodeMatch(OpCodes.Ble)); - jmpPos = matcher.Operand; - matcher.Advance(1) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)) - .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate>(_this => - Multiplayer.IsActive && _this.player.navigation.indicatorAstroId > 100000)) - .Insert(new CodeInstruction(OpCodes.Brtrue, jmpPos)); - - matcher.MatchForward(true, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlayerControlGizmo), "player")), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_navigation"), - new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "get_indicatorAstroId"), - new CodeMatch(OpCodes.Ldc_I4_0), - new CodeMatch(OpCodes.Ble)); - jmpPos = matcher.Operand; - matcher.Advance(1) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)) - .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate>(_this => - Multiplayer.IsActive && _this.player.navigation.indicatorAstroId > 100000)) - .Insert(new CodeInstruction(OpCodes.Brtrue, jmpPos)); - - return matcher.InstructionEnumeration(); - } -} diff --git a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs index 22d0a3d61..8469e0c85 100644 --- a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs @@ -11,18 +11,19 @@ namespace NebulaWorld.Chat.ChatLinks; public class NavigateChatLinkHandler : IChatLinkHandler { + const char SplitSeparator = '\t'; + public void OnClick(string data) { - using (Multiplayer.Session.World.GetRemotePlayersModels(out var remotePlayersModels)) + var substrings = data.Split(SplitSeparator); + switch (substrings.Length) { - foreach (var model in remotePlayersModels.Where(model => model.Value.Movement.Username == data)) - { - // handle indicator position update in RemotePlayerMovement.cs - GameMain.mainPlayer.navigation.indicatorAstroId = 100000 + model.Value.Movement.PlayerID; - ChatManager.Instance.SendChatMessage("Starting navigation to ".Translate() + model.Value.Movement.Username, + case 2: // PlayerId + if (!ushort.TryParse(substrings[0], out var playerId)) return; + Multiplayer.Session.Gizmos.SetIndicatorPlayerId(playerId); + ChatManager.Instance.SendChatMessage("Starting navigation to ".Translate() + substrings[1], ChatMessageType.CommandOutputMessage); - return; - } + break; } } @@ -85,6 +86,13 @@ private static void UpdateTip(ChatLinkTrigger trigger, ref MonoBehaviour tipObje public static string FormatNavigateString(string data) { - return $"{data}"; + var substrings = data.Split(SplitSeparator); + return $"{substrings[substrings.Length - 1]}"; + } + + public static string FormatNavigateToPlayerString(ushort playerId, string displayString) + { + var data = playerId + SplitSeparator.ToString() + displayString; + return FormatNavigateString(data); } } diff --git a/NebulaWorld/Chat/Commands/NavigateCommandHandler.cs b/NebulaWorld/Chat/Commands/NavigateCommandHandler.cs index e0723a660..b7b4a8749 100644 --- a/NebulaWorld/Chat/Commands/NavigateCommandHandler.cs +++ b/NebulaWorld/Chat/Commands/NavigateCommandHandler.cs @@ -41,7 +41,7 @@ public void Execute(ChatWindow window, string[] parameters) case "player": case "p": { - isNumeric = int.TryParse(parameters[1], out var ID); + isNumeric = ushort.TryParse(parameters[1], out var playerId); if (isNumeric) { @@ -49,10 +49,9 @@ public void Execute(ChatWindow window, string[] parameters) using (Multiplayer.Session.World.GetRemotePlayersModels( out var remotePlayersModels)) { - foreach (var model in remotePlayersModels.Where(model => model.Value.Movement.PlayerID == ID)) + foreach (var model in remotePlayersModels.Where(model => model.Value.Movement.PlayerID == playerId)) { - // handle indicator position update in RemotePlayerMovement.cs - GameMain.mainPlayer.navigation.indicatorAstroId = 100000 + ID; + Multiplayer.Session.Gizmos.SetIndicatorPlayerId(playerId); window.SendLocalChatMessage( "Starting navigation to ".Translate() + model.Value.Movement.Username, ChatMessageType.CommandOutputMessage); @@ -69,8 +68,7 @@ public void Execute(ChatWindow window, string[] parameters) foreach (var model in remotePlayersModels.Where(model => model.Value.Movement.Username == parameters[1])) { - // handle indicator position update in RemotePlayerMovement.cs - GameMain.mainPlayer.navigation.indicatorAstroId = 100000 + model.Value.Movement.PlayerID; + Multiplayer.Session.Gizmos.SetIndicatorPlayerId(model.Value.Movement.PlayerID); window.SendLocalChatMessage( "Starting navigation to ".Translate() + model.Value.Movement.Username, ChatMessageType.CommandOutputMessage); diff --git a/NebulaWorld/Chat/Commands/WhoCommandHandler.cs b/NebulaWorld/Chat/Commands/WhoCommandHandler.cs index 1757b4637..1cc44db9a 100644 --- a/NebulaWorld/Chat/Commands/WhoCommandHandler.cs +++ b/NebulaWorld/Chat/Commands/WhoCommandHandler.cs @@ -53,7 +53,7 @@ public static string BuildResultPayload(IPlayerData[] allPlayers, ILocalPlayer h private static string BuildWhoMessageTextForPlayer(IPlayerData playerData, ILocalPlayer localPlayer) { - var sb = new StringBuilder($"[{playerData.PlayerId}] {FormatNavigateString(playerData.Username)}"); + var sb = new StringBuilder($"[{playerData.PlayerId}] {FormatNavigateToPlayerString(playerData.PlayerId, playerData.Username)}"); if (localPlayer.Id == playerData.PlayerId) { sb.Append(" (host)".Translate()); diff --git a/NebulaWorld/MonoBehaviours/Local/LocalPlayerMovement.cs b/NebulaWorld/MonoBehaviours/Local/LocalPlayerMovement.cs index 523b3b362..d9eae0fe3 100644 --- a/NebulaWorld/MonoBehaviours/Local/LocalPlayerMovement.cs +++ b/NebulaWorld/MonoBehaviours/Local/LocalPlayerMovement.cs @@ -27,6 +27,9 @@ private void Awake() private void Update() { + // update navigation indicator + Multiplayer.Session.Gizmos.OnUpdate(); + time += Time.deltaTime; if (!(time >= BROADCAST_INTERVAL)) diff --git a/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs b/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs index db71b5636..546c409fd 100644 --- a/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs +++ b/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs @@ -68,12 +68,6 @@ private void Update() return; } - // update navigation indicator if requested - if (GameMain.mainPlayer.navigation.indicatorAstroId > 100000) - { - UpdateNavigationGizmo(); - } - // update player dot on minimap if on same planet if (playerDot != null && playerName != null && localPlanetId == GameMain.mainPlayer.planetId) { @@ -177,45 +171,6 @@ private void OnDisable() } } - private void UpdateNavigationGizmo() - { - if (PlayerID != GameMain.mainPlayer.navigation.indicatorAstroId - 100000) - { - return; - } - var gizmo = GameMain.mainPlayer.gizmo; - var starmap = UIRoot.instance.uiGame.starmap; - - if (gizmo.naviIndicatorGizmo == null) - { - gizmo.naviIndicatorGizmo = LineGizmo.Create(1, gizmo.player.position, rootTransform.position); - gizmo.naviIndicatorGizmo.autoRefresh = true; - gizmo.naviIndicatorGizmo.multiplier = 1.5f; - gizmo.naviIndicatorGizmo.alphaMultiplier = 0.6f; - gizmo.naviIndicatorGizmo.width = 1.8f; - gizmo.naviIndicatorGizmo.color = Configs.builtin.gizmoColors[4]; - gizmo.naviIndicatorGizmo.spherical = gizmo.player.planetId == localPlanetId; - gizmo.naviIndicatorGizmo.Open(); - } - if (gizmo.naviIndicatorGizmoStarmap == null) - { - gizmo.naviIndicatorGizmoStarmap = LineGizmo.Create(1, gizmo.player.position, rootTransform.position); - gizmo.naviIndicatorGizmoStarmap.autoRefresh = true; - gizmo.naviIndicatorGizmoStarmap.multiplier = 1.5f; - gizmo.naviIndicatorGizmoStarmap.alphaMultiplier = 0.3f; - gizmo.naviIndicatorGizmoStarmap.width = 0.01f; - gizmo.naviIndicatorGizmoStarmap.color = Configs.builtin.gizmoColors[4]; - gizmo.naviIndicatorGizmoStarmap.spherical = false; - gizmo.naviIndicatorGizmoStarmap.Open(); - } - - gizmo.naviIndicatorGizmo.startPoint = gizmo.player.position; - gizmo.naviIndicatorGizmo.endPoint = rootTransform.position; - gizmo.naviIndicatorGizmoStarmap.startPoint = (gizmo.player.uPosition - starmap.viewTargetUPos) * 0.00025; - gizmo.naviIndicatorGizmoStarmap.endPoint = (absolutePosition - starmap.viewTargetUPos) * 0.00025; - gizmo.naviIndicatorGizmoStarmap.gameObject.layer = 20; - } - public void UpdatePosition(PlayerMovement movement) { if (!rootTransform) diff --git a/NebulaWorld/MultiplayerSession.cs b/NebulaWorld/MultiplayerSession.cs index a9ff643fa..214f2d86f 100644 --- a/NebulaWorld/MultiplayerSession.cs +++ b/NebulaWorld/MultiplayerSession.cs @@ -47,6 +47,7 @@ public MultiplayerSession(INetworkProvider networkProvider) Belts = new BeltManager(); BuildTools = new BuildToolManager(); Drones = new DroneManager(); + Gizmos = new GizmoManager(); History = new GameDataHistoryManager(); State = new GameStatesManager(); Couriers = new CourierManager(); @@ -70,6 +71,7 @@ public MultiplayerSession(INetworkProvider networkProvider) public BeltManager Belts { get; set; } public BuildToolManager BuildTools { get; set; } public DroneManager Drones { get; set; } + public GizmoManager Gizmos { get; set; } public GameDataHistoryManager History { get; set; } private GameStatesManager State { get; set; } public CourierManager Couriers { get; set; } @@ -130,6 +132,9 @@ public void Dispose() Drones?.Dispose(); Drones = null; + Gizmos?.Dispose(); + Gizmos = null; + History?.Dispose(); History = null; diff --git a/NebulaWorld/Player/GizmoManager.cs b/NebulaWorld/Player/GizmoManager.cs new file mode 100644 index 000000000..212d5044f --- /dev/null +++ b/NebulaWorld/Player/GizmoManager.cs @@ -0,0 +1,134 @@ +#region + +using System; +using System.Collections.Generic; +using NebulaAPI.DataStructures; +using NebulaModel.DataStructures; +using NebulaModel.Packets.Players; +using UnityEngine; +using Random = UnityEngine.Random; +#pragma warning disable IDE1006 // Naming Styles + +#endregion + +namespace NebulaWorld.Player; + +public class GizmoManager : IDisposable +{ + private ushort indicatorPlayerId; + private int indicatorPlanetId; + private Vector3 indicatorPos; + private LineGizmo naviIndicatorGizmo; + private LineGizmo naviIndicatorGizmoStarmap; + + public void Dispose() + { + naviIndicatorGizmo = null; + naviIndicatorGizmoStarmap = null; + GC.SuppressFinalize(this); + } + + public void SetIndicatorPlayerId(ushort playerId) + { + indicatorPlayerId = playerId; + GameMain.mainPlayer.navigation.indicatorAstroId = 0; + GameMain.mainPlayer.navigation.indicatorMsgId = 0; + GameMain.mainPlayer.navigation.indicatorEnemyId = 0; + } + + public void SetIndicatorPing(int planetId, Vector3 pos) + { + indicatorPlanetId = planetId; + indicatorPos = pos; + GameMain.mainPlayer.navigation.indicatorAstroId = 0; + GameMain.mainPlayer.navigation.indicatorMsgId = 0; + GameMain.mainPlayer.navigation.indicatorEnemyId = 0; + } + + public void OnUpdate() + { + UpdateIndicator(); + } + + private void UpdateIndicator() + { + if (GameMain.mainPlayer.gizmo.naviIndicatorGizmo != null + && naviIndicatorGizmo != null) // When main player is navigating to other target, close the exisitng one + { + indicatorPlayerId = 0; + indicatorPlanetId = 0; + } + + if (indicatorPlayerId != 0 && Multiplayer.Session.Combat.IndexByPlayerId.TryGetValue(indicatorPlayerId, out var index)) + { + ref var ptr = ref Multiplayer.Session.Combat.Players[index]; + UpdateNavigationGizmo(ptr.planetId, ptr.skillTargetL, ptr.skillTargetU); + return; + } + + var planet = GameMain.galaxy.PlanetById(indicatorPlanetId); + if (indicatorPlanetId != 0 && planet != null) + { + UpdateNavigationGizmo(indicatorPlanetId, indicatorPos, planet.uPosition); + return; + } + + // Close gizmos if there is no vaild target + indicatorPlayerId = 0; + indicatorPlanetId = 0; + if (naviIndicatorGizmoStarmap != null) + { + naviIndicatorGizmoStarmap.gameObject.layer = 0; + naviIndicatorGizmoStarmap.Close(); + naviIndicatorGizmoStarmap = null; + } + if (naviIndicatorGizmo != null) + { + naviIndicatorGizmo.Close(); + naviIndicatorGizmo = null; + } + } + + private void UpdateNavigationGizmo(int planetId, in Vector3 lpos, in VectorLF3 upos) + { + var gizmo = GameMain.mainPlayer.gizmo; + if (naviIndicatorGizmo == null) + { + naviIndicatorGizmo = LineGizmo.Create(1, gizmo.player.position, lpos); + naviIndicatorGizmo.autoRefresh = true; + naviIndicatorGizmo.multiplier = 1.5f; + naviIndicatorGizmo.alphaMultiplier = 0.6f; + naviIndicatorGizmo.width = 1.8f; + naviIndicatorGizmo.color = Configs.builtin.gizmoColors[4]; + naviIndicatorGizmo.Open(); + } + if (naviIndicatorGizmoStarmap == null) + { + naviIndicatorGizmoStarmap = LineGizmo.Create(1, gizmo.player.position, lpos); + naviIndicatorGizmoStarmap.autoRefresh = true; + naviIndicatorGizmoStarmap.multiplier = 1.5f; + naviIndicatorGizmoStarmap.alphaMultiplier = 0.3f; + naviIndicatorGizmoStarmap.width = 0.01f; + naviIndicatorGizmoStarmap.color = Configs.builtin.gizmoColors[4]; + naviIndicatorGizmoStarmap.Open(); + } + + if (gizmo.player.planetId == planetId) + { + naviIndicatorGizmo.spherical = true; + naviIndicatorGizmo.startPoint = gizmo.player.mecha.skillTargetLCenter; + naviIndicatorGizmo.endPoint = lpos; + } + else + { + naviIndicatorGizmo.spherical = false; + naviIndicatorGizmo.startPoint = gizmo.player.position; + naviIndicatorGizmo.endPoint = lpos; + } + + var starmap = UIRoot.instance.uiGame.starmap; + naviIndicatorGizmoStarmap.startPoint = (gizmo.player.uPosition - starmap.viewTargetUPos) * 0.00025; + naviIndicatorGizmoStarmap.endPoint = (upos - starmap.viewTargetUPos) * 0.00025; + naviIndicatorGizmoStarmap.gameObject.layer = 20; + } +} From 18e9f84c790840cbf00f4ad216b73568539c05f7 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:27:04 +0800 Subject: [PATCH 2/8] Add IChatLinkHandler.OnRightClick --- NebulaWorld/Chat/ChatLinks/CopyTextChatLinkHandler.cs | 5 +++++ NebulaWorld/Chat/ChatLinks/IChatLinkHandler.cs | 2 ++ NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs | 4 ++++ NebulaWorld/Chat/ChatLinks/SignalChatLinkHandler.cs | 4 ++++ NebulaWorld/MonoBehaviours/Local/Chat/ChatLinkTrigger.cs | 4 ++++ 5 files changed, 19 insertions(+) diff --git a/NebulaWorld/Chat/ChatLinks/CopyTextChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/CopyTextChatLinkHandler.cs index b2363b725..28725743e 100644 --- a/NebulaWorld/Chat/ChatLinks/CopyTextChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/CopyTextChatLinkHandler.cs @@ -19,6 +19,11 @@ public void OnClick(string data) GUIUtility.systemCopyBuffer = data; } + public void OnRightClick(string data) + { + OnClick(data); + } + public void OnHover(string data, ChatLinkTrigger trigger, ref MonoBehaviour tipObject) { if (!string.IsNullOrEmpty(data)) diff --git a/NebulaWorld/Chat/ChatLinks/IChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/IChatLinkHandler.cs index af1aa409b..a627a7609 100644 --- a/NebulaWorld/Chat/ChatLinks/IChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/IChatLinkHandler.cs @@ -11,6 +11,8 @@ public interface IChatLinkHandler { void OnClick(string data); + void OnRightClick(string data); + void OnHover(string data, ChatLinkTrigger trigger, ref MonoBehaviour tipObject); string GetIconName(string data); diff --git a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs index 8469e0c85..165d3e563 100644 --- a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs @@ -27,6 +27,10 @@ public void OnClick(string data) } } + public void OnRightClick(string data) + { + } + public void OnHover(string data, ChatLinkTrigger trigger, ref MonoBehaviour tipObject) { if (!string.IsNullOrEmpty(data)) diff --git a/NebulaWorld/Chat/ChatLinks/SignalChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/SignalChatLinkHandler.cs index a961faa2b..89ef1416e 100644 --- a/NebulaWorld/Chat/ChatLinks/SignalChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/SignalChatLinkHandler.cs @@ -18,6 +18,10 @@ public void OnClick(string data) { } + public void OnRightClick(string data) + { + } + public void OnHover(string data, ChatLinkTrigger trigger, ref MonoBehaviour tipObject) { var signalId = GetSignalId(data); diff --git a/NebulaWorld/MonoBehaviours/Local/Chat/ChatLinkTrigger.cs b/NebulaWorld/MonoBehaviours/Local/Chat/ChatLinkTrigger.cs index 95248fd2f..5f82a0fdb 100644 --- a/NebulaWorld/MonoBehaviours/Local/Chat/ChatLinkTrigger.cs +++ b/NebulaWorld/MonoBehaviours/Local/Chat/ChatLinkTrigger.cs @@ -70,6 +70,10 @@ private void Update() { handler.OnClick(linkData); } + if (Input.GetMouseButtonDown(1)) + { + handler.OnRightClick(linkData); + } } else { 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 3/8] 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; From 031e9c668a2c0724860338935eb168598c7f9bd5 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:24:22 +0800 Subject: [PATCH 4/8] Add map ping (Ctrl + Alt + LeftClick) to mark position in chat --- .../Patches/Dynamic/GameCamera_Patch.cs | 79 +++++++-- .../Chat/ChatLinks/NavigateChatLinkHandler.cs | 104 +++++++++++- NebulaWorld/Chat/RichChatLinkRegistry.cs | 4 +- .../MonoBehaviours/Local/Chat/ChatManager.cs | 11 ++ .../MonoBehaviours/Local/Chat/ChatWindow.cs | 8 + .../Remote/RemotePlayerMovement.cs | 1 + NebulaWorld/Player/GizmoManager.cs | 156 ++++++++++++++++-- NebulaWorld/SimulatedWorld.cs | 4 +- 8 files changed, 334 insertions(+), 33 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs index 4acef5a87..37a76cfda 100644 --- a/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameCamera_Patch.cs @@ -5,6 +5,7 @@ using NebulaWorld; using NebulaWorld.GameStates; using NebulaWorld.MonoBehaviours.Local.Chat; +using UnityEngine; #endregion @@ -28,14 +29,14 @@ public static void Logic_Postfix(GameCamera __instance) if (!Multiplayer.IsActive || GameStatesManager.DuringReconnect) return; var observingPlayerId = Multiplayer.Session.Gizmos.ObservingPlayerId; - if (observingPlayerId == 0) return; + var observingPlanetId = Multiplayer.Session.Gizmos.ObservingPlanetId; + if (observingPlayerId == 0 && observingPlanetId == 0) return; if (VFInput.escape) { Multiplayer.Session.Gizmos.ObservingPlayerId = 0; - ChatManager.Instance.SendChatMessage( - "Exit tracking mode".Translate(), - ChatMessageType.CommandOutputMessage); + Multiplayer.Session.Gizmos.ObservingPlanetId = 0; + VFInput.UseEscape(); return; } @@ -43,6 +44,10 @@ public static void Logic_Postfix(GameCamera __instance) { TrackingPlayer(__instance, observingPlayerId); } + if (observingPlanetId > 0) + { + TrakcingPlanetPos(__instance, observingPlanetId, Multiplayer.Session.Gizmos.ObservingPos); + } } private static void TrackingPlayer(GameCamera cam, ushort playerId) @@ -51,23 +56,67 @@ private static void TrackingPlayer(GameCamera cam, ushort playerId) { 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; + StopTrackingPlayer(string.Format("Can't find player {0}".Translate(), playerId)); return; } - var planetId = model.PlayerInstance.planetId; + var planetId = model.Movement.localPlanetId; 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; + StopTrackingPlayer(string.Format("Player {0} is on a different planet".Translate(), playerId)); + return; + } + var starId = model.Movement.LocalStarId; + if (planetId == 0 && (starId <= 0 || starId != GameMain.localStar?.id)) + { + StopTrackingPlayer(string.Format("Player {0} is too far away".Translate(), playerId)); return; } - cam.rtsTarget.position = model.PlayerTransform.position; - cam.rtsTarget.eulerAngles = Maths.SphericalRotation(cam.rtsTarget.position, 0f).eulerAngles; + if (GameMain.mainPlayer.planetId > 0) + { + if (planetId == 0 && Multiplayer.Session.IsClient) + { + StopTrackingPlayer(string.Format("Player {0} is too far away".Translate(), playerId)); + return; + } + // The local player is on the planet and viewing another player on the same planet or in space + cam.rtsTarget.position = model.PlayerTransform.position; + cam.rtsTarget.eulerAngles = Maths.SphericalRotation(cam.rtsTarget.position, 0f).eulerAngles; + } + else + { + // Both players are in space + StopTrackingPlayer(string.Format("Player {0} is too far away".Translate(), playerId)); + } } } + + private static void StopTrackingPlayer(string text) + { + ChatManager.Instance.SendChatMessage(text, ChatMessageType.CommandOutputMessage); + Multiplayer.Session.Gizmos.ObservingPlayerId = 0; + } + + private static void TrakcingPlanetPos(GameCamera cam, int planetId, Vector3 pos) + { + if (planetId > 0 && planetId != GameMain.mainPlayer.planetId) + { + var planet = GameMain.galaxy.PlanetById(planetId); + if (planet != null) + { + UIRoot.instance.uiGame.OpenStarmap(); + var map = UIRoot.instance.uiGame.starmap; + var starIdx = planetId / 100 - 1; + map.focusStar = map.starUIs[starIdx]; + map.focusPlanet = null; + map.OnCursorFunction2Click(0); + map.screenCameraController.SetViewTarget(planet, null, null, null, VectorLF3.zero, + planet.realRadius * 0.00025 * 6.0, planet.realRadius * 0.00025 * 160.0, true, false); + } + Multiplayer.Session.Gizmos.ObservingPlanetId = 0; + return; + } + cam.rtsTarget.position = pos; + cam.rtsTarget.eulerAngles = Maths.SphericalRotation(pos, 0f).eulerAngles; + + } } diff --git a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs index 76aaa849a..1f91d6c62 100644 --- a/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs +++ b/NebulaWorld/Chat/ChatLinks/NavigateChatLinkHandler.cs @@ -1,6 +1,5 @@ #region -using System.Linq; using NebulaModel.DataStructures.Chat; using NebulaWorld.MonoBehaviours.Local.Chat; using UnityEngine; @@ -21,21 +20,90 @@ public void OnClick(string data) case 2: // PlayerId if (!ushort.TryParse(substrings[0], out var playerId)) return; Multiplayer.Session.Gizmos.SetIndicatorPlayerId(playerId); - ChatManager.Instance.SendChatMessage("Starting navigation to ".Translate() + substrings[1], + ChatManager.Instance.SendChatMessage("Navigate to ".Translate() + substrings[1], ChatMessageType.CommandOutputMessage); break; + + case 3: // AstroId + if (!int.TryParse(substrings[0], out var astroId)) return; + if (astroId < 0) return; + + // Clear the guide line if choosing the same target + var previousAstro = GameMain.mainPlayer.navigation.indicatorAstroId; + GameMain.mainPlayer.navigation.indicatorAstroId = previousAstro != astroId ? astroId : 0; + break; + + case 5: // PlanetPos + if (!TryParsePlanetPos(substrings, out var planetId, out var pos)) return; + Multiplayer.Session.Gizmos.SetIndicatorPing(planetId, pos); + break; } } public void OnRightClick(string data) { + var gizmoManager = Multiplayer.Session.Gizmos; 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(), + if (gizmoManager.ObservingPlayerId == playerId) + { + gizmoManager.ObservingPlayerId = 0; + return; + } + gizmoManager.ObservingPlayerId = playerId; + ChatManager.Instance.SendChatMessage("Tracking mode (ESC or click again to exit)".Translate(), + ChatMessageType.CommandOutputMessage); + break; + + case 3: // AstroId + if (!int.TryParse(substrings[0], out var astorId)) return; + if (astorId <= 0) return; + + // Open the starmap and focus on the target + UIRoot.instance.uiGame.OpenStarmap(); + var starmap = UIRoot.instance.uiGame.starmap; + var planet = GameMain.galaxy.PlanetById(astorId); + var star = GameMain.galaxy.StarById(astorId / 100); + if (planet != null) + { + var starIdx = astorId / 100 - 1; + starmap.focusStar = starmap.starUIs[starIdx]; + starmap.focusPlanet = null; + starmap.OnCursorFunction2Click(0); + starmap.screenCameraController.SetViewTarget(planet, null, null, null, VectorLF3.zero, + planet.realRadius * 0.00025 * 6.0, planet.realRadius * 0.00025 * 160.0, true, false); + } + else if (star != null) + { + var starIdx = astorId / 100 - 1; + starmap.focusPlanet = null; + starmap.focusStar = starmap.starUIs[starIdx]; + starmap.OnCursorFunction2Click(0); + } + return; + + case 5: // PlanetPos + if (!TryParsePlanetPos(substrings, out var planetId, out var pos)) return; + if (gizmoManager.ObservingPlanetId == planetId && gizmoManager.ObservingPos == pos) + { + gizmoManager.ObservingPlanetId = 0; + return; + } + gizmoManager.ObservingPlanetId = planetId; + gizmoManager.ObservingPos = pos; + if (GameCamera.instance.planetMode && planetId == GameMain.localPlanet?.id) + { + // In planet view, move the camera to aim at the target + var toRotate = Quaternion.FromToRotation(Vector3.up, pos); + var vector = toRotate * Vector3.up; + var normalized = Vector3.Cross(vector, Vector3.up).normalized; + toRotate = Quaternion.LookRotation(Vector3.Cross(normalized, vector), vector); + GameCamera.instance.planetPoser.rotationWanted = toRotate; + } + ChatManager.Instance.SendChatMessage("Tracking mode (ESC or click again to exit)".Translate(), ChatMessageType.CommandOutputMessage); break; } @@ -109,4 +177,32 @@ public static string FormatNavigateToPlayerString(ushort playerId, string displa var data = playerId + SplitSeparator.ToString() + displayString; return FormatNavigateString(data); } + + public static string FormatNavigateToAstro(int astroId, string displayString) + { + var data = astroId + SplitSeparator.ToString() + + "astroId" + SplitSeparator.ToString() + displayString; + return FormatNavigateString(data); + } + + public static string FormatNavigateToPlanetPos(int planetId, Vector3 pos, string displayString) + { + var data = planetId + SplitSeparator.ToString() + + pos.x + SplitSeparator.ToString() + pos.y + SplitSeparator.ToString() + pos.z + SplitSeparator.ToString() + + displayString; + return FormatNavigateString(data); + } + + private static bool TryParsePlanetPos(string[] substrings, out int planetId, out Vector3 pos) + { + planetId = 0; + pos = Vector3.zero; + if (substrings.Length != 5) return false; + if (!int.TryParse(substrings[0], out planetId)) return false; + if (!float.TryParse(substrings[1], out var x)) return false; + if (!float.TryParse(substrings[2], out var y)) return false; + if (!float.TryParse(substrings[3], out var z)) return false; + pos = new Vector3(x, y, z); + return true; + } } diff --git a/NebulaWorld/Chat/RichChatLinkRegistry.cs b/NebulaWorld/Chat/RichChatLinkRegistry.cs index 4e4713fa2..b6743c8a9 100644 --- a/NebulaWorld/Chat/RichChatLinkRegistry.cs +++ b/NebulaWorld/Chat/RichChatLinkRegistry.cs @@ -40,12 +40,12 @@ public static string ParseRichText(string linkString, out string linkData) { linkData = ""; var splitStrings = linkString.Split(' '); - if (splitStrings.Length != 2) + if (splitStrings.Length < 2) { return ""; } - linkData = splitStrings[1]; + linkData = linkString.Substring(splitStrings[0].Length + 1); return splitStrings[0]; } diff --git a/NebulaWorld/MonoBehaviours/Local/Chat/ChatManager.cs b/NebulaWorld/MonoBehaviours/Local/Chat/ChatManager.cs index 04bc4dd08..d414ac332 100644 --- a/NebulaWorld/MonoBehaviours/Local/Chat/ChatManager.cs +++ b/NebulaWorld/MonoBehaviours/Local/Chat/ChatManager.cs @@ -147,6 +147,17 @@ public void SendChatMessage(string text, ChatMessageType messageType) chatWindow.SendLocalChatMessage(text, messageType); } + public void InsetTextToChatbox(string text, bool forceOpenChatWindow) + { + if (chatWindow == null) return; + if (!chatWindow.IsActive) + { + if (!forceOpenChatWindow) return; + chatWindow.Toggle(); + } + chatWindow.InsertText(text); + } + public bool IsPointerIn() { return chatWindow.DragTrigger.pointerIn; diff --git a/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs b/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs index dfddf42f8..4f3a7553a 100644 --- a/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs +++ b/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs @@ -36,6 +36,7 @@ public class ChatWindow : MonoBehaviour internal string UserName; + public bool IsActive { get; private set; } private void Awake() @@ -283,6 +284,7 @@ public void Toggle(bool forceClosed = false, bool focusField = true) var desiredStatus = !forceClosed && !chatWindow.activeSelf; chatWindow.SetActive(desiredStatus); notifier.gameObject.SetActive(!desiredStatus); + IsActive = desiredStatus; if (chatWindow.activeSelf) { // when the window is activated we assume user wants to type right away @@ -323,6 +325,12 @@ public void InsertSprite() }); } + public void InsertText(string richText) + { + chatBox.Insert(richText); + FocusInputField(); + } + public QueuedMessage GetQueuedMessage() { return outgoingMessages.Count > 0 ? outgoingMessages.Dequeue() : null; diff --git a/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs b/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs index 546c409fd..a2e8d9fda 100644 --- a/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs +++ b/NebulaWorld/MonoBehaviours/Remote/RemotePlayerMovement.cs @@ -202,6 +202,7 @@ private void MoveInterpolated(Snapshot previous, Snapshot current, float ratio) var currentAbsolutePosition = GetAbsolutePosition(current); localPlanetId = current.LocalPlanetId; + if (current.LocalPlanetId > 0) LocalStarId = current.LocalPlanetId / 100; rootTransform.SetPositionAndRotation(Vector3.Lerp(previousRelativePosition, currentRelativePosition, ratio), Quaternion.Slerp(previous.Rotation, current.Rotation, ratio)); diff --git a/NebulaWorld/Player/GizmoManager.cs b/NebulaWorld/Player/GizmoManager.cs index 9ba83e9bb..82045aa48 100644 --- a/NebulaWorld/Player/GizmoManager.cs +++ b/NebulaWorld/Player/GizmoManager.cs @@ -1,12 +1,10 @@ #region using System; -using System.Collections.Generic; -using NebulaAPI.DataStructures; -using NebulaModel.DataStructures; -using NebulaModel.Packets.Players; +using System.Text; +using NebulaWorld.Chat.ChatLinks; +using NebulaWorld.MonoBehaviours.Local.Chat; using UnityEngine; -using Random = UnityEngine.Random; #pragma warning disable IDE1006 // Naming Styles #endregion @@ -16,23 +14,37 @@ namespace NebulaWorld.Player; public class GizmoManager : IDisposable { public ushort ObservingPlayerId { get; set; } + public int ObservingPlanetId { get; set; } + public Vector3 ObservingPos { get; set; } private ushort indicatorPlayerId; private int indicatorPlanetId; private Vector3 indicatorPos; private LineGizmo naviIndicatorGizmo; private LineGizmo naviIndicatorGizmoStarmap; + private CircleGizmo targetGizmo0; + private CircleGizmo targetGizmo1; public void Dispose() { naviIndicatorGizmo = null; naviIndicatorGizmoStarmap = null; + targetGizmo0 = null; + targetGizmo1 = null; GC.SuppressFinalize(this); } public void SetIndicatorPlayerId(ushort playerId) { + CloseTargetGizmos(); + if (indicatorPlayerId == playerId) + { + indicatorPlayerId = 0; + return; + } indicatorPlayerId = playerId; + + indicatorPlanetId = 0; GameMain.mainPlayer.navigation.indicatorAstroId = 0; GameMain.mainPlayer.navigation.indicatorMsgId = 0; GameMain.mainPlayer.navigation.indicatorEnemyId = 0; @@ -40,8 +52,16 @@ public void SetIndicatorPlayerId(ushort playerId) public void SetIndicatorPing(int planetId, Vector3 pos) { + CloseTargetGizmos(); + if (indicatorPlanetId == planetId) + { + indicatorPlanetId = 0; + return; + } indicatorPlanetId = planetId; indicatorPos = pos; + + indicatorPlayerId = 0; GameMain.mainPlayer.navigation.indicatorAstroId = 0; GameMain.mainPlayer.navigation.indicatorMsgId = 0; GameMain.mainPlayer.navigation.indicatorEnemyId = 0; @@ -49,9 +69,62 @@ public void SetIndicatorPing(int planetId, Vector3 pos) public void OnUpdate() { + if (VFInput.alt && VFInput.control && Input.GetMouseButtonDown(0)) GetMapPing(); UpdateIndicator(); } + private static void GetMapPing() + { + // Modify from UIGlobemap.TeleportLogic + if (Camera.main == null || GameMain.localPlanet == null) return; + if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var hitInfo, 800f, 8720, QueryTriggerInteraction.Collide)) return; + + var starmap = UIRoot.instance.uiGame.starmap; + if (starmap.active) + { + // In starmap view, get the focusing planet or star (OnCursorFunction3Click) + int astroId; + string displayString; + if (starmap.focusPlanet != null) + { + astroId = starmap.focusPlanet.planet.id; + displayString = starmap.focusPlanet.planet.displayName; + } + else if (starmap.focusStar != null) + { + astroId = starmap.focusStar.star.astroId; + displayString = starmap.focusStar.star.displayName; + } + else if (starmap.focusHive != null) + { + astroId = starmap.focusHive.hive.hiveAstroId; + displayString = starmap.focusHive.hive.displayName; + } + else + { + return; + } + ChatManager.Instance.InsetTextToChatbox(NavigateChatLinkHandler.FormatNavigateToAstro(astroId, displayString), false); + return; + } + + Maths.GetLatitudeLongitude(hitInfo.point, out var latd, out _, out var logd, out _, + out var north, out _, out _, out var east); + + var stringBuilder = new StringBuilder(); + stringBuilder.Append(GameMain.localPlanet.displayName); + stringBuilder.Append(' '); + stringBuilder.Append(north == true ? 'N' : 'S'); + stringBuilder.Append(latd); + stringBuilder.Append('°'); + stringBuilder.Append(east == true ? 'E' : 'W'); + stringBuilder.Append(logd); + stringBuilder.Append('°'); + + var str = NavigateChatLinkHandler.FormatNavigateToPlanetPos(GameMain.localPlanet.id, hitInfo.point, stringBuilder.ToString()); + ChatManager.Instance.InsetTextToChatbox(str, false); + } + private void UpdateIndicator() { if (GameMain.mainPlayer.gizmo.naviIndicatorGizmo != null @@ -71,7 +144,18 @@ private void UpdateIndicator() var planet = GameMain.galaxy.PlanetById(indicatorPlanetId); if (indicatorPlanetId != 0 && planet != null) { - UpdateNavigationGizmo(indicatorPlanetId, indicatorPos, planet.uPosition); + if (planet == GameMain.localPlanet) + { + UpdateNavigationGizmo(indicatorPlanetId, indicatorPos, planet.uPosition); + CreateTargetGizmos(indicatorPos); + } + else + { + // Convert position on planet to world position + var pos = Maths.QInvRotateLF(GameMain.data.relativeRot, planet.uPosition - GameMain.data.relativePos); + UpdateNavigationGizmo(indicatorPlanetId, pos + (VectorLF3)indicatorPos, planet.uPosition); + CloseTargetGizmos(); + } return; } @@ -89,6 +173,7 @@ private void UpdateIndicator() naviIndicatorGizmo.Close(); naviIndicatorGizmo = null; } + CloseTargetGizmos(); } private void UpdateNavigationGizmo(int planetId, in Vector3 lpos, in VectorLF3 upos) @@ -96,10 +181,10 @@ private void UpdateNavigationGizmo(int planetId, in Vector3 lpos, in VectorLF3 u var gizmo = GameMain.mainPlayer.gizmo; if (naviIndicatorGizmo == null) { - naviIndicatorGizmo = LineGizmo.Create(1, gizmo.player.position, lpos); + naviIndicatorGizmo = LineGizmo.Create(1, gizmo.player.mecha.skillTargetLCenter, lpos); naviIndicatorGizmo.autoRefresh = true; naviIndicatorGizmo.multiplier = 1.5f; - naviIndicatorGizmo.alphaMultiplier = 0.6f; + naviIndicatorGizmo.alphaMultiplier = 1.0f; naviIndicatorGizmo.width = 1.8f; naviIndicatorGizmo.color = Configs.builtin.gizmoColors[4]; naviIndicatorGizmo.Open(); @@ -109,17 +194,23 @@ private void UpdateNavigationGizmo(int planetId, in Vector3 lpos, in VectorLF3 u naviIndicatorGizmoStarmap = LineGizmo.Create(1, gizmo.player.position, lpos); naviIndicatorGizmoStarmap.autoRefresh = true; naviIndicatorGizmoStarmap.multiplier = 1.5f; - naviIndicatorGizmoStarmap.alphaMultiplier = 0.3f; - naviIndicatorGizmoStarmap.width = 0.01f; + naviIndicatorGizmoStarmap.alphaMultiplier = 0.6f; + naviIndicatorGizmoStarmap.width = 0.03f; naviIndicatorGizmoStarmap.color = Configs.builtin.gizmoColors[4]; + naviIndicatorGizmoStarmap.spherical = false; naviIndicatorGizmoStarmap.Open(); } - if (gizmo.player.planetId == planetId) + if (planetId > 0 && gizmo.player.planetId == planetId) { naviIndicatorGizmo.spherical = true; naviIndicatorGizmo.startPoint = gizmo.player.mecha.skillTargetLCenter; naviIndicatorGizmo.endPoint = lpos; + if (targetGizmo0 != null) + { + // In planet view, enlarge the target circle + targetGizmo0.radius = GameCamera.instance.planetMode ? 10f : 1f; + } } else { @@ -133,4 +224,47 @@ private void UpdateNavigationGizmo(int planetId, in Vector3 lpos, in VectorLF3 u naviIndicatorGizmoStarmap.endPoint = (upos - starmap.viewTargetUPos) * 0.00025; naviIndicatorGizmoStarmap.gameObject.layer = 20; } + + private void CreateTargetGizmos(Vector3 pos) + { + if (targetGizmo0 == null) + { + targetGizmo0 = CircleGizmo.Create(2, pos, 1f); + targetGizmo0.multiplier = 2f; + targetGizmo0.alphaMultiplier = 1.0f; + targetGizmo0.fadeInScale = 1.3f; + targetGizmo0.fadeInTime = 0.13f; + targetGizmo0.fadeInFalloff = 0.5f; + targetGizmo0.color = Configs.builtin.gizmoColors[2]; + targetGizmo0.rotateSpeed = 60f; + targetGizmo0.Open(); + } + + if (targetGizmo1 == null) + { + targetGizmo1 = CircleGizmo.Create(4, pos, 3f); + targetGizmo1.multiplier = 2f; + targetGizmo1.alphaMultiplier = 0.5f; + targetGizmo1.fadeInScale = 1.3f; + targetGizmo1.fadeInTime = 0.13f; + targetGizmo1.fadeInFalloff = 0.5f; + targetGizmo1.color = Configs.builtin.gizmoColors[2]; + targetGizmo1.rotateSpeed = 60f; + targetGizmo1.Open(); + } + } + + private void CloseTargetGizmos() + { + if (targetGizmo0 != null) + { + targetGizmo0.Close(); + targetGizmo0 = null; + } + if (targetGizmo1 != null) + { + targetGizmo1.Close(); + targetGizmo1 = null; + } + } } diff --git a/NebulaWorld/SimulatedWorld.cs b/NebulaWorld/SimulatedWorld.cs index f3c865654..b576dd470 100644 --- a/NebulaWorld/SimulatedWorld.cs +++ b/NebulaWorld/SimulatedWorld.cs @@ -162,7 +162,7 @@ public void SetupInitialPlayerState() Multiplayer.Session.Network.SendPacket(new SyncComplete(clientCert)); // Subscribe for the local star events - Multiplayer.Session.Network.SendPacket(new PlayerUpdateLocalStarId(Multiplayer.Session.LocalPlayer.Id, GameMain.data.localStar.id)); + Multiplayer.Session.Network.SendPacket(new PlayerUpdateLocalStarId(Multiplayer.Session.LocalPlayer.Id, GameMain.data.localStar?.id ?? -1)); // Request latest warning signal Multiplayer.Session.Network.SendPacket(new WarningDataRequest(WarningRequestEvent.Signal)); @@ -286,6 +286,8 @@ public void SpawnRemotePlayerModel(IPlayerData playerData) } Log.Info($"Spawn player model {playerData.PlayerId} {playerData.Username}"); var model = new RemotePlayerModel(playerData.PlayerId, playerData.Username); + model.Movement.LocalStarId = playerData.LocalStarId; + model.Movement.localPlanetId = playerData.LocalPlanetId; remotePlayersModels.Add(playerData.PlayerId, model); // Show conneted message From 705414fa2a2941f64973a5d2f60a027b269ff2ab Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:03:32 +0800 Subject: [PATCH 5/8] Add config option EnableBattleMessage --- NebulaModel/DataStructures/Chat/ChatMessageType.cs | 9 +++++---- NebulaModel/MultiplayerOptions.cs | 4 ++++ NebulaModel/Utils/ChatUtils.cs | 3 +++ NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs | 1 + NebulaWorld/SimulatedWorld.cs | 9 ++------- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/NebulaModel/DataStructures/Chat/ChatMessageType.cs b/NebulaModel/DataStructures/Chat/ChatMessageType.cs index 9aa26e3ed..b56534615 100644 --- a/NebulaModel/DataStructures/Chat/ChatMessageType.cs +++ b/NebulaModel/DataStructures/Chat/ChatMessageType.cs @@ -5,8 +5,9 @@ public enum ChatMessageType PlayerMessage = 0, SystemInfoMessage = 1, SystemWarnMessage = 2, - CommandUsageMessage = 3, - CommandOutputMessage = 4, - CommandErrorMessage = 5, - PlayerMessagePrivate = 6 + BattleMessage = 3, + CommandUsageMessage = 4, + CommandOutputMessage = 5, + CommandErrorMessage = 6, + PlayerMessagePrivate = 7 } diff --git a/NebulaModel/MultiplayerOptions.cs b/NebulaModel/MultiplayerOptions.cs index 71180dc8a..b9eed4492 100644 --- a/NebulaModel/MultiplayerOptions.cs +++ b/NebulaModel/MultiplayerOptions.cs @@ -142,6 +142,10 @@ public bool StreamerMode [Category("Chat")] public bool EnableInfoMessage { get; set; } = true; + [DisplayName("Show battle notification message")] + [Category("Chat")] + public bool EnableBattleMessage { get; set; } = true; + [DisplayName("Default chat position")] [Category("Chat")] public ChatPosition DefaultChatPosition { get; set; } = ChatPosition.LeftMiddle; diff --git a/NebulaModel/Utils/ChatUtils.cs b/NebulaModel/Utils/ChatUtils.cs index fc75a0120..69f8b8f3d 100644 --- a/NebulaModel/Utils/ChatUtils.cs +++ b/NebulaModel/Utils/ChatUtils.cs @@ -98,6 +98,9 @@ public static Color GetMessageColor(ChatMessageType messageType) case ChatMessageType.SystemWarnMessage: return new Color(1, 0.95f, 0, 1); + case ChatMessageType.BattleMessage: + return Color.cyan; + case ChatMessageType.CommandUsageMessage: return new Color(1, 0.65f, 0, 1); diff --git a/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs b/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs index 4f3a7553a..820d8a8e3 100644 --- a/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs +++ b/NebulaWorld/MonoBehaviours/Local/Chat/ChatWindow.cs @@ -203,6 +203,7 @@ public ChatMessage SendLocalChatMessage(string text, ChatMessageType messageType { case ChatMessageType.SystemInfoMessage when !Config.Options.EnableInfoMessage: case ChatMessageType.SystemWarnMessage when !Config.Options.EnableWarnMessage: + case ChatMessageType.BattleMessage when !Config.Options.EnableBattleMessage: return null; case ChatMessageType.PlayerMessage: break; diff --git a/NebulaWorld/SimulatedWorld.cs b/NebulaWorld/SimulatedWorld.cs index b576dd470..7b5f89443 100644 --- a/NebulaWorld/SimulatedWorld.cs +++ b/NebulaWorld/SimulatedWorld.cs @@ -294,7 +294,7 @@ public void SpawnRemotePlayerModel(IPlayerData playerData) var planetname = GameMain.galaxy.PlanetById(playerData.LocalPlanetId)?.displayName ?? "In space"; var message = string.Format("[{0:HH:mm}] {1} connected ({2})".Translate(), DateTime.Now, playerData.Username, planetname); - SendChatMessage(message); + ChatManager.Instance.SendChatMessage(message, ChatMessageType.SystemInfoMessage); } } @@ -308,7 +308,7 @@ public void DestroyRemotePlayerModel(ushort playerId) } // Show disconnected message var message = string.Format("[{0:HH:mm}] {1} disconnected".Translate(), DateTime.Now, player.Username); - SendChatMessage(message); + ChatManager.Instance.SendChatMessage(message, ChatMessageType.SystemInfoMessage); player.Destroy(); remotePlayersModels.Remove(playerId); @@ -584,11 +584,6 @@ public static int GetUniverseObserveLevel() return level; } - private static void SendChatMessage(string text, ChatMessageType messageType = ChatMessageType.SystemInfoMessage) - { - ChatManager.Instance.SendChatMessage(text, messageType); - } - private sealed class ThreadSafe { internal readonly Dictionary RemotePlayersModels = new(); From 44df59a82b9dfcb987429391ec029d9233ca20ab Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:38:57 +0800 Subject: [PATCH 6/8] Add EnemyManager.DisplayPlanetPingMessage and DisplayAstroMessage --- .../DFTinder/DFTinderDispatchProcessor.cs | 2 + .../GroundEnemy/DFGLaunchAssaultProcessor.cs | 7 +- .../DFSLaunchLancerAssaultProcessor.cs | 1 + .../Patches/Dynamic/DFGBaseComponent_Patch.cs | 2 +- .../Patches/Dynamic/DFRelayComponent_Patch.cs | 23 ++++++ .../Dynamic/DFTinderComponent_Patch.cs | 1 + .../Dynamic/EnemyDFHiveSystem_Patch.cs | 2 + .../Patches/Dynamic/GameData_Patch.cs | 4 +- NebulaWorld/Combat/EnemyManager.cs | 72 ++++++++++++++----- 9 files changed, 93 insertions(+), 21 deletions(-) diff --git a/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs index 4b7b28e13..64d73618c 100644 --- a/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs @@ -18,6 +18,8 @@ protected override void ProcessPacket(DFTinderDispatchPacket packet, NebulaConne var hiveSystem = GameMain.spaceSector.GetHiveByAstroId(packet.OriginHiveAstroId); if (hiveSystem == null) return; + Multiplayer.Session.Enemies.DisplayAstroMessage("Dark Fog seed send out from".Translate(), hiveSystem.starData.astroId); + ref var tinderComponent = ref hiveSystem.tinders.buffer[packet.TinderId]; if (tinderComponent.id != packet.TinderId) return; diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs index 81ca718f6..5b65f7241 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs @@ -18,7 +18,12 @@ public class DFGLaunchAssaultProcessor : PacketProcessor protected override void ProcessPacket(DFGLaunchAssaultPacket packet, NebulaConnection conn) { var factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory; - if (factory == null) return; + if (factory == null) + { + // Display message in chat if it can't show in UIDarkFogMonitor + Multiplayer.Session.Enemies.DisplayPlanetPingMessage("Planetary base is attacking".Translate(), packet.PlanetId, packet.TarPos.ToVector3()); + return; + } using (Multiplayer.Session.Combat.IsIncomingRequest.On()) { diff --git a/NebulaNetwork/PacketProcessors/Combat/SpaceEnemy/DFSLaunchLancerAssaultProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/SpaceEnemy/DFSLaunchLancerAssaultProcessor.cs index aa31e8fd4..629c4d04a 100644 --- a/NebulaNetwork/PacketProcessors/Combat/SpaceEnemy/DFSLaunchLancerAssaultProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/SpaceEnemy/DFSLaunchLancerAssaultProcessor.cs @@ -17,6 +17,7 @@ public class DFSLaunchLancerAssaultProcessor : PacketProcessor 0) + { + Multiplayer.Session.Enemies.DisplayPlanetPingMessage("Relay lands on planet".Translate(), __instance.targetAstroId, __instance.targetLPos); + } + } + [HarmonyPrefix] [HarmonyPatch(nameof(DFRelayComponent.ArriveDock))] public static bool ArriveDock_Prefix(DFRelayComponent __instance) @@ -49,6 +62,16 @@ public static bool ArriveDock_Prefix(DFRelayComponent __instance) public static bool LeaveBase_Prefix(DFRelayComponent __instance) { if (!Multiplayer.IsActive) return true; + + if (Multiplayer.Session.IsServer || Multiplayer.Session.Enemies.IsIncomingRelayRequest) + { + var planet = GameMain.galaxy.PlanetById(__instance.targetAstroId); + if (planet != null) + { + Multiplayer.Session.Enemies.DisplayPlanetPingMessage("Relay leaves from planet", __instance.targetAstroId, __instance.targetLPos); + } + } + if (Multiplayer.Session.IsClient) return Multiplayer.Session.Enemies.IsIncomingRelayRequest; Multiplayer.Session.Network.SendPacket(new DFRelayLeaveBasePacket(__instance)); diff --git a/NebulaPatcher/Patches/Dynamic/DFTinderComponent_Patch.cs b/NebulaPatcher/Patches/Dynamic/DFTinderComponent_Patch.cs index 2308d7301..6a4e8db4f 100644 --- a/NebulaPatcher/Patches/Dynamic/DFTinderComponent_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/DFTinderComponent_Patch.cs @@ -24,6 +24,7 @@ public static bool DispatchFromHive_Prefix(ref DFTinderComponent __instance, int { __instance.targetHiveAstroId = _targetHiveAstroId; Multiplayer.Session.Network.SendPacket(new DFTinderDispatchPacket(__instance)); + Multiplayer.Session.Enemies.DisplayAstroMessage("Dark Fog seed send out from".Translate(), hive1.starData.astroId); } return true; } diff --git a/NebulaPatcher/Patches/Dynamic/EnemyDFHiveSystem_Patch.cs b/NebulaPatcher/Patches/Dynamic/EnemyDFHiveSystem_Patch.cs index 9cff73351..b90350b09 100644 --- a/NebulaPatcher/Patches/Dynamic/EnemyDFHiveSystem_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/EnemyDFHiveSystem_Patch.cs @@ -2,6 +2,7 @@ using System; using HarmonyLib; +using NebulaAPI.DataStructures; using NebulaModel.Packets.Combat.DFHive; using NebulaModel.Packets.Combat.SpaceEnemy; using NebulaWorld; @@ -236,6 +237,7 @@ public static bool LaunchLancerAssault_Prefix(EnemyDFHiveSystem __instance, EAgg var packet = new DFSLaunchLancerAssaultPacket(in __instance, aggressiveLevel, in tarPos, in maxHatredPos, targetAstroId, unitCount0, unitThreat); Multiplayer.Session.Server.SendPacket(packet); + Multiplayer.Session.Enemies.DisplayAstroMessage("Space hive is attacking".Translate(), packet.TargetAstroId); return true; } diff --git a/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs b/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs index 802ad2e99..d27676b5d 100644 --- a/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/GameData_Patch.cs @@ -320,7 +320,6 @@ public static void GameTick_Postfix(GameData __instance, long time) Multiplayer.Session.Couriers.GameTick(); Multiplayer.Session.Belts.GameTick(); Multiplayer.Session.Combat.GameTick(); - Multiplayer.Session.Enemies.GameTick(time); if (Multiplayer.Session.LocalPlayer.IsHost) { @@ -426,8 +425,7 @@ public static void LeavePlanet_Prefix() { Multiplayer.Session.Trashes.Refresh(); Multiplayer.Session.PowerTowers.ResetAndBroadcast(); - //todo:replace - //GameMain.mainPlayer.mecha.droneLogic.serving.Clear(); + Multiplayer.Session.Enemies.OnLeavePlanet(); } } diff --git a/NebulaWorld/Combat/EnemyManager.cs b/NebulaWorld/Combat/EnemyManager.cs index 65db1d800..918b49d4d 100644 --- a/NebulaWorld/Combat/EnemyManager.cs +++ b/NebulaWorld/Combat/EnemyManager.cs @@ -3,9 +3,14 @@ using System; using System.Collections.Generic; using NebulaModel.DataStructures; +using NebulaModel.DataStructures.Chat; using NebulaModel.Packets.Combat.DFHive; using NebulaModel.Packets.Combat.GroundEnemy; +using NebulaWorld.Chat.ChatLinks; +using NebulaWorld.MonoBehaviours.Local.Chat; +using UnityEngine; #pragma warning disable IDE1006 // Naming Styles +#pragma warning disable CA1822 // Mark members as static #endregion @@ -17,19 +22,13 @@ public class EnemyManager : IDisposable public readonly ToggleSwitch IsIncomingRelayRequest = new(); - public readonly Dictionary GroundTargets = new(); + public readonly Dictionary GroundTargets = []; public const bool DISABLE_DFCommunicator = true; private readonly Dictionary basePackets = []; private readonly Dictionary hivePackets = []; - public EnemyManager() - { - GroundTargets.Clear(); - basePackets.Clear(); - hivePackets.Clear(); - } public void Dispose() { @@ -39,13 +38,6 @@ public void Dispose() GC.SuppressFinalize(this); } - public void GameTick(long gameTick) - { - if (!Multiplayer.Session.IsGameLoaded) return; - // Place holder for future - var _ = gameTick; - } - public void BroadcastBaseStatusPackets(EnemyDFGroundSystem enemySystem, long gameTick) { var factoryIndex = enemySystem.factory.index; @@ -62,9 +54,9 @@ public void BroadcastBaseStatusPackets(EnemyDFGroundSystem enemySystem, long gam basePackets.Add(hashId, packet); } var levelChanged = packet.Level != dFbase.evolve.level; - if (levelChanged || (hashId % 300) == (int)gameTick % 300) + if (levelChanged || (hashId % 120) == (int)gameTick % 120) { - // Update when base level changes, or every 5s + // Update when base level changes, or every 2s to players on that planet packet.Record(in dFbase); var planetId = enemySystem.planet.id; if (levelChanged) @@ -95,6 +87,33 @@ public void BroadcastHiveStatusPackets(EnemyDFHiveSystem hive, long gameTick) } } + public void DisplayPlanetPingMessage(string text, int planetId, Vector3 pos) + { + var planet = GameMain.galaxy.PlanetById(planetId); + if (planet == null) return; + + var message = text + " [" + NavigateChatLinkHandler.FormatNavigateToPlanetPos(planetId, pos, planet.displayName) + "]"; + ChatManager.Instance.SendChatMessage(message, ChatMessageType.BattleMessage); + } + + public void DisplayAstroMessage(string text, int astroId) + { + string displayMessage = null; + + if (GameMain.galaxy.PlanetById(astroId) != null) + { + displayMessage = GameMain.galaxy.PlanetById(astroId).displayName; + } + else if (GameMain.galaxy.StarById(astroId / 100) != null) + { + displayMessage = GameMain.galaxy.StarById(astroId / 100).displayName; + } + if (displayMessage == null) return; + + var message = text + " [" + NavigateChatLinkHandler.FormatNavigateToAstro(astroId, displayMessage) + "]"; + ChatManager.Instance.SendChatMessage(message, ChatMessageType.BattleMessage); + } + public void OnFactoryLoadFinished(PlanetFactory factory) { var planetId = factory.planetId; @@ -111,6 +130,27 @@ public void OnFactoryLoadFinished(PlanetFactory factory) } } + public void OnLeavePlanet() + { + if (Multiplayer.Session.IsServer) return; + + // Reset threat on each base on the loaded factory so it doesn't show on the monitor + for (var factoryIdx = 0; factoryIdx < GameMain.data.factoryCount; factoryIdx++) + { + var factory = GameMain.data.factories[factoryIdx]; + if (factory == null) continue; + + var bases = factory.enemySystem.bases; + for (var baseId = 1; baseId < bases.cursor; baseId++) + { + if (bases[baseId] != null && bases[baseId].id == baseId && !bases[baseId].hasAssaultingUnit) + { + bases[baseId].evolve.threat = 0; + } + } + } + } + public static void SetPlanetFactoryNextEnemyId(PlanetFactory factory, int enemyId) { if (enemyId >= factory.enemyCursor) From 4185b6324db728bf64e91a52b17ad1a93cc53686 Mon Sep 17 00:00:00 2001 From: starfi5h <50672801+starfi5h@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:37:26 +0800 Subject: [PATCH 7/8] Apply suggestions from code review Co-authored-by: Chris Yeninas <844685+PhantomGamers@users.noreply.github.com> --- NebulaWorld/Player/GizmoManager.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/NebulaWorld/Player/GizmoManager.cs b/NebulaWorld/Player/GizmoManager.cs index 82045aa48..c028c50d7 100644 --- a/NebulaWorld/Player/GizmoManager.cs +++ b/NebulaWorld/Player/GizmoManager.cs @@ -75,8 +75,10 @@ public void OnUpdate() private static void GetMapPing() { - // Modify from UIGlobemap.TeleportLogic - if (Camera.main == null || GameMain.localPlanet == null) return; + // Modify from UIGlobemap.TeleportLogic + var mainCam = Camera.main; + if (mainCam == null || GameMain.localPlanet == null) return; + if (!Physics.Raycast(mainCam.ScreenPointToRay(Input.mousePosition), out var hitInfo, 800f, 8720, QueryTriggerInteraction.Collide)) return; if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var hitInfo, 800f, 8720, QueryTriggerInteraction.Collide)) return; var starmap = UIRoot.instance.uiGame.starmap; @@ -128,7 +130,7 @@ private static void GetMapPing() private void UpdateIndicator() { if (GameMain.mainPlayer.gizmo.naviIndicatorGizmo != null - && naviIndicatorGizmo != null) // When main player is navigating to other target, close the exisitng one + && naviIndicatorGizmo != null) // When main player is navigating to other target, close the existing one { indicatorPlayerId = 0; indicatorPlanetId = 0; @@ -159,7 +161,7 @@ private void UpdateIndicator() return; } - // Close gizmos if there is no vaild target + // Close gizmos if there is no valid target indicatorPlayerId = 0; indicatorPlanetId = 0; if (naviIndicatorGizmoStarmap != null) From 85b1c39c39fa58c5eb192244c077150fc4a77839 Mon Sep 17 00:00:00 2001 From: starfish <50672801+starfi5h@users.noreply.github.com> Date: Sun, 10 Mar 2024 14:43:24 +0800 Subject: [PATCH 8/8] Update battle messages --- .../Combat/DFTinder/DFTinderDispatchProcessor.cs | 2 +- NebulaPatcher/Patches/Dynamic/DFRelayComponent_Patch.cs | 4 ++-- NebulaWorld/Player/GizmoManager.cs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs index 64d73618c..6cdfeb192 100644 --- a/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/DFTinder/DFTinderDispatchProcessor.cs @@ -18,7 +18,7 @@ protected override void ProcessPacket(DFTinderDispatchPacket packet, NebulaConne var hiveSystem = GameMain.spaceSector.GetHiveByAstroId(packet.OriginHiveAstroId); if (hiveSystem == null) return; - Multiplayer.Session.Enemies.DisplayAstroMessage("Dark Fog seed send out from".Translate(), hiveSystem.starData.astroId); + Multiplayer.Session.Enemies.DisplayAstroMessage("DF seed sent out from".Translate(), hiveSystem.starData.astroId); ref var tinderComponent = ref hiveSystem.tinders.buffer[packet.TinderId]; if (tinderComponent.id != packet.TinderId) return; diff --git a/NebulaPatcher/Patches/Dynamic/DFRelayComponent_Patch.cs b/NebulaPatcher/Patches/Dynamic/DFRelayComponent_Patch.cs index 47bb6e5f5..8cdbca0a1 100644 --- a/NebulaPatcher/Patches/Dynamic/DFRelayComponent_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/DFRelayComponent_Patch.cs @@ -42,7 +42,7 @@ public static void ArriveBase_Postfix(DFRelayComponent __instance) var planet = GameMain.galaxy.PlanetById(__instance.targetAstroId); if (planet != null && __instance.baseId > 0) { - Multiplayer.Session.Enemies.DisplayPlanetPingMessage("Relay lands on planet".Translate(), __instance.targetAstroId, __instance.targetLPos); + Multiplayer.Session.Enemies.DisplayPlanetPingMessage("DF relay landed on planet".Translate(), __instance.targetAstroId, __instance.targetLPos); } } @@ -68,7 +68,7 @@ public static bool LeaveBase_Prefix(DFRelayComponent __instance) var planet = GameMain.galaxy.PlanetById(__instance.targetAstroId); if (planet != null) { - Multiplayer.Session.Enemies.DisplayPlanetPingMessage("Relay leaves from planet", __instance.targetAstroId, __instance.targetLPos); + Multiplayer.Session.Enemies.DisplayPlanetPingMessage("DF relay left from planet", __instance.targetAstroId, __instance.targetLPos); } } diff --git a/NebulaWorld/Player/GizmoManager.cs b/NebulaWorld/Player/GizmoManager.cs index c028c50d7..ff74f6be2 100644 --- a/NebulaWorld/Player/GizmoManager.cs +++ b/NebulaWorld/Player/GizmoManager.cs @@ -75,11 +75,10 @@ public void OnUpdate() private static void GetMapPing() { - // Modify from UIGlobemap.TeleportLogic + // Modify from UIGlobemap.TeleportLogic var mainCam = Camera.main; if (mainCam == null || GameMain.localPlanet == null) return; if (!Physics.Raycast(mainCam.ScreenPointToRay(Input.mousePosition), out var hitInfo, 800f, 8720, QueryTriggerInteraction.Collide)) return; - if (!Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var hitInfo, 800f, 8720, QueryTriggerInteraction.Collide)) return; var starmap = UIRoot.instance.uiGame.starmap; if (starmap.active)