From 9b1a6dd57b9416d03650a77dd62b6f40f1ad402a Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Tue, 20 May 2025 14:36:08 +0200 Subject: [PATCH] add reduced motion drug overlay (#37584) * reduced motion flash effect * reduced motion drug overlay * Revert "reduced motion flash effect" This reverts commit e350b2899d0acc78c9833b5bc23a9680e03b2736. --- Content.Client/Drugs/DrugOverlaySystem.cs | 5 ++++ Content.Client/Drugs/RainbowOverlay.cs | 24 ++++++++++++----- Resources/Textures/Shaders/rainbow.swsl | 32 ++++++++++++++--------- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Content.Client/Drugs/DrugOverlaySystem.cs b/Content.Client/Drugs/DrugOverlaySystem.cs index 60fdf12f5e..608ae02842 100644 --- a/Content.Client/Drugs/DrugOverlaySystem.cs +++ b/Content.Client/Drugs/DrugOverlaySystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Drugs; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Player; +using Robust.Shared.Random; namespace Content.Client.Drugs; @@ -12,6 +13,7 @@ public sealed class DrugOverlaySystem : EntitySystem { [Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IOverlayManager _overlayMan = default!; + [Dependency] private readonly IRobustRandom _random = default!; private RainbowOverlay _overlay = default!; @@ -45,7 +47,10 @@ public sealed class DrugOverlaySystem : EntitySystem private void OnInit(EntityUid uid, SeeingRainbowsComponent component, ComponentInit args) { if (_player.LocalEntity == uid) + { + _overlay.Phase = _random.NextFloat(MathF.Tau); // random starting phase for movement effect _overlayMan.AddOverlay(_overlay); + } } private void OnShutdown(EntityUid uid, SeeingRainbowsComponent component, ComponentShutdown args) diff --git a/Content.Client/Drugs/RainbowOverlay.cs b/Content.Client/Drugs/RainbowOverlay.cs index fb48c91010..4e0bed1264 100644 --- a/Content.Client/Drugs/RainbowOverlay.cs +++ b/Content.Client/Drugs/RainbowOverlay.cs @@ -24,16 +24,27 @@ public sealed class RainbowOverlay : Overlay public float Intoxication = 0.0f; public float TimeTicker = 0.0f; + public float Phase = 0.0f; private const float VisualThreshold = 10.0f; private const float PowerDivisor = 250.0f; + private float _timeScale = 0.0f; + private float _warpScale = 0.0f; private float EffectScale => Math.Clamp((Intoxication - VisualThreshold) / PowerDivisor, 0.0f, 1.0f); public RainbowOverlay() { IoCManager.InjectDependencies(this); + _rainbowShader = _prototypeManager.Index("Rainbow").InstanceUnique(); + _config.OnValueChanged(CCVars.ReducedMotion, OnReducedMotionChanged, invokeImmediately: true); + } + + private void OnReducedMotionChanged(bool reducedMotion) + { + _timeScale = reducedMotion ? 0.0f : 1.0f; + _warpScale = reducedMotion ? 0.0f : 1.0f; } protected override void FrameUpdate(FrameEventArgs args) @@ -51,7 +62,7 @@ public sealed class RainbowOverlay : Overlay if (!statusSys.TryGetTime(playerEntity.Value, DrugOverlaySystem.RainbowKey, out var time, status)) return; - var timeLeft = (float) (time.Value.Item2 - time.Value.Item1).TotalSeconds; + var timeLeft = (float)(time.Value.Item2 - time.Value.Item1).TotalSeconds; TimeTicker += args.DeltaSeconds; @@ -61,7 +72,7 @@ public sealed class RainbowOverlay : Overlay } else { - Intoxication -= Intoxication/(timeLeft - TimeTicker) * args.DeltaSeconds; + Intoxication -= Intoxication / (timeLeft - TimeTicker) * args.DeltaSeconds; } } @@ -78,16 +89,15 @@ public sealed class RainbowOverlay : Overlay protected override void Draw(in OverlayDrawArgs args) { - // TODO disable only the motion part or ike's idea (single static frame of the overlay) - if (_config.GetCVar(CCVars.ReducedMotion)) - return; - if (ScreenTexture == null) return; var handle = args.WorldHandle; _rainbowShader.SetParameter("SCREEN_TEXTURE", ScreenTexture); - _rainbowShader.SetParameter("effectScale", EffectScale); + _rainbowShader.SetParameter("colorScale", EffectScale); + _rainbowShader.SetParameter("timeScale", _timeScale); + _rainbowShader.SetParameter("warpScale", _warpScale * EffectScale); + _rainbowShader.SetParameter("phase", Phase); handle.UseShader(_rainbowShader); handle.DrawRect(args.WorldBounds, Color.White); handle.UseShader(null); diff --git a/Resources/Textures/Shaders/rainbow.swsl b/Resources/Textures/Shaders/rainbow.swsl index 6e474abb1a..e622e1fa1a 100644 --- a/Resources/Textures/Shaders/rainbow.swsl +++ b/Resources/Textures/Shaders/rainbow.swsl @@ -1,12 +1,21 @@ uniform sampler2D SCREEN_TEXTURE; -uniform highp float effectScale; +// Strength of the rainbow color effect. Between 0 and 1. +uniform highp float colorScale; +// Strength of the screen warping effect. Between 0 and 1. +uniform highp float warpScale; +// How fast to do the rotating motion. +// 1 for normal effect. +// 0 for the reduced motion setting. +uniform highp float timeScale; +// starting phase for the rotation effect +// needed so it doesn't always look the same for 0 motion +uniform highp float phase; -const highp float TimeScale = 0.15; const highp float DistortionScale = 0.02; // how strongly to warp the screen const highp float NoiseScale = 4.0; // scale of the random noise const highp float MaxColorMix = 0.05; // rainbow effect strength. at 1.0, you wont be able to see the screen anymore const highp float BaseColorMult = 8.0; // multiplier of the underlying screen texture for the rainbow effect -const highp float BaseColorPow = 0.8; // exponent for the rainbow effect's +const highp float BaseColorPow = 0.8; // exponent for the rainbow effect's const highp float CenterRadius = 200.0; // radius of the gradient used to tone down the distortion effect const highp float CenterMinDist = 0.4; // minimum distance from the center of the screen for the distortion to appear at all const highp float CenterPow = 3.0; // the exponent used for the distortion center @@ -27,7 +36,7 @@ highp float noise( highp vec2 p ) { highp vec2 i = floor( p + (p.x+p.y)*K1 ); highp vec2 a = p - i + (i.x+i.y)*K2; - highp float m = step(a.y,a.x); + highp float m = step(a.y,a.x); highp vec2 o = vec2(m,1.0-m); highp vec2 b = a - o + K2; highp vec2 c = a - 1.0 + 2.0*K2; @@ -43,8 +52,8 @@ highp vec3 hsv2rgb_smooth( highp vec3 c ) { } -highp float mixNoise(highp vec2 point, highp float phase) { - highp float time = TIME * TimeScale + phase; +highp float mixNoise(highp vec2 point, highp float phase2) { + highp float time = TIME * timeScale * 0.15 + phase + phase2; highp float a = noise( NoiseScale * point - time); highp float b = noise( NoiseScale * point + time ); return mix(a,b,0.5); @@ -58,19 +67,16 @@ void fragment() { highp vec2 coord = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.xy; highp vec2 aspect = vec2(1.0/SCREEN_PIXEL_SIZE.x, 1.0/SCREEN_PIXEL_SIZE.y); highp vec2 center = aspect * 0.5; - + // warp the screen. highp vec2 offset = vec2(mixNoise(coord, 0.), mixNoise(coord, 5.)); highp float centergradient = genGradient(center, FRAGCOORD.xy, CenterRadius, CenterMinDist, CenterPow); - COLOR = zTextureSpec(SCREEN_TEXTURE, coord + effectScale * (DistortionScale * centergradient) * offset); - + COLOR = zTextureSpec(SCREEN_TEXTURE, coord + warpScale * (DistortionScale * centergradient) * offset); + // apply rainbow effect. highp float hue = 1. + mixNoise(coord, 10.); highp vec3 color = hsv2rgb_smooth(vec3(hue,1.0,1.0)); highp float centercolor = genGradient(center, FRAGCOORD.xy, CenterColorRadius, CenterColorMinDist, CenterColorPow); highp float coloration = pow((COLOR.x + COLOR.y + COLOR.z) * BaseColorMult, BaseColorPow) * centercolor; - COLOR.xyz = mix(COLOR.xyz, color, MaxColorMix * effectScale * effectScale * coloration); + COLOR.xyz = mix(COLOR.xyz, color, MaxColorMix * colorScale * colorScale * coloration); } - - - -- 2.51.2