mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-01 17:47:24 +02:00
* [Dependency] source generator No more reflection, no more codegen at runtime Also various changes to Roslyn helpers to make this easier to write. Requires all types with dependencies to be partial and not have readonly dependency fields. An analyzer enforces this at warning level, the previous injection strategies have remained in the code *for now* as a fallback. No fallback is available for [field: Dependency] properties, due to a Roslyn bug. Code Fixes exist. We love Roslyn * Apply dependencies generator changes to all code * Release notes * Preprocessor got hands * Handle nullable dependencies These are bad but gotta deal with it. * Apply suggestions from code review Co-authored-by: Moony <moony@hellomouse.net> * Fine, let's not use collection expressions --------- Co-authored-by: Moony <moony@hellomouse.net>
222 lines
7.2 KiB
C#
222 lines
7.2 KiB
C#
using Robust.Client.Graphics;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Physics.Components;
|
|
using System.Numerics;
|
|
|
|
namespace Robust.Client.Debugging;
|
|
|
|
/// <summary>
|
|
/// A collection of visual debug overlays for the client game.
|
|
/// </summary>
|
|
public sealed partial class DebugDrawingSystem : EntitySystem
|
|
{
|
|
[Dependency] private IOverlayManager _overlayManager = default!;
|
|
[Dependency] private EntityLookupSystem _lookup = default!;
|
|
[Dependency] private SharedTransformSystem _transform = default!;
|
|
|
|
private bool _debugPositions;
|
|
private bool _debugRotations;
|
|
private bool _debugVelocities;
|
|
private bool _debugAngularVelocities;
|
|
|
|
/// <summary>
|
|
/// Toggles the visual overlay of the local origin for each entity on screen.
|
|
/// </summary>
|
|
public bool DebugPositions
|
|
{
|
|
get => _debugPositions;
|
|
set
|
|
{
|
|
if (value == DebugPositions)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_debugPositions = value;
|
|
|
|
if (value && !_overlayManager.HasOverlay<EntityPositionOverlay>())
|
|
{
|
|
_overlayManager.AddOverlay(new EntityPositionOverlay(_lookup, _transform));
|
|
}
|
|
else
|
|
{
|
|
_overlayManager.RemoveOverlay<EntityPositionOverlay>();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggles the visual overlay of the rotation for each entity on screen.
|
|
/// </summary>
|
|
public bool DebugRotations
|
|
{
|
|
get => _debugRotations;
|
|
set
|
|
{
|
|
if (value == DebugRotations)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_debugRotations = value;
|
|
|
|
if (value && !_overlayManager.HasOverlay<EntityRotationOverlay>())
|
|
{
|
|
_overlayManager.AddOverlay(new EntityRotationOverlay(_lookup, _transform));
|
|
}
|
|
else
|
|
{
|
|
_overlayManager.RemoveOverlay<EntityRotationOverlay>();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggles the visual overlay of the local velocity for each entity on screen.
|
|
/// </summary>
|
|
public bool DebugVelocities
|
|
{
|
|
get => _debugVelocities;
|
|
set
|
|
{
|
|
if (value == DebugVelocities)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_debugVelocities = value;
|
|
|
|
if (value && !_overlayManager.HasOverlay<EntityVelocityOverlay>())
|
|
{
|
|
_overlayManager.AddOverlay(new EntityVelocityOverlay(EntityManager, _lookup, _transform));
|
|
}
|
|
else
|
|
{
|
|
_overlayManager.RemoveOverlay<EntityVelocityOverlay>();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggles the visual overlay of the angular velocity for each entity on screen.
|
|
/// </summary>
|
|
public bool DebugAngularVelocities
|
|
{
|
|
get => _debugAngularVelocities;
|
|
set
|
|
{
|
|
if (value == DebugAngularVelocities)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_debugAngularVelocities = value;
|
|
|
|
if (value && !_overlayManager.HasOverlay<EntityAngularVelocityOverlay>())
|
|
{
|
|
_overlayManager.AddOverlay(new EntityAngularVelocityOverlay(EntityManager, _lookup, _transform));
|
|
}
|
|
else
|
|
{
|
|
_overlayManager.RemoveOverlay<EntityAngularVelocityOverlay>();
|
|
}
|
|
}
|
|
}
|
|
private sealed class EntityPositionOverlay(EntityLookupSystem _lookup, SharedTransformSystem _transform) : Overlay
|
|
{
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
protected internal override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
const float stubLength = 0.25f;
|
|
|
|
var worldHandle = (DrawingHandleWorld)args.DrawingHandle;
|
|
|
|
foreach (var uid in _lookup.GetEntitiesIntersecting(args.MapId, args.WorldBounds))
|
|
{
|
|
var (center, worldRotation) = _transform.GetWorldPositionRotation(uid);
|
|
|
|
var xLine = worldRotation.RotateVec(Vector2.UnitX);
|
|
var yLine = worldRotation.RotateVec(Vector2.UnitY);
|
|
|
|
worldHandle.DrawLine(center, center + xLine * stubLength, Color.Red);
|
|
worldHandle.DrawLine(center, center + yLine * stubLength, Color.Green);
|
|
}
|
|
}
|
|
}
|
|
|
|
private sealed class EntityRotationOverlay(EntityLookupSystem _lookup, SharedTransformSystem _transform) : Overlay
|
|
{
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
protected internal override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
const float stubLength = 0.25f;
|
|
var worldHandle = (DrawingHandleWorld)args.DrawingHandle;
|
|
|
|
foreach (var uid in _lookup.GetEntitiesIntersecting(args.MapId, args.WorldBounds))
|
|
{
|
|
var (center, worldRotation) = _transform.GetWorldPositionRotation(uid);
|
|
|
|
var drawLine = worldRotation.RotateVec(-Vector2.UnitY);
|
|
|
|
worldHandle.DrawLine(center, center + drawLine * stubLength, Color.Red);
|
|
}
|
|
}
|
|
}
|
|
|
|
private sealed class EntityVelocityOverlay(IEntityManager _entityManager, EntityLookupSystem _lookup, SharedTransformSystem _transform) : Overlay
|
|
{
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
protected internal override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
const float multiplier = 0.2f;
|
|
|
|
var worldHandle = (DrawingHandleWorld)args.DrawingHandle;
|
|
|
|
var physicsQuery = _entityManager.GetEntityQuery<PhysicsComponent>();
|
|
foreach (var uid in _lookup.GetEntitiesIntersecting(args.MapId, args.WorldBounds))
|
|
{
|
|
if (!physicsQuery.TryGetComponent(uid, out var physicsComp))
|
|
continue;
|
|
|
|
var center = _transform.GetWorldPosition(uid);
|
|
var localVelocity = physicsComp.LinearVelocity;
|
|
|
|
if (localVelocity != Vector2.Zero)
|
|
worldHandle.DrawLine(center, center + localVelocity * multiplier, Color.Yellow);
|
|
}
|
|
}
|
|
}
|
|
|
|
private sealed class EntityAngularVelocityOverlay(IEntityManager _entityManager, EntityLookupSystem _lookup, SharedTransformSystem _transform) : Overlay
|
|
{
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
protected internal override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
const float multiplier = (float)(0.2 / (2 * System.Math.PI));
|
|
|
|
var worldHandle = (DrawingHandleWorld)args.DrawingHandle;
|
|
|
|
var physicsQuery = _entityManager.GetEntityQuery<PhysicsComponent>();
|
|
foreach (var uid in _lookup.GetEntitiesIntersecting(args.MapId, args.WorldBounds))
|
|
{
|
|
if (!physicsQuery.TryGetComponent(uid, out var physicsComp))
|
|
continue;
|
|
|
|
var center = _transform.GetWorldPosition(uid);
|
|
var angularVelocity = physicsComp.AngularVelocity;
|
|
|
|
if (angularVelocity != 0.0f)
|
|
worldHandle.DrawCircle(center, angularVelocity * multiplier, angularVelocity > 0 ? Color.Magenta : Color.Blue, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|