Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgencheg committed Aug 13, 2024
2 parents e27132e + d056c64 commit 6d2b4df
Show file tree
Hide file tree
Showing 33 changed files with 2,222 additions and 2 deletions.
42 changes: 42 additions & 0 deletions Content.Client/Administration/AdminNameOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,48 @@ public AdminNameOverlay(AdminSystem system, IEntityManager entityManager, IEyeMa

public override OverlaySpace Space => OverlaySpace.ScreenSpace;

// start _Backmen: AI

private void DrawVisitedOwner(in Content.Shared.Administration.PlayerInfo playerInfo, in OverlayDrawArgs args)
{
var entity = _entityManager.GetEntity(playerInfo.NetEntity);

// Otherwise the entity can not exist yet
if (entity == null || !_entityManager.EntityExists(entity))
{
return;
}

// if not on the same map, continue
if (_entityManager.GetComponent<TransformComponent>(entity.Value).MapID != _eyeManager.CurrentMap)
{
return;
}

var aabb = _entityLookup.GetWorldAABB(entity.Value);

// if not on screen, continue
if (!aabb.Intersects(in args.WorldAABB))
{
return;
}

var lineoffset = new Vector2(0f, 11f);
var screenCoordinates = _eyeManager.WorldToScreen(aabb.Center +
new Angle(-_eyeManager.CurrentEye.Rotation).RotateVec(
aabb.TopRight - aabb.Center)) + new Vector2(1f, 7f);
if (playerInfo.Antag)
{
args.ScreenHandle.DrawString(_font, screenCoordinates + (lineoffset * 3), "ANTAG", Color.OrangeRed);
}
args.ScreenHandle.DrawString(_font, screenCoordinates + lineoffset, playerInfo.Username, playerInfo.Connected ? Color.Yellow : Color.White);
args.ScreenHandle.DrawString(_font, screenCoordinates, playerInfo.CharacterName, playerInfo.Connected ? Color.Aquamarine : Color.White);

args.ScreenHandle.DrawString(_font, screenCoordinates + (lineoffset * 2), "(In REMOTE)", Color.Cyan);
}

// end _Backmen: AI

protected override void Draw(in OverlayDrawArgs args)
{
var viewport = args.WorldAABB;
Expand Down
127 changes: 127 additions & 0 deletions Content.Client/_Backmen/StationAI/AiCamOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System.Numerics;
using Content.Client.Parallax;
using Content.Client.Weather;
using Content.Shared._Backmen.StationAI;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client._Backmen.StationAI;

public sealed class AiCamOverlay : Overlay
{
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IPlayerManager _player = default!;

private readonly ParallaxSystem _parallax;
private readonly SharedTransformSystem _transform;
private readonly SpriteSystem _sprite;
private readonly StationAiSystem _aiSystem;


public override OverlaySpace Space => OverlaySpace.WorldSpace;

private IRenderTexture? _blep;

private readonly ShaderInstance _shader;

public AiCamOverlay(ParallaxSystem parallax, SharedTransformSystem transform, SpriteSystem sprite, StationAiSystem aiSystem)
{
ZIndex = ParallaxSystem.ParallaxZIndex + 1;
_parallax = parallax;
_transform = transform;
_sprite = sprite;
_aiSystem = aiSystem;
IoCManager.InjectDependencies(this);
_shader = _protoManager.Index<ShaderPrototype>("WorldGradientCircle").InstanceUnique();
}

protected override void Draw(in OverlayDrawArgs args)
{
var playerUid = _player.LocalSession?.AttachedEntity;
if (playerUid is not { Valid: true })
return;

if (!_entManager.TryGetComponent<AIEyeComponent>(playerUid, out var eyeComponent))
{
return;
}

var invMatrix = args.Viewport.GetWorldToLocalMatrix();

if (_blep?.Texture.Size != args.Viewport.Size)
{
_blep?.Dispose();
_blep = _clyde.CreateRenderTarget(args.Viewport.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "aicam-stencil");
}

if (eyeComponent.Camera != null)
{
DrawRestrictedRange(args, eyeComponent, invMatrix);
}

args.WorldHandle.UseShader(null);
args.WorldHandle.SetTransform(Matrix3.Identity);
}

private void DrawRestrictedRange(in OverlayDrawArgs args, AIEyeComponent eyeComponent, Matrix3 invMatrix)
{
var pos = _transform.GetMapCoordinates(eyeComponent.Camera!.Value);

var worldHandle = args.WorldHandle;
var renderScale = args.Viewport.RenderScale.X;
// TODO: This won't handle non-standard zooms so uhh yeah, not sure how to structure it on the shader side.
var zoom = args.Viewport.Eye?.Zoom ?? Vector2.One;
var length = zoom.X;
var bufferRange = MathF.Min(10f, SharedStationAISystem.CameraEyeRange);

var pixelCenter = pos.Position;//Vector2.Transform(pos.Position, invMatrix);
// Something something offset?
var vertical = args.Viewport.Size.Y;

var pixelMaxRange = SharedStationAISystem.CameraEyeRange * renderScale / length * EyeManager.PixelsPerMeter;
var pixelBufferRange = bufferRange * renderScale / length * EyeManager.PixelsPerMeter;
var pixelMinRange = pixelMaxRange - pixelBufferRange;

_shader.SetParameter("position", new Vector2(pixelCenter.X, vertical - pixelCenter.Y));
_shader.SetParameter("maxRange", pixelMaxRange);
_shader.SetParameter("minRange", pixelMinRange);
_shader.SetParameter("bufferRange", pixelBufferRange);
_shader.SetParameter("gradient", 0.80f);

var worldAABB = args.WorldAABB;
var worldBounds = args.WorldBounds;
var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero;
var localAABB = invMatrix.TransformBox(worldAABB);

// Cut out the irrelevant bits via stencil
// This is why we don't just use parallax; we might want specific tiles to get drawn over
// particularly for planet maps or stations.
worldHandle.RenderInRenderTarget(_blep!,
() =>
{
worldHandle.UseShader(_shader);
worldHandle.DrawRect(localAABB, Color.White);
},
Color.Transparent);

worldHandle.SetTransform(Matrix3.Identity);
worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilMask").Instance());
worldHandle.DrawTextureRect(_blep!.Texture, worldBounds);
var curTime = _timing.RealTime;
var sprite = _sprite.GetFrame(new SpriteSpecifier.Texture(new ResPath("/Textures/Parallaxes/aicam.png")), curTime);

// Draw the fog
worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilDraw").Instance());
_parallax.DrawParallax(worldHandle, worldAABB, sprite, curTime, position, new Vector2(0.5f, 0f));
}
}
42 changes: 42 additions & 0 deletions Content.Client/_Backmen/StationAI/AiEnemySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Content.Shared._Backmen.StationAI;
using Content.Shared._Backmen.StationAI.Components;
using Content.Shared._Backmen.StationAI.Systems;
using Content.Shared.Ghost;
using Content.Shared.Silicons.Borgs.Components;
using Content.Shared.StatusIcon;
using Content.Shared.StatusIcon.Components;
using Robust.Client.Player;
using Robust.Shared.Prototypes;

namespace Content.Client._Backmen.StationAI;

public sealed class AiEnemySystem : SharedAiEnemySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<AIEnemyNTComponent, GetStatusIconsEvent>(GetIcon);
}

protected override void ToggleEnemy(EntityUid u, EntityUid target)
{
//noop
}

[ValidatePrototypeId<StatusIconPrototype>]
private const string AiEnemyStatus = "AiIconEnemyTarget";
private void GetIcon(Entity<AIEnemyNTComponent> target, ref GetStatusIconsEvent args)
{
var ent = _player.LocalSession?.AttachedEntity ?? EntityUid.Invalid;

if (!EntityQuery.HasComponent(ent))
{
return;
}
args.StatusIcons.Add(_prototype.Index<StatusIconPrototype>(AiEnemyStatus));
}
}
99 changes: 99 additions & 0 deletions Content.Client/_Backmen/StationAI/AiVisualizerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System.Linq;
using Content.Client.Power;
using Content.Shared._Backmen.StationAI;
using Content.Shared._Backmen.StationAI.UI;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;

namespace Content.Client._Backmen.StationAI;

public sealed class AiVisualizerSystem : VisualizerSystem<StationAIComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
private EntityQuery<AIEyeComponent> _aiEye;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<StationAIComponent, AfterAutoHandleStateEvent>(OnUpdate);

_aiEye = GetEntityQuery<AIEyeComponent>();
}

protected override void OnAppearanceChange(EntityUid uid, StationAIComponent component, ref AppearanceChangeEvent args)
{
if (_aiEye.HasComp(uid))
{
base.OnAppearanceChange(uid, component, ref args);
return;
}

UpdateAppearance(uid, component, args.Component, args.Sprite);
}

private void OnUpdate(Entity<StationAIComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (_aiEye.HasComp(ent))
{
return;
}
if (
!ent.Comp.Layers.ContainsKey(ent.Comp.SelectedLayer) ||
!TryComp<MetaDataComponent>(ent, out var metaDataComponent) ||
metaDataComponent.EntityPrototype == null ||
!_prototypeManager.TryIndex<EntityPrototype>(metaDataComponent.EntityPrototype.ID, out var proto) ||
!proto.TryGetComponent<SpriteComponent>(out var spriteProtoComponent)
)
{
return;
}

var spriteComponent = (SpriteComponent) _serialization.CreateCopy(spriteProtoComponent, notNullableOverride: true);

var layers = ent.Comp.Layers[ent.Comp.SelectedLayer];

foreach (var layer in layers)
{
spriteComponent.AddLayer(layer);
}

AddComp(ent, spriteComponent, true);

UpdateAppearance(ent, ent, sprite: spriteComponent);
}

private void UpdateAppearance(EntityUid id, StationAIComponent sign, AppearanceComponent? appearance = null,
SpriteComponent? sprite = null)
{
if (!Resolve(id, ref appearance, ref sprite))
return;

if (_aiEye.HasComp(id))
{
return;
}

AppearanceSystem.TryGetData<bool>(id, PowerDeviceVisuals.Powered, out var powered, appearance);
AppearanceSystem.TryGetData<bool>(id, AiVisuals.Dead, out var dead, appearance);
AppearanceSystem.TryGetData<bool>(id, AiVisuals.InEye, out var inEye, appearance);

if (sprite.LayerMapTryGet(AiVisualLayers.NotInEye, out var eyeLayer))
{
sprite.LayerSetVisible(eyeLayer, powered && !inEye && !dead);
}

if (sprite.LayerMapTryGet(AiVisualLayers.Dead, out var deadLayer))
{
sprite.LayerSetVisible(deadLayer, powered && dead);
}

if (sprite.LayerMapTryGet(PowerDeviceVisualLayers.Powered, out var poweredLayer))
{
sprite.LayerSetVisible(poweredLayer, powered && !dead);
}
}
}
Loading

0 comments on commit 6d2b4df

Please sign in to comment.