119
Content.Client/Silicons/StationAi/StationAiOverlay.cs
Normal file
119
Content.Client/Silicons/StationAi/StationAiOverlay.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
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.Prototypes;
|
||||
|
||||
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 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;
|
||||
|
||||
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);
|
||||
|
||||
var invMatrix = args.Viewport.GetWorldToLocalMatrix();
|
||||
|
||||
if (grid != null)
|
||||
{
|
||||
// TODO: Pass in attached entity's grid.
|
||||
// TODO: Credit OD on the moved to code
|
||||
// TODO: Call the moved-to code here.
|
||||
|
||||
_visibleTiles.Clear();
|
||||
var lookups = _entManager.System<EntityLookupSystem>();
|
||||
var xforms = _entManager.System<SharedTransformSystem>();
|
||||
_entManager.System<StationAiVisionSystem>().GetView((gridUid, 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);
|
||||
|
||||
}
|
||||
}
|
||||
80
Content.Client/Silicons/StationAi/StationAiSystem.cs
Normal file
80
Content.Client/Silicons/StationAi/StationAiSystem.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Content.Shared.Silicons.StationAi;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Client.Silicons.StationAi;
|
||||
|
||||
public sealed partial class StationAiSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IOverlayManager _overlayMgr = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
private StationAiOverlay? _overlay;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
// InitializeAirlock();
|
||||
// InitializePowerToggle();
|
||||
|
||||
SubscribeLocalEvent<StationAiOverlayComponent, LocalPlayerAttachedEvent>(OnAiAttached);
|
||||
SubscribeLocalEvent<StationAiOverlayComponent, LocalPlayerDetachedEvent>(OnAiDetached);
|
||||
SubscribeLocalEvent<StationAiOverlayComponent, ComponentInit>(OnAiOverlayInit);
|
||||
SubscribeLocalEvent<StationAiOverlayComponent, ComponentRemove>(OnAiOverlayRemove);
|
||||
}
|
||||
|
||||
private void OnAiOverlayInit(Entity<StationAiOverlayComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
var attachedEnt = _player.LocalEntity;
|
||||
|
||||
if (attachedEnt != ent.Owner)
|
||||
return;
|
||||
|
||||
AddOverlay();
|
||||
}
|
||||
|
||||
private void OnAiOverlayRemove(Entity<StationAiOverlayComponent> ent, ref ComponentRemove args)
|
||||
{
|
||||
var attachedEnt = _player.LocalEntity;
|
||||
|
||||
if (attachedEnt != ent.Owner)
|
||||
return;
|
||||
|
||||
RemoveOverlay();
|
||||
}
|
||||
|
||||
private void AddOverlay()
|
||||
{
|
||||
if (_overlay != null)
|
||||
return;
|
||||
|
||||
_overlay = new StationAiOverlay();
|
||||
_overlayMgr.AddOverlay(_overlay);
|
||||
}
|
||||
|
||||
private void RemoveOverlay()
|
||||
{
|
||||
if (_overlay == null)
|
||||
return;
|
||||
|
||||
_overlayMgr.RemoveOverlay(_overlay);
|
||||
_overlay = null;
|
||||
}
|
||||
|
||||
private void OnAiAttached(Entity<StationAiOverlayComponent> ent, ref LocalPlayerAttachedEvent args)
|
||||
{
|
||||
AddOverlay();
|
||||
}
|
||||
|
||||
private void OnAiDetached(Entity<StationAiOverlayComponent> ent, ref LocalPlayerDetachedEvent args)
|
||||
{
|
||||
RemoveOverlay();
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
_overlayMgr.RemoveOverlay<StationAiOverlay>();
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,17 @@ using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.DecalPlacer;
|
||||
using Content.Client.UserInterface.Systems.Sandbox.Windows;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Silicons.StationAi;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.Debugging;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Client.UserInterface.Controllers.Implementations;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
@@ -27,10 +30,12 @@ namespace Content.Client.UserInterface.Systems.Sandbox;
|
||||
[UsedImplicitly]
|
||||
public sealed class SandboxUIController : UIController, IOnStateChanged<GameplayState>, IOnSystemChanged<SandboxSystem>
|
||||
{
|
||||
[Dependency] private readonly IConsoleHost _console = default!;
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
[Dependency] private readonly IInputManager _input = default!;
|
||||
[Dependency] private readonly ILightManager _light = default!;
|
||||
[Dependency] private readonly IClientAdminManager _admin = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
[UISystemDependency] private readonly DebugPhysicsSystem _debugPhysics = default!;
|
||||
[UISystemDependency] private readonly MarkerSystem _marker = default!;
|
||||
@@ -116,6 +121,21 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
|
||||
_window.ShowMarkersButton.Pressed = _marker.MarkersVisible;
|
||||
_window.ShowBbButton.Pressed = (_debugPhysics.Flags & PhysicsDebugFlags.Shapes) != 0x0;
|
||||
|
||||
_window.AiOverlayButton.OnPressed += args =>
|
||||
{
|
||||
var player = _player.LocalEntity;
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var pnent = EntityManager.GetNetEntity(player.Value);
|
||||
|
||||
// Need NetworkedAddComponent but engine PR.
|
||||
if (args.Button.Pressed)
|
||||
_console.ExecuteCommand($"addcomp {pnent.Id} StationAiOverlay");
|
||||
else
|
||||
_console.ExecuteCommand($"rmcomp {pnent.Id} StationAiOverlay");
|
||||
};
|
||||
_window.RespawnButton.OnPressed += _ => _sandbox.Respawn();
|
||||
_window.SpawnTilesButton.OnPressed += _ => TileSpawningController.ToggleWindow();
|
||||
_window.SpawnEntitiesButton.OnPressed += _ => EntitySpawningController.ToggleWindow();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Title="{Loc sandbox-window-title}"
|
||||
Resizable="False">
|
||||
<BoxContainer Orientation="Vertical" SeparationOverride="4">
|
||||
<Button Name="AiOverlayButton" Access="Public" Text="{Loc sandbox-window-ai-overlay-button}" ToggleMode="True"/>
|
||||
<Button Name="RespawnButton" Access="Public" Text="{Loc sandbox-window-respawn-button}"/>
|
||||
<Button Name="SpawnEntitiesButton" Access="Public" Text="{Loc sandbox-window-spawn-entities-button}"/>
|
||||
<Button Name="SpawnTilesButton" Access="Public" Text="{Loc sandbox-window-spawn-tiles-button}"/>
|
||||
|
||||
Reference in New Issue
Block a user