From d5e9bd17d26e95df5a2ad495029995228f6dd4e1 Mon Sep 17 00:00:00 2001 From: SokyranTheDragon Date: Sun, 16 Nov 2025 19:13:06 +0100 Subject: [PATCH] Fix and improve world ping bugs - Prevent pinging invalid locations - This includes trying to ping space or planet locations that aren't part of playable world - When finding a tile under a mouse failed, attempt again but snap to expandable world objects - This will properly handle finding world objects in space - This doesn't allow pinging empty locations in space, as `GenWorld.MouseTile` cannot select those - Prevent drawing pings from planet layers that aren't currently active - When sending map location, use `PlanetTile.Invalid` rather than a surface tile with ID of 0. - When receiving pings, make sure that we received a valid ping location before accepting it --- Source/Client/UI/DrawPingPlanet.cs | 2 ++ Source/Client/UI/LocationPings.cs | 22 +++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Source/Client/UI/DrawPingPlanet.cs b/Source/Client/UI/DrawPingPlanet.cs index f226cff7..4e32fe96 100644 --- a/Source/Client/UI/DrawPingPlanet.cs +++ b/Source/Client/UI/DrawPingPlanet.cs @@ -16,6 +16,8 @@ static void Postfix() { if (ping.mapId != -1) continue; if (ping.PlayerInfo is not { } player) continue; + // Only display pings on the current layer + if (ping.planetTile.Layer != Find.WorldSelector.SelectedLayer) continue; var tileCenter = GenWorldUI.WorldToUIPosition(Find.WorldGrid.GetTileCenter(ping.planetTile)); const float size = 30f; diff --git a/Source/Client/UI/LocationPings.cs b/Source/Client/UI/LocationPings.cs index f690b420..68179ff7 100644 --- a/Source/Client/UI/LocationPings.cs +++ b/Source/Client/UI/LocationPings.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Multiplayer.Client.Util; using Multiplayer.Common.Networking.Packet; using RimWorld; @@ -23,9 +24,19 @@ public void UpdatePing() if (MultiplayerStatic.PingKeyDef.JustPressed || KeyDown(Multiplayer.settings.sendPingButton)) { if (WorldRendererUtility.WorldSelected) - PingLocation(-1, GenWorld.MouseTile(), Vector3.zero); + { + // Grab the tile under mouse + var tile = GenWorld.MouseTile(); + // If the tile is not valid, snap to expandable world objects (handles orbital locations) + if (!tile.Valid) + tile = GenWorld.MouseTile(true); + + // Make sure the tile is valid and that we didn't ping with the mouse outside of map bounds or in space + if (tile.Valid) + PingLocation(-1, tile, Vector3.zero); + } else if (Find.CurrentMap != null) - PingLocation(Find.CurrentMap.uniqueID, 0, UI.MouseMapPosition()); + PingLocation(Find.CurrentMap.uniqueID, PlanetTile.Invalid, UI.MouseMapPosition()); } for (int i = pings.Count - 1; i >= 0; i--) @@ -69,11 +80,16 @@ public void ReceivePing(ServerPingLocPacket packet) if (!Multiplayer.settings.enablePings) return; var data = packet.data; + var planetTile = new PlanetTile(data.planetTileId, data.planetTileLayer); + // Return early if both the map and planet tile are invalid + if (data.mapId == -1 && !planetTile.Valid) + return; + pings.RemoveAll(p => p.player == packet.playerId); pings.Add(new PingInfo { player = packet.playerId, mapId = data.mapId, - planetTile = new PlanetTile(data.planetTileId, data.planetTileLayer), + planetTile = planetTile, mapLoc = new Vector3(data.x, data.y, data.z) }); alertHidden = false;