Skip to content

Commit ba29911

Browse files
Fix and improve world ping bugs (#794)
* 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 * Added an option to draw cross-layer pings Requires adding translations * Extra null planet layer check
1 parent e4f40bd commit ba29911

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

Source/Client/Settings/MpSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class MpSettings : ModSettings
2323
public bool showModCompatibility = true;
2424
public bool hideTranslationMods = true;
2525
public bool enablePings = true;
26+
public bool enableCrossPlanetLayerPings = true;
2627
public KeyCode? sendPingButton = KeyCode.Mouse4;
2728
public KeyCode? jumpToPingButton = KeyCode.Mouse3;
2829
public Rect chatRect;
@@ -66,6 +67,7 @@ public override void ExposeData()
6667
Scribe_Values.Look(ref showModCompatibility, "showModCompatibility", true);
6768
Scribe_Values.Look(ref hideTranslationMods, "hideTranslationMods", true);
6869
Scribe_Values.Look(ref enablePings, "enablePings", true);
70+
Scribe_Values.Look(ref enableCrossPlanetLayerPings, "enableCrossPlanetLayerPings", true);
6971
Scribe_Values.Look(ref sendPingButton, "sendPingButton", KeyCode.Mouse4);
7072
Scribe_Values.Look(ref jumpToPingButton, "jumpToPingButton", KeyCode.Mouse3);
7173
Scribe_Custom.LookRect(ref chatRect, "chatRect");

Source/Client/Settings/MpSettingsUI.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public static void DoGeneralSettings(MpSettings settings, Rect inRect, Rect page
7373
listing.CheckboxLabeled("MpShowModCompat".Translate(), ref settings.showModCompatibility,
7474
"MpShowModCompatDesc".Translate());
7575
listing.CheckboxLabeled("MpEnablePingsSetting".Translate(), ref settings.enablePings);
76+
listing.CheckboxLabeled("MpEnableCrossPlanetLayerPings".Translate(), ref settings.enableCrossPlanetLayerPings,
77+
"MpEnableCrossPlanetLayerPingsDesc".Translate());
7678
listing.CheckboxLabeled("MpShowMainMenuAnimation".Translate(), ref settings.showMainMenuAnim);
7779

7880
const string buttonOff = "Off";

Source/Client/UI/DrawPingPlanet.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ static void Postfix()
1616
{
1717
if (ping.mapId != -1) continue;
1818
if (ping.PlayerInfo is not { } player) continue;
19+
if (ping.planetTile.Layer == null) continue;
20+
21+
var layer = Find.WorldSelector.SelectedLayer;
22+
// Only display pings on the current layer or (if enabled) on layers we can zoom to.
23+
if (Multiplayer.settings.enableCrossPlanetLayerPings)
24+
{
25+
// We can either start with the ping layer, and keep zooming out,
26+
// or start with the current player layer, and keep zooming in.
27+
// Or both. This implementation tries to zoom in from the current player's layer.
28+
29+
// Infinite loop prevention.
30+
for (var i = 0; i < 25; i++)
31+
{
32+
// Either can't zoom in more, or we found our target
33+
if (layer == null || layer == ping.planetTile.Layer)
34+
break;
35+
36+
layer = layer.zoomInToLayer;
37+
}
38+
}
39+
if (ping.planetTile.Layer != layer) continue;
1940

2041
var tileCenter = GenWorldUI.WorldToUIPosition(Find.WorldGrid.GetTileCenter(ping.planetTile));
2142
const float size = 30f;

Source/Client/UI/LocationPings.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.Linq;
23
using Multiplayer.Client.Util;
34
using Multiplayer.Common.Networking.Packet;
45
using RimWorld;
@@ -23,9 +24,19 @@ public void UpdatePing()
2324
if (MultiplayerStatic.PingKeyDef.JustPressed || KeyDown(Multiplayer.settings.sendPingButton))
2425
{
2526
if (WorldRendererUtility.WorldSelected)
26-
PingLocation(-1, GenWorld.MouseTile(), Vector3.zero);
27+
{
28+
// Grab the tile under mouse
29+
var tile = GenWorld.MouseTile();
30+
// If the tile is not valid, snap to expandable world objects (handles orbital locations)
31+
if (!tile.Valid)
32+
tile = GenWorld.MouseTile(true);
33+
34+
// Make sure the tile is valid and that we didn't ping with the mouse outside of map bounds or in space
35+
if (tile.Valid)
36+
PingLocation(-1, tile, Vector3.zero);
37+
}
2738
else if (Find.CurrentMap != null)
28-
PingLocation(Find.CurrentMap.uniqueID, 0, UI.MouseMapPosition());
39+
PingLocation(Find.CurrentMap.uniqueID, PlanetTile.Invalid, UI.MouseMapPosition());
2940
}
3041

3142
for (int i = pings.Count - 1; i >= 0; i--)
@@ -69,11 +80,16 @@ public void ReceivePing(ServerPingLocPacket packet)
6980
if (!Multiplayer.settings.enablePings) return;
7081

7182
var data = packet.data;
83+
var planetTile = new PlanetTile(data.planetTileId, data.planetTileLayer);
84+
// Return early if both the map and planet tile are invalid
85+
if (data.mapId == -1 && !planetTile.Valid)
86+
return;
87+
7288
pings.RemoveAll(p => p.player == packet.playerId);
7389
pings.Add(new PingInfo {
7490
player = packet.playerId,
7591
mapId = data.mapId,
76-
planetTile = new PlanetTile(data.planetTileId, data.planetTileLayer),
92+
planetTile = planetTile,
7793
mapLoc = new Vector3(data.x, data.y, data.z)
7894
});
7995
alertHidden = false;

0 commit comments

Comments
 (0)