diff --git a/src/MultiplayerMod/Game/UI/Tools/Events/InterfaceToolEvents.cs b/src/MultiplayerMod/Game/UI/Tools/Events/InterfaceToolEvents.cs index a8311137..7147f7fb 100644 --- a/src/MultiplayerMod/Game/UI/Tools/Events/InterfaceToolEvents.cs +++ b/src/MultiplayerMod/Game/UI/Tools/Events/InterfaceToolEvents.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using HarmonyLib; +using JetBrains.Annotations; using MultiplayerMod.ModRuntime.Context; using UnityEngine; @@ -9,28 +10,35 @@ namespace MultiplayerMod.Game.UI.Tools.Events; [HarmonyPatch(typeof(InterfaceTool))] public static class InterfaceToolEvents { - public static event Action? MouseMoved; + public static event Action? MouseMoved; - // ReSharper disable once InconsistentNaming, UnusedMember.Local + // ReSharper disable once InconsistentNaming + [UsedImplicitly] [HarmonyPrefix] [HarmonyPatch(nameof(InterfaceTool.OnMouseMove))] [RequireExecutionLevel(ExecutionLevel.Game)] private static void OnMouseMove(Vector3 cursor_pos) { var kScreens = KScreenManager.Instance.screenStack.Where(screen => screen.mouseOver).ToList(); + var kScreen = kScreens.FirstOrDefault(); MouseMoved?.Invoke( - new Vector2(cursor_pos.x, cursor_pos.y), - GetScreenName(kScreens.FirstOrDefault()) + new MouseMovedEventArgs( + new Vector2(cursor_pos.x, cursor_pos.y), + GetScreenName(kScreen), + kScreen?.GetType() + ) ); } - private static string? GetScreenName(KScreen? screen) { - switch (screen) { - case TableScreen tableScreen: - return tableScreen.title.ToLower(); - case RootMenu rootMenu: - return rootMenu.detailsScreen.displayName; - default: - return screen?.displayName; - } - } + private static string? GetScreenName(KScreen? screen) => screen switch { + TableScreen tableScreen => tableScreen.title.ToLower(), + RootMenu rootMenu => rootMenu.detailsScreen.displayName, + _ => screen?.displayName + }; + + [Serializable] + public record MouseMovedEventArgs( + Vector2 Position, + string? ScreenName, + Type? ScreenType + ); } diff --git a/src/MultiplayerMod/Multiplayer/Commands/Player/UpdatePlayerCursorPosition.cs b/src/MultiplayerMod/Multiplayer/Commands/Player/UpdatePlayerCursorPosition.cs index 59f6617c..22b933e2 100644 --- a/src/MultiplayerMod/Multiplayer/Commands/Player/UpdatePlayerCursorPosition.cs +++ b/src/MultiplayerMod/Multiplayer/Commands/Player/UpdatePlayerCursorPosition.cs @@ -1,7 +1,7 @@ using System; +using MultiplayerMod.Game.UI.Tools.Events; using MultiplayerMod.Multiplayer.Players; using MultiplayerMod.Multiplayer.Players.Events; -using UnityEngine; namespace MultiplayerMod.Multiplayer.Commands.Player; @@ -9,18 +9,19 @@ namespace MultiplayerMod.Multiplayer.Commands.Player; public class UpdatePlayerCursorPosition : MultiplayerCommand { private PlayerIdentity playerId; - private Vector2 position; - private string? screenName; + private InterfaceToolEvents.MouseMovedEventArgs mouseMovedEventArgs; - public UpdatePlayerCursorPosition(PlayerIdentity playerId, Vector2 position, string? screenName) { + public UpdatePlayerCursorPosition( + PlayerIdentity playerId, + InterfaceToolEvents.MouseMovedEventArgs mouseMovedEventArgs + ) { this.playerId = playerId; - this.position = position; - this.screenName = screenName; + this.mouseMovedEventArgs = mouseMovedEventArgs; } public override void Execute(MultiplayerCommandContext context) { var player = context.Multiplayer.Players[playerId]; - context.EventDispatcher.Dispatch(new PlayerCursorPositionUpdatedEvent(player, position, screenName)); + context.EventDispatcher.Dispatch(new PlayerCursorPositionUpdatedEvent(player, mouseMovedEventArgs)); } } diff --git a/src/MultiplayerMod/Multiplayer/Components/CursorComponent.cs b/src/MultiplayerMod/Multiplayer/Components/CursorComponent.cs index 28f2edc4..fe3b7961 100644 --- a/src/MultiplayerMod/Multiplayer/Components/CursorComponent.cs +++ b/src/MultiplayerMod/Multiplayer/Components/CursorComponent.cs @@ -1,3 +1,5 @@ +using System; +using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; @@ -12,6 +14,7 @@ private record TimedCursor(Vector2 Position, long Time); private TimedCursor current = null!; private Camera camera = null!; + private Image imageComponent = null!; private TextMeshProUGUI textComponent = null!; private bool initialized; @@ -27,6 +30,7 @@ public Vector3 Position { public string PlayerName { get; set; } = null!; public string? ScreenName { get; set; } + public Type? ScreenType { get; set; } public void Trace(Vector2 position) { previous = current; @@ -55,7 +59,7 @@ private void CreateCursorGameObject(Texture2D cursorTexture) { rectTransform.sizeDelta = new Vector2(cursorTexture.width, cursorTexture.height); rectTransform.pivot = new Vector2(0, 1); // Align to top left corner. - var imageComponent = imageGameObject.AddComponent(); + imageComponent = imageGameObject.AddComponent(); imageComponent.sprite = Sprite.Create( cursorTexture, new Rect(0, 0, cursorTexture.width, cursorTexture.height), @@ -85,8 +89,13 @@ private void Update() { if (!initialized) return; + var isOnTheSameScreen = KScreenManager.Instance.screenStack.FirstOrDefault(screen => screen.mouseOver) + ?.GetType() == ScreenType; + gameObject.transform.position = camera.WorldToScreenPoint(GetCurrentPosition()); - textComponent.text = PlayerName + (ScreenName == null ? "" : $" ({ScreenName})"); + textComponent.text = PlayerName + (isOnTheSameScreen ? "" : $" ({ScreenName ?? "World"})"); + + imageComponent.color = textComponent.color = isOnTheSameScreen ? Color.white : new Color(1, 1, 1, 0.5f); } private Vector2 GetCurrentPosition() { diff --git a/src/MultiplayerMod/Multiplayer/Components/CursorManager.cs b/src/MultiplayerMod/Multiplayer/Components/CursorManager.cs index b79e2123..585db674 100644 --- a/src/MultiplayerMod/Multiplayer/Components/CursorManager.cs +++ b/src/MultiplayerMod/Multiplayer/Components/CursorManager.cs @@ -30,14 +30,16 @@ private void OnPlayerLeft(PlayerLeftEvent @event) { private void OnCursorUpdated(PlayerCursorPositionUpdatedEvent updatedEvent) { if (!cursors.TryGetValue(updatedEvent.Player, out var cursorComponent)) { cursorComponent = gameObject.AddComponent(); - cursorComponent.Position = updatedEvent.Position; cursorComponent.PlayerName = updatedEvent.Player.Profile.PlayerName; - cursorComponent.ScreenName = updatedEvent.ScreenName; + cursorComponent.Position = updatedEvent.MouseMovedEventArgs.Position; + cursorComponent.ScreenName = updatedEvent.MouseMovedEventArgs.ScreenName; + cursorComponent.ScreenType = updatedEvent.MouseMovedEventArgs.ScreenType; cursors[updatedEvent.Player] = cursorComponent; return; } - cursorComponent.ScreenName = updatedEvent.ScreenName; - cursorComponent.Trace(updatedEvent.Position); + cursorComponent.ScreenName = updatedEvent.MouseMovedEventArgs.ScreenName; + cursorComponent.ScreenType = updatedEvent.MouseMovedEventArgs.ScreenType; + cursorComponent.Trace(updatedEvent.MouseMovedEventArgs.Position); } } diff --git a/src/MultiplayerMod/Multiplayer/CoreOperations/Binders/GameEventsBinder.cs b/src/MultiplayerMod/Multiplayer/CoreOperations/Binders/GameEventsBinder.cs index a2a2d6df..58010fca 100644 --- a/src/MultiplayerMod/Multiplayer/CoreOperations/Binders/GameEventsBinder.cs +++ b/src/MultiplayerMod/Multiplayer/CoreOperations/Binders/GameEventsBinder.cs @@ -65,8 +65,8 @@ private void BindSpeedControl() { private void BindMouse() { // TODO: Cursor update may be ignored if MouseMoved isn't triggered after the rate period. // TODO: Will be changed later (probably with current / last sent positions check). - InterfaceToolEvents.MouseMoved += (position, screenName) => throttle10Hz.Run( - () => client.Send(new UpdatePlayerCursorPosition(multiplayer.Players.Current.Id, position, screenName)) + InterfaceToolEvents.MouseMoved += args => throttle10Hz.Run( + () => client.Send(new UpdatePlayerCursorPosition(multiplayer.Players.Current.Id, args)) ); } diff --git a/src/MultiplayerMod/Multiplayer/Players/Events/PlayerCursorPositionUpdatedEvent.cs b/src/MultiplayerMod/Multiplayer/Players/Events/PlayerCursorPositionUpdatedEvent.cs index 4f4d203f..65578544 100644 --- a/src/MultiplayerMod/Multiplayer/Players/Events/PlayerCursorPositionUpdatedEvent.cs +++ b/src/MultiplayerMod/Multiplayer/Players/Events/PlayerCursorPositionUpdatedEvent.cs @@ -1,7 +1,9 @@ using MultiplayerMod.Core.Events; -using UnityEngine; +using MultiplayerMod.Game.UI.Tools.Events; namespace MultiplayerMod.Multiplayer.Players.Events; -public record PlayerCursorPositionUpdatedEvent - (MultiplayerPlayer Player, Vector2 Position, string? ScreenName) : IDispatchableEvent; +public record PlayerCursorPositionUpdatedEvent( + MultiplayerPlayer Player, + InterfaceToolEvents.MouseMovedEventArgs MouseMovedEventArgs +) : IDispatchableEvent;