Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -13,6 +14,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;
Expand All @@ -23,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;

/// <summary>
/// Used to transform all of the radar objects. Typically is a shuttle console parented to a grid.
Expand All @@ -49,11 +52,31 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl

private List<Entity<MapGridComponent>> _grids = new();

#region Hullrot
// These 2 handle timing updates
private const float RadarUpdateInterval = 2f;
private float _updateAccumulator = 0f;
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.

if (_consoleEntity != null)
_blips.RequestBlips((EntityUid)_consoleEntity);
}
}
#endregion Hullrot

public ShuttleNavControl() : base(64f, 256f, 256f)
{
RobustXamlLoader.Load(this);
_shuttles = EntManager.System<SharedShuttleSystem>();
_transform = EntManager.System<SharedTransformSystem>();
_blips = EntManager.System<RadarBlipsSystem>();
}

public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
Expand Down Expand Up @@ -290,6 +313,25 @@ protected override void Draw(DrawingHandleScreen handle)
}
}

#region Hullrot
// Draw radar line
// First, figure out which angle to draw.
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));

// 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
}

private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 gridToView)
Expand Down
48 changes: 48 additions & 0 deletions Content.Client/_Hullrot/Radar/RadarBlipsSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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();
SubscribeNetworkEvent<GiveBlipsEvent>(HandleReceiveBlips);
}

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);
}

_blips = ev.Blips;
_lastUpdatedTime = _timing.CurTime;
}

public void RequestBlips(EntityUid console)
{
var netConsole = GetNetEntity(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;
}
}
29 changes: 29 additions & 0 deletions Content.Server/_Hullrot/Radar/RadarBlipComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Content.Server._Hullrot.Radar;

/// <summary>
/// These handle objects which should be represented by radar blips.
/// </summary>
[RegisterComponent]
public sealed partial class RadarBlipComponent : Component
{
/// <summary>
/// Color of the blip.
/// </summary>
[DataField]
public Color Color = Color.Red;

/// <summary>
/// Scale of the blip.
/// </summary>
[DataField]
public float Scale = 1;

/// <summary>
/// Whether this blip should be shown even when parented to a grid.
/// </summary>
[DataField]
public bool RequireNoGrid = false;

[DataField]
public bool Enabled = true;
}
67 changes: 67 additions & 0 deletions Content.Server/_Hullrot/Radar/RadarBlipSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.Numerics;
using Content.Server.Shuttles.Systems;
using Content.Shared._Hullrot.Radar;
using Content.Shared.Shuttles.Components;

namespace Content.Server._Hullrot.Radar;

/// <summary>
/// I debated making <see cref="RadarConsoleSystem"/> 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.
/// </summary>
public sealed partial class RadarBlipSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _xform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<RequestBlipsEvent>(OnBlipsRequested);
}

private void OnBlipsRequested(RequestBlipsEvent ev, EntitySessionEventArgs args)
{
if (!TryGetEntity(ev.Radar, out var radarUid))
return;

if (!TryComp<RadarConsoleComponent>(radarUid, out var radar))
return;

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<RadarBlipComponent, TransformComponent>();

// 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;
}
}
31 changes: 31 additions & 0 deletions Content.Shared/_Hullrot/Radar/RadarMessages.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// Blips are a position, a scale, and a color.
/// </summary>
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;
}
}
Loading