Files
tbd-station-14/Content.Client/Holopad/HolopadSystem.cs
Pieter-Jan Briers af4ff4e9de Update content to remove redundant Robust math types (#38930)
Vector3, Vector4, Matrix4, and Quaternion are now gone. This switches us over to System.Numerics where applicable.
2025-07-22 12:29:17 +02:00

135 lines
5.2 KiB
C#

using Content.Shared.Chat.TypingIndicator;
using Content.Shared.Holopad;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Linq;
using System.Numerics;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
namespace Content.Client.Holopad;
public sealed class HolopadSystem : SharedHolopadSystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<HolopadHologramComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<HolopadHologramComponent, BeforePostShaderRenderEvent>(OnShaderRender);
SubscribeAllEvent<TypingChangedEvent>(OnTypingChanged);
}
private void OnComponentStartup(Entity<HolopadHologramComponent> entity, ref ComponentStartup ev)
{
UpdateHologramSprite(entity, entity.Comp.LinkedEntity);
}
private void OnShaderRender(Entity<HolopadHologramComponent> entity, ref BeforePostShaderRenderEvent ev)
{
if (ev.Sprite.PostShader == null)
return;
UpdateHologramSprite(entity, entity.Comp.LinkedEntity);
}
private void OnTypingChanged(TypingChangedEvent ev, EntitySessionEventArgs args)
{
var uid = args.SenderSession.AttachedEntity;
if (!Exists(uid))
return;
if (!HasComp<HolopadUserComponent>(uid))
return;
var netEv = new HolopadUserTypingChangedEvent(GetNetEntity(uid.Value), ev.State);
RaiseNetworkEvent(netEv);
}
private void UpdateHologramSprite(EntityUid hologram, EntityUid? target)
{
// Get required components
if (!TryComp<SpriteComponent>(hologram, out var hologramSprite) ||
!TryComp<HolopadHologramComponent>(hologram, out var holopadhologram))
return;
// Remove all sprite layers
for (var i = hologramSprite.AllLayers.Count() - 1; i >= 0; i--)
_sprite.RemoveLayer((hologram, hologramSprite), i);
if (TryComp<SpriteComponent>(target, out var targetSprite))
{
// Use the target's holographic avatar (if available)
if (TryComp<HolographicAvatarComponent>(target, out var targetAvatar) &&
targetAvatar.LayerData != null)
{
for (var i = 0; i < targetAvatar.LayerData.Length; i++)
{
_sprite.AddLayer((hologram, hologramSprite), targetAvatar.LayerData[i], i);
}
}
// Otherwise copy the target's current physical appearance
else
{
_sprite.CopySprite((target.Value, targetSprite), (hologram, hologramSprite));
}
}
// There is no target, display a default sprite instead (if available)
else
{
if (string.IsNullOrEmpty(holopadhologram.RsiPath) || string.IsNullOrEmpty(holopadhologram.RsiState))
return;
var layer = new PrototypeLayerData
{
RsiPath = holopadhologram.RsiPath,
State = holopadhologram.RsiState
};
_sprite.AddLayer((hologram, hologramSprite), layer, null);
}
// Override specific values
_sprite.SetColor((hologram, hologramSprite), Color.White);
_sprite.SetOffset((hologram, hologramSprite), holopadhologram.Offset);
_sprite.SetDrawDepth((hologram, hologramSprite), (int)DrawDepth.Mobs);
hologramSprite.NoRotation = true;
hologramSprite.DirectionOverride = Direction.South;
hologramSprite.EnableDirectionOverride = true;
// Remove shading from all layers (except displacement maps)
for (var i = 0; i < hologramSprite.AllLayers.Count(); i++)
{
if (_sprite.TryGetLayer((hologram, hologramSprite), i, out var layer, false) && layer.ShaderPrototype != "DisplacedDraw")
hologramSprite.LayerSetShader(i, "unshaded");
}
UpdateHologramShader(hologram, hologramSprite, holopadhologram);
}
private void UpdateHologramShader(EntityUid uid, SpriteComponent sprite, HolopadHologramComponent holopadHologram)
{
// Find the texture height of the largest layer
float texHeight = sprite.AllLayers.Max(x => x.PixelSize.Y);
var instance = _prototypeManager.Index<ShaderPrototype>(holopadHologram.ShaderName).InstanceUnique();
instance.SetParameter("color1", new Vector3(holopadHologram.Color1.R, holopadHologram.Color1.G, holopadHologram.Color1.B));
instance.SetParameter("color2", new Vector3(holopadHologram.Color2.R, holopadHologram.Color2.G, holopadHologram.Color2.B));
instance.SetParameter("alpha", holopadHologram.Alpha);
instance.SetParameter("intensity", holopadHologram.Intensity);
instance.SetParameter("texHeight", texHeight);
instance.SetParameter("t", (float)_timing.CurTime.TotalSeconds * holopadHologram.ScrollRate);
sprite.PostShader = instance;
sprite.RaiseShaderEvent = true;
}
}