mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-06-09 13:26:34 +02:00
cbf1047c55
* option to reduce ai static overlay * wrong file path! * requested change
166 lines
5.9 KiB
C#
166 lines
5.9 KiB
C#
using System.Numerics;
|
|
using Content.Client.Graphics;
|
|
using Content.Shared.CCVar;
|
|
using Content.Shared.Silicons.StationAi;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.Configuration;
|
|
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 partial class StationAiOverlay : Overlay
|
|
{
|
|
private static readonly ProtoId<ShaderPrototype> CameraStaticShader = "CameraStatic";
|
|
private static readonly ProtoId<ShaderPrototype> CameraStaticAccessibleShader = "CameraStaticAccessible";
|
|
private static readonly ProtoId<ShaderPrototype> StencilMaskShader = "StencilMask";
|
|
private static readonly ProtoId<ShaderPrototype> StencilDrawShader = "StencilDraw";
|
|
|
|
[Dependency] private IClyde _clyde = default!;
|
|
[Dependency] private IConfigurationManager _cfg = default!;
|
|
[Dependency] private IEntityManager _entManager = default!;
|
|
[Dependency] private IGameTiming _timing = default!;
|
|
[Dependency] private IPlayerManager _player = default!;
|
|
[Dependency] private IPrototypeManager _proto = default!;
|
|
|
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
|
|
|
private readonly HashSet<Vector2i> _visibleTiles = new();
|
|
|
|
private readonly OverlayResourceCache<CachedResources> _resources = new();
|
|
|
|
private ProtoId<ShaderPrototype> _activeShader = CameraStaticShader;
|
|
private float _updateRate = 1f / 30f;
|
|
private float _accumulator;
|
|
|
|
public StationAiOverlay()
|
|
{
|
|
IoCManager.InjectDependencies(this);
|
|
_cfg.OnValueChanged(CCVars.DisableAiStatic, OnAiStaticChanged, invokeImmediately: true);
|
|
|
|
}
|
|
|
|
private void OnAiStaticChanged(bool toggle)
|
|
{
|
|
_activeShader = toggle ? CameraStaticAccessibleShader : CameraStaticShader;
|
|
}
|
|
|
|
protected override void Draw(in OverlayDrawArgs args)
|
|
{
|
|
var res = _resources.GetForViewport(args.Viewport, static _ => new CachedResources());
|
|
|
|
if (res.StencilTexture?.Texture.Size != args.Viewport.Size)
|
|
{
|
|
res.StaticTexture?.Dispose();
|
|
res.StencilTexture?.Dispose();
|
|
res.StencilTexture = _clyde.CreateRenderTarget(args.Viewport.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "station-ai-stencil");
|
|
res.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(res.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(res.StaticTexture!,
|
|
() =>
|
|
{
|
|
worldHandle.SetTransform(invMatrix);
|
|
var shader = _proto.Index(_activeShader).Instance();
|
|
worldHandle.UseShader(shader);
|
|
worldHandle.DrawRect(worldBounds, Color.White);
|
|
},
|
|
Color.Black);
|
|
}
|
|
// Not on a grid
|
|
else
|
|
{
|
|
worldHandle.RenderInRenderTarget(res.StencilTexture!, () =>
|
|
{
|
|
},
|
|
Color.Transparent);
|
|
|
|
worldHandle.RenderInRenderTarget(res.StaticTexture!,
|
|
() =>
|
|
{
|
|
worldHandle.SetTransform(Matrix3x2.Identity);
|
|
worldHandle.DrawRect(worldBounds, Color.Black);
|
|
}, Color.Black);
|
|
}
|
|
|
|
// Use the lighting as a mask
|
|
worldHandle.UseShader(_proto.Index(StencilMaskShader).Instance());
|
|
worldHandle.DrawTextureRect(res.StencilTexture!.Texture, worldBounds);
|
|
|
|
// Draw the static
|
|
worldHandle.UseShader(_proto.Index(StencilDrawShader).Instance());
|
|
worldHandle.DrawTextureRect(res.StaticTexture!.Texture, worldBounds);
|
|
|
|
worldHandle.SetTransform(Matrix3x2.Identity);
|
|
worldHandle.UseShader(null);
|
|
|
|
}
|
|
|
|
protected override void DisposeBehavior()
|
|
{
|
|
_resources.Dispose();
|
|
|
|
base.DisposeBehavior();
|
|
}
|
|
|
|
private sealed class CachedResources : IDisposable
|
|
{
|
|
public IRenderTexture? StaticTexture;
|
|
public IRenderTexture? StencilTexture;
|
|
|
|
public void Dispose()
|
|
{
|
|
StaticTexture?.Dispose();
|
|
StencilTexture?.Dispose();
|
|
}
|
|
}
|
|
}
|