From 77f98711a57b62f14377782defda82bf1e1283da Mon Sep 17 00:00:00 2001 From: Rane Date: Fri, 10 Jan 2025 16:24:34 -0500 Subject: [PATCH 1/8] register component --- .../_Hullrot/Radar/RadarBlipComponent.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Content.Server/_Hullrot/Radar/RadarBlipComponent.cs diff --git a/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs new file mode 100644 index 0000000000..4d297551ea --- /dev/null +++ b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs @@ -0,0 +1,28 @@ +using Robust.Shared.GameStates; + +namespace Content.Server._Hullrot.Radar; + +/// +/// These handle objects which should be represented by radar blips. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class RadarBlipComponent : Component +{ + /// + /// Color of the blip. + /// + [DataField] + public Color Color = Color.Red; + + /// + /// Scale of the blip. + /// + [DataField] + public float Scale = 1; + + /// + /// Whether this blip should be shown even when parented to a grid. + /// + [DataField] + public bool RequireNoGrid = true; +} From 0fe8e0bf3344acc6f0e298feba1763b8f8e89d00 Mon Sep 17 00:00:00 2001 From: Rane Date: Fri, 10 Jan 2025 16:52:38 -0500 Subject: [PATCH 2/8] lay out how it works --- .../Shuttles/UI/ShuttleNavControl.xaml.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 805608c9a5..efbd362fc9 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -13,6 +13,7 @@ using Robust.Shared.Map.Components; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; +using Robust.Shared.Timing; using Robust.Shared.Utility; namespace Content.Client.Shuttles.UI; @@ -49,6 +50,32 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl private List> _grids = new(); + #region Hullrot + // These 2 handle timing updates + private const float RadarUpdateInterval = 2f; + private float _updateAccumulator = 0f; + + // We ask for the next update a little early so it's more responsive, but we always ignore it until it's time. + private bool _nextUpdateReady = false; + + // private list CachedNextUpdate + + // We receive our updates in the form of a list of positions, colors, and scale. + // private list CurrentUpdate + + // As the scan line hits them, they become active blips. They're removed from the above list and added to this list of active blips. + // private list ActiveBlips + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + _updateAccumulator += args.DeltaSeconds; + + if (_updateAccumulator >= RadarUpdateInterval) + _updateAccumulator = 0; // I'm not subtracting because frame updates can majorly lag in a way normal ones cannot. + } + #endregion Hullrot + public ShuttleNavControl() : base(64f, 256f, 256f) { RobustXamlLoader.Load(this); @@ -290,6 +317,22 @@ protected override void Draw(DrawingHandleScreen handle) } } + #region Hullrot + // Draw radar line + // First, figure out which angle to draw. + var angle = (_updateAccumulator / RadarUpdateInterval) * 360f; + + // Here's how the old north line worked. + // protected void DrawNorthLine(DrawingHandleScreen handle, Angle angle) + // { + // var origin = ScalePosition(-new Vector2(Offset.X, -Offset.Y)); + // var aExtent = (angle - Math.Tau / 4).ToVec() * ScaledMinimapRadius * 1.42f; + // var lineColor = Color.Red.WithAlpha(0.1f); + // handle.DrawLine(origin, origin + aExtent, lineColor); + // } + + // Draw blips + #endregion } private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 gridToView) From 57e5f788ea2473c12efc7b10a73bb1ebe408475b Mon Sep 17 00:00:00 2001 From: Rane Date: Fri, 10 Jan 2025 17:04:42 -0500 Subject: [PATCH 3/8] scaffolding --- Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index efbd362fc9..21d97d80fb 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -320,7 +320,9 @@ protected override void Draw(DrawingHandleScreen handle) #region Hullrot // Draw radar line // First, figure out which angle to draw. - var angle = (_updateAccumulator / RadarUpdateInterval) * 360f; + Angle angle = _updateAccumulator / RadarUpdateInterval * Math.Tau; + var origin = ScalePosition(-new Vector2(Offset.X, -Offset.Y)); + handle.DrawLine(origin, origin + angle.ToVec() * ScaledMinimapRadius * 1.42f, Color.Green.WithAlpha(0.1f)); // Here's how the old north line worked. // protected void DrawNorthLine(DrawingHandleScreen handle, Angle angle) From 0edfd6f0de895a1dbd7e351bcb06aea17533c6e7 Mon Sep 17 00:00:00 2001 From: Rane Date: Fri, 10 Jan 2025 17:18:46 -0500 Subject: [PATCH 4/8] draw the radar line effect --- Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs | 2 +- Content.Server/_Hullrot/Radar/RadarBlipComponent.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 21d97d80fb..beb67ccfea 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -322,7 +322,7 @@ protected override void Draw(DrawingHandleScreen handle) // First, figure out which angle to draw. Angle angle = _updateAccumulator / RadarUpdateInterval * Math.Tau; var origin = ScalePosition(-new Vector2(Offset.X, -Offset.Y)); - handle.DrawLine(origin, origin + angle.ToVec() * ScaledMinimapRadius * 1.42f, Color.Green.WithAlpha(0.1f)); + handle.DrawLine(origin, origin + angle.ToVec() * ScaledMinimapRadius * 1.42f, Color.Orange.WithAlpha(0.1f)); // Here's how the old north line worked. // protected void DrawNorthLine(DrawingHandleScreen handle, Angle angle) diff --git a/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs index 4d297551ea..e2b85c2767 100644 --- a/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs +++ b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs @@ -1,11 +1,9 @@ -using Robust.Shared.GameStates; - namespace Content.Server._Hullrot.Radar; /// /// These handle objects which should be represented by radar blips. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent] public sealed partial class RadarBlipComponent : Component { /// From aeb3345742f7ed475f1dd3be80f12fed3f85b2fb Mon Sep 17 00:00:00 2001 From: Rane Date: Wed, 15 Jan 2025 15:32:41 -0500 Subject: [PATCH 5/8] networking scaffolding --- .../Shuttles/UI/ShuttleNavControl.xaml.cs | 8 +++++ .../_Hullrot/Radar/RadarBlipsSystem.cs | 25 +++++++++++++++ .../_Hullrot/Radar/RadarBlipSystem.cs | 23 ++++++++++++++ .../_Hullrot/Radar/RadarMessages.cs | 31 +++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs create mode 100644 Content.Server/_Hullrot/Radar/RadarBlipSystem.cs create mode 100644 Content.Shared/_Hullrot/Radar/RadarMessages.cs diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index beb67ccfea..7f852d2d57 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -1,4 +1,5 @@ using System.Numerics; +using Content.Client._Hullrot.Radar; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Systems; @@ -24,6 +25,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl [Dependency] private readonly IMapManager _mapManager = default!; private readonly SharedShuttleSystem _shuttles; private readonly SharedTransformSystem _transform; + private readonly RadarBlipsSystem _blips; /// /// Used to transform all of the radar objects. Typically is a shuttle console parented to a grid. @@ -72,7 +74,12 @@ protected override void FrameUpdate(FrameEventArgs args) _updateAccumulator += args.DeltaSeconds; if (_updateAccumulator >= RadarUpdateInterval) + { _updateAccumulator = 0; // I'm not subtracting because frame updates can majorly lag in a way normal ones cannot. + + if (_consoleEntity != null) + _blips.RequestBlips((EntityUid)_consoleEntity); + } } #endregion Hullrot @@ -81,6 +88,7 @@ public ShuttleNavControl() : base(64f, 256f, 256f) RobustXamlLoader.Load(this); _shuttles = EntManager.System(); _transform = EntManager.System(); + _blips = EntManager.System(); } public void SetMatrix(EntityCoordinates? coordinates, Angle? angle) diff --git a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs new file mode 100644 index 0000000000..39d716a996 --- /dev/null +++ b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs @@ -0,0 +1,25 @@ +using Content.Shared._Hullrot.Radar; + +namespace Content.Client._Hullrot.Radar; + +public sealed partial class RadarBlipsSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(HandleReceiveBlips); + } + + private void HandleReceiveBlips(GiveBlipsEvent ev, EntitySessionEventArgs args) + { + + } + + public void RequestBlips(EntityUid console) + { + var netConsole = GetNetEntity(console); + + var ev = new RequestBlipsEvent(netConsole); + RaiseNetworkEvent(ev); + } +} diff --git a/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs new file mode 100644 index 0000000000..28d79bd70b --- /dev/null +++ b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs @@ -0,0 +1,23 @@ +using Content.Server.Shuttles.Systems; +using Content.Shared._Hullrot.Radar; + +namespace Content.Server._Hullrot.Radar; + +/// +/// I debated making partial +/// but ended up doing this instead to mnimize conflicts. This system +/// handles radar blips -- which, due to both the limitations of PVS range +/// and against giving the client too much info must be server side. +/// +public sealed partial class RadarBlipSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnBlipsRequested); + } + + private void OnBlipsRequested(RequestBlipsEvent ev, EntitySessionEventArgs args) + { + } +} diff --git a/Content.Shared/_Hullrot/Radar/RadarMessages.cs b/Content.Shared/_Hullrot/Radar/RadarMessages.cs new file mode 100644 index 0000000000..fc6fd3bd16 --- /dev/null +++ b/Content.Shared/_Hullrot/Radar/RadarMessages.cs @@ -0,0 +1,31 @@ +using System.Numerics; +using Robust.Shared.Serialization; + +namespace Content.Shared._Hullrot.Radar; + +/// These are messages for exchanging information about radar signatures +/// between the client and server. See the Server's RadarBlipSystem and +/// the Client's ShuttleNavControl. + +[Serializable, NetSerializable] +public sealed class GiveBlipsEvent : EntityEventArgs +{ + /// + /// Blips are a position, a scale, and a color. + /// + public readonly List<(Vector2, float, Color)> Blips; + public GiveBlipsEvent(List<(Vector2, float, Color)> blips) + { + Blips = blips; + } +} + +[Serializable, NetSerializable] +public sealed class RequestBlipsEvent : EntityEventArgs +{ + public NetEntity Radar; + public RequestBlipsEvent(NetEntity radar) + { + Radar = radar; + } +} From 0d5be8d1543037eefff6d3e611e0e3939018a48c Mon Sep 17 00:00:00 2001 From: Rane Date: Wed, 15 Jan 2025 15:40:51 -0500 Subject: [PATCH 6/8] verify client request -> server send loop working --- Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs | 1 - Content.Server/_Hullrot/Radar/RadarBlipSystem.cs | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs index 39d716a996..ac329cccbe 100644 --- a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs +++ b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs @@ -12,7 +12,6 @@ public override void Initialize() private void HandleReceiveBlips(GiveBlipsEvent ev, EntitySessionEventArgs args) { - } public void RequestBlips(EntityUid console) diff --git a/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs index 28d79bd70b..e0536bec82 100644 --- a/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs +++ b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs @@ -1,5 +1,7 @@ +using System.Numerics; using Content.Server.Shuttles.Systems; using Content.Shared._Hullrot.Radar; +using Content.Shared.Shuttles.Components; namespace Content.Server._Hullrot.Radar; @@ -19,5 +21,15 @@ public override void Initialize() private void OnBlipsRequested(RequestBlipsEvent ev, EntitySessionEventArgs args) { + if (!TryGetEntity(ev.Radar, out var radarUid)) + return; + + if (!TryComp(radarUid, out var radar)) + return; + + var blips = new List<(Vector2, float, Color)>(); + + var giveEv = new GiveBlipsEvent(blips); + RaiseNetworkEvent(giveEv, args.SenderSession); } } From 2b1fc5259b71ee383ce3bf1506c10915bc0eacc0 Mon Sep 17 00:00:00 2001 From: Rane Date: Wed, 15 Jan 2025 16:07:14 -0500 Subject: [PATCH 7/8] blip reports actual blips --- .../_Hullrot/Radar/RadarBlipsSystem.cs | 7 ++++ .../_Hullrot/Radar/RadarBlipComponent.cs | 5 ++- .../_Hullrot/Radar/RadarBlipSystem.cs | 34 ++++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs index ac329cccbe..0c9b8da6cc 100644 --- a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs +++ b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs @@ -12,6 +12,13 @@ public override void Initialize() private void HandleReceiveBlips(GiveBlipsEvent ev, EntitySessionEventArgs args) { + Logger.Error("Received blips. Count: " + ev.Blips.Count); + foreach (var blip in ev.Blips) + { + Logger.Error("Pos: " + blip.Item1); + Logger.Error("Scale: " + blip.Item2); + Logger.Error("Color: " + blip.Item3); + } } public void RequestBlips(EntityUid console) diff --git a/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs index e2b85c2767..4bd563dae2 100644 --- a/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs +++ b/Content.Server/_Hullrot/Radar/RadarBlipComponent.cs @@ -22,5 +22,8 @@ public sealed partial class RadarBlipComponent : Component /// Whether this blip should be shown even when parented to a grid. /// [DataField] - public bool RequireNoGrid = true; + public bool RequireNoGrid = false; + + [DataField] + public bool Enabled = true; } diff --git a/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs index e0536bec82..e685874593 100644 --- a/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs +++ b/Content.Server/_Hullrot/Radar/RadarBlipSystem.cs @@ -13,6 +13,7 @@ namespace Content.Server._Hullrot.Radar; /// public sealed partial class RadarBlipSystem : EntitySystem { + [Dependency] private readonly SharedTransformSystem _xform = default!; public override void Initialize() { base.Initialize(); @@ -27,9 +28,40 @@ private void OnBlipsRequested(RequestBlipsEvent ev, EntitySessionEventArgs args) if (!TryComp(radarUid, out var radar)) return; - var blips = new List<(Vector2, float, Color)>(); + var blips = AssembleBlipsReport((EntityUid)radarUid, radar); var giveEv = new GiveBlipsEvent(blips); RaiseNetworkEvent(giveEv, args.SenderSession); } + + private List<(Vector2, float, Color)> AssembleBlipsReport(EntityUid uid, RadarConsoleComponent? component = null) + { + var blips = new List<(Vector2, float, Color)>(); + + if (Resolve(uid, ref component)) + { + var blipQuery = EntityQueryEnumerator(); + + // add blips, except + while (blipQuery.MoveNext(out var blipUid, out var blip, out var _)) + { + // case 1: component disabled + if (!blip.Enabled) + continue; + + // case 2: blip out of radar's max range + var distance = (_xform.GetWorldPosition(blipUid) - _xform.GetWorldPosition(uid)).Length(); + if (distance > component.MaxRange) + continue; + + // case 3: On grid but will only show up off grid + if (blip.RequireNoGrid && _xform.GetGrid(blipUid) != null) + continue; + + blips.Add((_xform.GetWorldPosition(blipUid), blip.Scale, blip.Color)); + } + } + + return blips; + } } From 971dafce4d040995de5fff68a1fd89224e52d328 Mon Sep 17 00:00:00 2001 From: Rane Date: Wed, 15 Jan 2025 16:36:50 -0500 Subject: [PATCH 8/8] Basically works --- .../Shuttles/UI/ShuttleNavControl.xaml.cs | 33 +++++++------------ .../_Hullrot/Radar/RadarBlipsSystem.cs | 17 ++++++++++ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 7f852d2d57..cc85dd4832 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -56,18 +56,6 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl // These 2 handle timing updates private const float RadarUpdateInterval = 2f; private float _updateAccumulator = 0f; - - // We ask for the next update a little early so it's more responsive, but we always ignore it until it's time. - private bool _nextUpdateReady = false; - - // private list CachedNextUpdate - - // We receive our updates in the form of a list of positions, colors, and scale. - // private list CurrentUpdate - - // As the scan line hits them, they become active blips. They're removed from the above list and added to this list of active blips. - // private list ActiveBlips - protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); @@ -328,20 +316,21 @@ protected override void Draw(DrawingHandleScreen handle) #region Hullrot // Draw radar line // First, figure out which angle to draw. - Angle angle = _updateAccumulator / RadarUpdateInterval * Math.Tau; + var updateRatio = _updateAccumulator / RadarUpdateInterval; + + Angle angle = updateRatio * Math.Tau; var origin = ScalePosition(-new Vector2(Offset.X, -Offset.Y)); handle.DrawLine(origin, origin + angle.ToVec() * ScaledMinimapRadius * 1.42f, Color.Orange.WithAlpha(0.1f)); - // Here's how the old north line worked. - // protected void DrawNorthLine(DrawingHandleScreen handle, Angle angle) - // { - // var origin = ScalePosition(-new Vector2(Offset.X, -Offset.Y)); - // var aExtent = (angle - Math.Tau / 4).ToVec() * ScaledMinimapRadius * 1.42f; - // var lineColor = Color.Red.WithAlpha(0.1f); - // handle.DrawLine(origin, origin + aExtent, lineColor); - // } - // Draw blips + var blips = _blips.GetCurrentBlips(); + + foreach (var blip in blips) + { + var blipPos = Vector2.Transform(blip.Item1, worldToShuttle * shuttleToView); + handle.DrawCircle(blipPos, blip.Item2 * 3f, blip.Item3.WithAlpha(0.8f)); + } + #endregion } diff --git a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs index 0c9b8da6cc..16adcecbd4 100644 --- a/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs +++ b/Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs @@ -1,9 +1,15 @@ +using System.Numerics; using Content.Shared._Hullrot.Radar; +using Robust.Shared.Timing; namespace Content.Client._Hullrot.Radar; public sealed partial class RadarBlipsSystem : EntitySystem { + [Dependency] private readonly IGameTiming _timing = default!; + private TimeSpan _lastUpdatedTime; + private List<(Vector2, float, Color)> _blips = new(); + public override void Initialize() { base.Initialize(); @@ -19,6 +25,9 @@ private void HandleReceiveBlips(GiveBlipsEvent ev, EntitySessionEventArgs args) Logger.Error("Scale: " + blip.Item2); Logger.Error("Color: " + blip.Item3); } + + _blips = ev.Blips; + _lastUpdatedTime = _timing.CurTime; } public void RequestBlips(EntityUid console) @@ -28,4 +37,12 @@ public void RequestBlips(EntityUid console) var ev = new RequestBlipsEvent(netConsole); RaiseNetworkEvent(ev); } + + public List<(Vector2, float, Color)> GetCurrentBlips() + { + if (_timing.CurTime.TotalSeconds - _lastUpdatedTime.TotalSeconds > 10) + return new List<(Vector2, float, Color)>(); + + return _blips; + } }