| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- using Content.Client.Interactable.Components;
- using Content.Client.StatusIcon;
- using Content.Shared.Stealth;
- using Content.Shared.Stealth.Components;
- using Robust.Client.GameObjects;
- using Robust.Client.Graphics;
- using Robust.Shared.Prototypes;
- namespace Content.Client.Stealth;
- public sealed class StealthSystem : SharedStealthSystem
- {
- [Dependency] private readonly IPrototypeManager _protoMan = default!;
- [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
- private ShaderInstance _shader = default!;
- public override void Initialize()
- {
- base.Initialize();
- _shader = _protoMan.Index<ShaderPrototype>("Stealth").InstanceUnique();
- SubscribeLocalEvent<StealthComponent, ComponentShutdown>(OnShutdown);
- SubscribeLocalEvent<StealthComponent, ComponentStartup>(OnStartup);
- SubscribeLocalEvent<StealthComponent, BeforePostShaderRenderEvent>(OnShaderRender);
- }
- public override void SetEnabled(EntityUid uid, bool value, StealthComponent? component = null)
- {
- if (!Resolve(uid, ref component) || component.Enabled == value)
- return;
- base.SetEnabled(uid, value, component);
- SetShader(uid, value, component);
- }
- private void SetShader(EntityUid uid, bool enabled, StealthComponent? component = null, SpriteComponent? sprite = null)
- {
- if (!Resolve(uid, ref component, ref sprite, false))
- return;
- sprite.Color = Color.White;
- sprite.PostShader = enabled ? _shader : null;
- sprite.GetScreenTexture = enabled;
- sprite.RaiseShaderEvent = enabled;
- if (!enabled)
- {
- if (component.HadOutline && !TerminatingOrDeleted(uid))
- EnsureComp<InteractionOutlineComponent>(uid);
- return;
- }
- if (TryComp(uid, out InteractionOutlineComponent? outline))
- {
- RemCompDeferred(uid, outline);
- component.HadOutline = true;
- }
- }
- private void OnStartup(EntityUid uid, StealthComponent component, ComponentStartup args)
- {
- SetShader(uid, component.Enabled, component);
- }
- private void OnShutdown(EntityUid uid, StealthComponent component, ComponentShutdown args)
- {
- if (!Terminating(uid))
- SetShader(uid, false, component);
- }
- private void OnShaderRender(EntityUid uid, StealthComponent component, BeforePostShaderRenderEvent args)
- {
- // Distortion effect uses screen coordinates. If a player moves, the entities appear to move on screen. this
- // makes the distortion very noticeable.
- // So we need to use relative screen coordinates. The reference frame we use is the parent's position on screen.
- // this ensures that if the Stealth is not moving relative to the parent, its relative screen position remains
- // unchanged.
- var parent = Transform(uid).ParentUid;
- if (!parent.IsValid())
- return; // should never happen, but lets not kill the client.
- var parentXform = Transform(parent);
- var reference = args.Viewport.WorldToLocal(_transformSystem.GetWorldPosition(parentXform));
- reference.X = -reference.X;
- var visibility = GetVisibility(uid, component);
- // actual visual visibility effect is limited to +/- 1.
- visibility = Math.Clamp(visibility, -1f, 1f);
- _shader.SetParameter("reference", reference);
- _shader.SetParameter("visibility", visibility);
- visibility = MathF.Max(0, visibility);
- args.Sprite.Color = new Color(visibility, visibility, 1, 1);
- }
- }
|