129 lines
4.6 KiB
C#
129 lines
4.6 KiB
C#
using System.Numerics;
|
|
using Content.Shared.Silicons.StationAi;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Physics;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Client.Silicons.StationAi;
|
|
|
|
public sealed class StationAiOverlay : Overlay
|
|
{
|
|
[Dependency] private readonly IClyde _clyde = default!;
|
|
[Dependency] private readonly IEntityManager _entManager = default!;
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
[Dependency] private readonly IPlayerManager _player = default!;
|
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
|
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
private readonly HashSet<Vector2i> _visibleTiles = new();
|
|
|
|
private IRenderTexture? _staticTexture;
|
|
private IRenderTexture? _stencilTexture;
|
|
|
|
private float _updateRate = 1f / 30f;
|
|
private float _accumulator;
|
|
|
|
public StationAiOverlay()
|
|
{
|
|
IoCManager.InjectDependencies(this);
|
|
}
|
|
|
|
protected override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
if (_stencilTexture?.Texture.Size != args.Viewport.Size)
|
|
{
|
|
_staticTexture?.Dispose();
|
|
_stencilTexture?.Dispose();
|
|
_stencilTexture = _clyde.CreateRenderTarget(args.Viewport.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "station-ai-stencil");
|
|
_staticTexture = _clyde.CreateRenderTarget(args.Viewport.Size,
|
|
new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb),
|
|
name: "station-ai-static");
|
|
}
|
|
|
|
var worldHandle = args.WorldHandle;
|
|
|
|
var worldBounds = args.WorldBounds;
|
|
|
|
var playerEnt = _player.LocalEntity;
|
|
_entManager.TryGetComponent(playerEnt, out TransformComponent? playerXform);
|
|
var gridUid = playerXform?.GridUid ?? EntityUid.Invalid;
|
|
_entManager.TryGetComponent(gridUid, out MapGridComponent? grid);
|
|
_entManager.TryGetComponent(gridUid, out BroadphaseComponent? broadphase);
|
|
|
|
var invMatrix = args.Viewport.GetWorldToLocalMatrix();
|
|
_accumulator -= (float) _timing.FrameTime.TotalSeconds;
|
|
|
|
if (grid != null && broadphase != null)
|
|
{
|
|
var lookups = _entManager.System<EntityLookupSystem>();
|
|
var xforms = _entManager.System<SharedTransformSystem>();
|
|
|
|
if (_accumulator <= 0f)
|
|
{
|
|
_accumulator = MathF.Max(0f, _accumulator + _updateRate);
|
|
_visibleTiles.Clear();
|
|
_entManager.System<StationAiVisionSystem>().GetView((gridUid, broadphase, grid), worldBounds, _visibleTiles);
|
|
}
|
|
|
|
var gridMatrix = xforms.GetWorldMatrix(gridUid);
|
|
var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
|
|
|
|
// Draw visible tiles to stencil
|
|
worldHandle.RenderInRenderTarget(_stencilTexture!, () =>
|
|
{
|
|
worldHandle.SetTransform(matty);
|
|
|
|
foreach (var tile in _visibleTiles)
|
|
{
|
|
var aabb = lookups.GetLocalBounds(tile, grid.TileSize);
|
|
worldHandle.DrawRect(aabb, Color.White);
|
|
}
|
|
},
|
|
Color.Transparent);
|
|
|
|
// Once this is gucci optimise rendering.
|
|
worldHandle.RenderInRenderTarget(_staticTexture!,
|
|
() =>
|
|
{
|
|
worldHandle.SetTransform(invMatrix);
|
|
var shader = _proto.Index<ShaderPrototype>("CameraStatic").Instance();
|
|
worldHandle.UseShader(shader);
|
|
worldHandle.DrawRect(worldBounds, Color.White);
|
|
},
|
|
Color.Black);
|
|
}
|
|
// Not on a grid
|
|
else
|
|
{
|
|
worldHandle.RenderInRenderTarget(_stencilTexture!, () =>
|
|
{
|
|
},
|
|
Color.Transparent);
|
|
|
|
worldHandle.RenderInRenderTarget(_staticTexture!,
|
|
() =>
|
|
{
|
|
worldHandle.SetTransform(Matrix3x2.Identity);
|
|
worldHandle.DrawRect(worldBounds, Color.Black);
|
|
}, Color.Black);
|
|
}
|
|
|
|
// Use the lighting as a mask
|
|
worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilMask").Instance());
|
|
worldHandle.DrawTextureRect(_stencilTexture!.Texture, worldBounds);
|
|
|
|
// Draw the static
|
|
worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilDraw").Instance());
|
|
worldHandle.DrawTextureRect(_staticTexture!.Texture, worldBounds);
|
|
|
|
worldHandle.SetTransform(Matrix3x2.Identity);
|
|
worldHandle.UseShader(null);
|
|
|
|
}
|
|
}
|