Port the Mass Scanner from OR14 (#6172)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -283,6 +283,7 @@ namespace Content.Client.Entry
|
|||||||
"AtmosAlarmable",
|
"AtmosAlarmable",
|
||||||
"FireAlarm",
|
"FireAlarm",
|
||||||
"AirAlarm",
|
"AirAlarm",
|
||||||
|
"RadarConsole",
|
||||||
"Guardian",
|
"Guardian",
|
||||||
"GuardianCreator",
|
"GuardianCreator",
|
||||||
"GuardianHost",
|
"GuardianHost",
|
||||||
|
|||||||
8
Content.Client/Radar/RadarConsoleWindow.xaml
Normal file
8
Content.Client/Radar/RadarConsoleWindow.xaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<DefaultWindow xmlns="https://spacestation14.io"
|
||||||
|
xmlns:radar="clr-namespace:Content.Client.Radar"
|
||||||
|
Title="{Loc 'radar-window-title'}"
|
||||||
|
Resizable="False">
|
||||||
|
<BoxContainer Orientation="Horizontal">
|
||||||
|
<radar:RadarControl Name="Radar"/>
|
||||||
|
</BoxContainer>
|
||||||
|
</DefaultWindow>
|
||||||
113
Content.Client/Radar/RadarConsoleWindow.xaml.cs
Normal file
113
Content.Client/Radar/RadarConsoleWindow.xaml.cs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Client.Computer;
|
||||||
|
using Content.Shared.Radar;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Client.Radar;
|
||||||
|
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public partial class RadarConsoleWindow : DefaultWindow, IComputerWindow<RadarConsoleBoundInterfaceState>
|
||||||
|
{
|
||||||
|
public RadarConsoleWindow()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetupComputerWindow(ComputerBoundUserInterfaceBase cb)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateState(RadarConsoleBoundInterfaceState scc)
|
||||||
|
{
|
||||||
|
Radar.UpdateState(scc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class RadarControl : Control
|
||||||
|
{
|
||||||
|
private float _radarArea = 256f;
|
||||||
|
|
||||||
|
private float RadarCircleRadius => MathF.Max(0, _radarArea - 8) / 2;
|
||||||
|
|
||||||
|
private RadarConsoleBoundInterfaceState _lastState = new(256f, Array.Empty<RadarObjectData>());
|
||||||
|
|
||||||
|
private float SizeFull => (int) (_radarArea * UIScale);
|
||||||
|
|
||||||
|
public int RadiusCircle => (int) (RadarCircleRadius * UIScale);
|
||||||
|
|
||||||
|
public RadarControl()
|
||||||
|
{
|
||||||
|
MinSize = (SizeFull, SizeFull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateState(RadarConsoleBoundInterfaceState ls)
|
||||||
|
{
|
||||||
|
if (!_radarArea.Equals(ls.Range * 2))
|
||||||
|
{
|
||||||
|
_radarArea = ls.Range * 2;
|
||||||
|
MinSize = (SizeFull, SizeFull);
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastState = ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
var point = SizeFull / 2;
|
||||||
|
var fakeAA = new Color(0.08f, 0.08f, 0.08f);
|
||||||
|
var gridLines = new Color(0.08f, 0.08f, 0.08f);
|
||||||
|
var gridLinesRadial = 8;
|
||||||
|
var gridLinesEquatorial = 8;
|
||||||
|
|
||||||
|
handle.DrawCircle((point, point), RadiusCircle + 1, fakeAA);
|
||||||
|
handle.DrawCircle((point, point), RadiusCircle, Color.Black);
|
||||||
|
|
||||||
|
for (var i = 0; i < gridLinesEquatorial; i++)
|
||||||
|
{
|
||||||
|
handle.DrawCircle((point, point), (RadiusCircle / gridLinesEquatorial) * i, gridLines, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < gridLinesRadial; i++)
|
||||||
|
{
|
||||||
|
Angle angle = (Math.PI / gridLinesRadial) * i;
|
||||||
|
var aExtent = angle.ToVec() * RadiusCircle;
|
||||||
|
handle.DrawLine((point, point) - aExtent, (point, point) + aExtent, gridLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle.DrawLine((point, point) + new Vector2(8, 8), (point, point) - new Vector2(0, 8), Color.Yellow);
|
||||||
|
handle.DrawLine((point, point) + new Vector2(-8, 8), (point, point) - new Vector2(0, 8), Color.Yellow);
|
||||||
|
|
||||||
|
foreach (var obj in _lastState.Objects)
|
||||||
|
{
|
||||||
|
if (obj.Position.Length > RadiusCircle - 24)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (obj.Shape)
|
||||||
|
{
|
||||||
|
case RadarObjectShape.CircleFilled:
|
||||||
|
case RadarObjectShape.Circle:
|
||||||
|
{
|
||||||
|
handle.DrawCircle(obj.Position + point, obj.Radius, obj.Color, obj.Shape == RadarObjectShape.CircleFilled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class RadarConsoleBoundUserInterface : ComputerBoundUserInterface<RadarConsoleWindow, RadarConsoleBoundInterfaceState>
|
||||||
|
{
|
||||||
|
public RadarConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
|
||||||
|
}
|
||||||
13
Content.Server/Radar/RadarConsoleComponent.cs
Normal file
13
Content.Server/Radar/RadarConsoleComponent.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
|
namespace Content.Server.Radar;
|
||||||
|
|
||||||
|
[RegisterComponent, ComponentProtoName("RadarConsole")]
|
||||||
|
public class RadarConsoleComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("range")]
|
||||||
|
public float Range = 256f;
|
||||||
|
}
|
||||||
68
Content.Server/Radar/RadarConsoleSystem.cs
Normal file
68
Content.Server/Radar/RadarConsoleSystem.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.Solar.Components;
|
||||||
|
using Content.Server.UserInterface;
|
||||||
|
using Content.Shared.Radar;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Server.Radar;
|
||||||
|
|
||||||
|
public class RadarConsoleSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
|
|
||||||
|
private static float Frequency = 1.5f;
|
||||||
|
|
||||||
|
private float _accumulator;
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
_accumulator += frameTime;
|
||||||
|
|
||||||
|
if (_accumulator < Frequency)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_accumulator -= Frequency;
|
||||||
|
|
||||||
|
foreach (var (component, xform) in EntityManager.EntityQuery<RadarConsoleComponent, TransformComponent>())
|
||||||
|
{
|
||||||
|
var s = component.Owner.GetUIOrNull(RadarConsoleUiKey.Key);
|
||||||
|
|
||||||
|
if (s is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var (radarPos, _, radarInvMatrix) = xform.GetWorldPositionRotationInvMatrix();
|
||||||
|
|
||||||
|
var mapId = xform.MapID;
|
||||||
|
var objects = new List<RadarObjectData>();
|
||||||
|
|
||||||
|
_mapManager.FindGridsIntersectingEnumerator(mapId, new Box2(radarPos - component.Range, radarPos + component.Range), out var enumerator, true);
|
||||||
|
|
||||||
|
while (enumerator.MoveNext(out var grid))
|
||||||
|
{
|
||||||
|
var phy = Comp<PhysicsComponent>(grid.GridEntityId);
|
||||||
|
var transform = Transform(grid.GridEntityId);
|
||||||
|
|
||||||
|
if (phy.Mass < 50)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var rad = Math.Log2(phy.Mass);
|
||||||
|
var gridCenter = transform.WorldMatrix.Transform(phy.LocalCenter);
|
||||||
|
|
||||||
|
var pos = radarInvMatrix.Transform(gridCenter);
|
||||||
|
pos.Y = -pos.Y; // Robust has an inverted Y, like BYOND. This undoes that.
|
||||||
|
|
||||||
|
if (pos.Length > component.Range)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
objects.Add(new RadarObjectData {Color = Color.Aqua, Position = pos, Radius = (float)rad});
|
||||||
|
}
|
||||||
|
|
||||||
|
s.SetState(new RadarConsoleBoundInterfaceState(component.Range, objects.ToArray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Content.Shared/Radar/RadarConsoleBoundInterfaceState.cs
Normal file
40
Content.Shared/Radar/RadarConsoleBoundInterfaceState.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Radar;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public float Range;
|
||||||
|
public RadarObjectData[] Objects;
|
||||||
|
|
||||||
|
public RadarConsoleBoundInterfaceState(float range, RadarObjectData[] objects)
|
||||||
|
{
|
||||||
|
Range = range;
|
||||||
|
Objects = objects;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public struct RadarObjectData
|
||||||
|
{
|
||||||
|
public Color Color;
|
||||||
|
public RadarObjectShape Shape;
|
||||||
|
public Vector2 Position;
|
||||||
|
public float Radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RadarObjectShape : byte
|
||||||
|
{
|
||||||
|
Circle,
|
||||||
|
CircleFilled,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum RadarConsoleUiKey : byte
|
||||||
|
{
|
||||||
|
Key
|
||||||
|
}
|
||||||
1
Resources/Locale/en-US/misc-computers.ftl
Normal file
1
Resources/Locale/en-US/misc-computers.ftl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
radar-window-title = Mass Scanner Console
|
||||||
@@ -67,6 +67,14 @@
|
|||||||
- type: ComputerBoard
|
- type: ComputerBoard
|
||||||
prototype: ComputerComms
|
prototype: ComputerComms
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseComputerCircuitboard
|
||||||
|
id: RadarConsoleCircuitboard
|
||||||
|
name: radar console computer board
|
||||||
|
components:
|
||||||
|
- type: ComputerBoard
|
||||||
|
prototype: ComputerRadar
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseComputerCircuitboard
|
parent: BaseComputerCircuitboard
|
||||||
id: SolarControlComputerCircuitboard
|
id: SolarControlComputerCircuitboard
|
||||||
|
|||||||
@@ -272,6 +272,32 @@
|
|||||||
energy: 1.6
|
energy: 1.6
|
||||||
color: "#e6e227"
|
color: "#e6e227"
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ComputerBase
|
||||||
|
id: ComputerRadar
|
||||||
|
name: mass scanner computer
|
||||||
|
description: A computer for detecting nearby bodies, displaying them by position and mass.
|
||||||
|
components:
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: ComputerVisualizer
|
||||||
|
key: generic_key
|
||||||
|
screen: solar_screen
|
||||||
|
- type: RadarConsole
|
||||||
|
- type: ActivatableUI
|
||||||
|
key: enum.RadarConsoleUiKey.Key
|
||||||
|
- type: ActivatableUIRequiresPower
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.RadarConsoleUiKey.Key
|
||||||
|
type: RadarConsoleBoundUserInterface
|
||||||
|
- type: Computer
|
||||||
|
board: RadarConsoleCircuitboard
|
||||||
|
- type: PointLight
|
||||||
|
radius: 1.5
|
||||||
|
energy: 1.6
|
||||||
|
color: "#e6e227"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ComputerSupplyOrdering
|
id: ComputerSupplyOrdering
|
||||||
parent: ComputerBase
|
parent: ComputerBase
|
||||||
|
|||||||
Reference in New Issue
Block a user