]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Blindness refactor (#15705)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sat, 29 Apr 2023 05:32:14 +0000 (17:32 +1200)
committerGitHub <noreply@github.com>
Sat, 29 Apr 2023 05:32:14 +0000 (15:32 +1000)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
34 files changed:
Content.Client/Examine/ExamineSystem.cs
Content.Client/Eye/Blinding/BlindOverlay.cs
Content.Client/Eye/Blinding/BlindingSystem.cs
Content.Client/Eye/Blinding/BlurryVisionOverlay.cs
Content.Client/Eye/Blinding/BlurryVisionSystem.cs
Content.Server/Chemistry/ReagentEffects/ChemHealEyeDamage.cs
Content.Server/Eye/Blinding/ActivatableUIRequiresVisionSystem.cs
Content.Server/Eye/Blinding/EyeProtection/EyeProtectionSystem.cs
Content.Server/Flash/FlashSystem.cs
Content.Shared/Bed/Sleep/SharedSleepingSystem.cs
Content.Shared/Examine/ExamineSystemShared.cs
Content.Shared/Eye/Blinding/BlindableComponent.cs [deleted file]
Content.Shared/Eye/Blinding/BlindfoldComponent.cs [deleted file]
Content.Shared/Eye/Blinding/BlurryVisionComponent.cs [deleted file]
Content.Shared/Eye/Blinding/Components/BlindableComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/BlindfoldComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/BlurryVisionComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/EyeProtectionComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/RequiresEyeProtectionComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Components/VisionCorrectionComponent.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/EyeProtection/EyeProtectionComponent.cs [deleted file]
Content.Shared/Eye/Blinding/EyeProtection/RequiresEyeProtectionComponent.cs [deleted file]
Content.Shared/Eye/Blinding/SharedBlindingSystem.cs [deleted file]
Content.Shared/Eye/Blinding/Systems/BlindableSystem.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Systems/BlindfoldSystem.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs [new file with mode: 0644]
Content.Shared/Eye/Blinding/TemporaryBlindnessComponent.cs [deleted file]
Content.Shared/Eye/Blinding/VisionCorrectionComponent.cs [deleted file]
Content.Shared/Inventory/InventorySystem.Relay.cs
Content.Shared/Traits/Assorted/PermanentBlindnessSystem.cs
Resources/Prototypes/Shaders/shaders.yml
Resources/Textures/Shaders/dim.swsl [deleted file]

index 9b3e209c3bdeec15c0c06b72fac4193968c777b8..a33671c3dba1c060bfcc4b2f6653d22ae21e7b65 100644 (file)
@@ -15,6 +15,7 @@ using Robust.Shared.Map;
 using Robust.Shared.Utility;
 using System.Linq;
 using System.Threading;
+using Content.Shared.Eye.Blinding.Components;
 using static Content.Shared.Interaction.SharedInteractionSystem;
 using static Robust.Client.UserInterface.Controls.BoxContainer;
 
index fc7367d715c36caf5ee63b85b9c31196957c3f39..1ade23c14d5c147ce8296b9f0e959ab8e3c52f06 100644 (file)
@@ -4,6 +4,7 @@ using Robust.Client.Player;
 using Robust.Shared.Enums;
 using Robust.Shared.Prototypes;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Components;
 
 namespace Content.Client.Eye.Blinding
 {
@@ -46,7 +47,7 @@ namespace Content.Client.Eye.Blinding
 
             _blindableComponent = blindComp;
 
-            var blind = _blindableComponent.Sources > 0;
+            var blind = _blindableComponent.IsBlind;
 
             if (!blind && _blindableComponent.LightSetup) // Turn FOV back on if we can see again
             {
index 5c7176dc773b8666a7f9193921f4cb1b422f5b1e..f0b760d838b53e003303461760e57102522f752e 100644 (file)
@@ -8,6 +8,7 @@ using System.Collections.Generic;
 using System.Linq;
 using Content.Shared.Administration;
 using Content.Shared.Administration.Events;
+using Content.Shared.Eye.Blinding.Components;
 using Content.Shared.GameTicking;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Network;
index 376b415fabd67c9cb24f1ade98b3ade407493594..9ab90d16c99d0e6712d2292a31a81e1cdc0f2b61 100644 (file)
@@ -4,24 +4,21 @@ using Robust.Client.Player;
 using Robust.Shared.Enums;
 using Robust.Shared.Prototypes;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Components;
 
 namespace Content.Client.Eye.Blinding
 {
     public sealed class BlurryVisionOverlay : Overlay
     {
-        [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
         [Dependency] private readonly IEntityManager _entityManager = default!;
         [Dependency] private readonly IPlayerManager _playerManager = default!;
 
-        public override bool RequestScreenTexture => true;
         public override OverlaySpace Space => OverlaySpace.WorldSpace;
-        private readonly ShaderInstance _dim;
-        private BlurryVisionComponent _blurryVisionComponent = default!;
+        private float _magnitude;
 
         public BlurryVisionOverlay()
         {
             IoCManager.InjectDependencies(this);
-            _dim = _prototypeManager.Index<ShaderPrototype>("Dim").InstanceUnique();
         }
 
         protected override bool BeforeDraw(in OverlayDrawArgs args)
@@ -40,33 +37,29 @@ namespace Content.Client.Eye.Blinding
             if (!_entityManager.TryGetComponent<BlurryVisionComponent>(playerEntity, out var blurComp))
                 return false;
 
-            if (!blurComp.Active)
+            if (blurComp.Magnitude <= 0)
                 return false;
 
             if (_entityManager.TryGetComponent<BlindableComponent>(playerEntity, out var blindComp)
-                && blindComp.Sources > 0)
+                && blindComp.IsBlind)
                 return false;
 
-            _blurryVisionComponent = blurComp;
+            _magnitude = blurComp.Magnitude;
             return true;
         }
 
         protected override void Draw(in OverlayDrawArgs args)
         {
-            if (ScreenTexture == null)
-                return;
-
-            var opacity = -(_blurryVisionComponent.Magnitude / 15) + 0.9f;
-
-            _dim.SetParameter("DAMAGE_AMOUNT", opacity);
-
+            // TODO make this better.
+            // This is a really shitty effect.
+            // Maybe gradually shrink the view-size?
+            // Make the effect only apply to the edge of the viewport?
+            // Actually make it blurry??
+            var opacity =  0.5f * _magnitude / BlurryVisionComponent.MaxMagnitude;
             var worldHandle = args.WorldHandle;
             var viewport = args.WorldBounds;
-
-            worldHandle.UseShader(_dim);
             worldHandle.SetTransform(Matrix3.Identity);
-            worldHandle.DrawRect(viewport, Color.Black);
-            worldHandle.UseShader(null);
+            worldHandle.DrawRect(viewport, Color.White.WithAlpha(opacity));
         }
     }
 }
index 3e8afd9e4d98c1b93938697cc4059f3ed133828d..1bac2a97bf45c0ba92ad8bb08c17140622cc21b5 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Components;
 using Robust.Client.GameObjects;
 using Robust.Client.Graphics;
 using Robust.Client.Player;
@@ -22,8 +23,6 @@ public sealed class BlurryVisionSystem : EntitySystem
         SubscribeLocalEvent<BlurryVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
         SubscribeLocalEvent<BlurryVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
 
-        SubscribeLocalEvent<BlurryVisionComponent, ComponentHandleState>(OnHandleState);
-
         _overlay = new();
     }
 
@@ -50,12 +49,4 @@ public sealed class BlurryVisionSystem : EntitySystem
             _overlayMan.RemoveOverlay(_overlay);
         }
     }
-
-    private void OnHandleState(EntityUid uid, BlurryVisionComponent component, ref ComponentHandleState args)
-    {
-        if (args.Current is not BlurryVisionComponentState state)
-            return;
-
-        component.Magnitude = state.Magnitude;
-    }
 }
index fb6d6484023da107f9a8af0f90c030dac5b709c7..0826e991102317007be8ecb7dd24571588b44c24 100644 (file)
@@ -1,27 +1,28 @@
 using Content.Shared.Chemistry.Reagent;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Systems;
 using JetBrains.Annotations;
 
 namespace Content.Server.Chemistry.ReagentEffects
 {
     /// <summary>
-    /// Heal eye damage (or deal)
+    /// Heal or apply eye damage
     /// </summary>
     [UsedImplicitly]
     public sealed class ChemHealEyeDamage : ReagentEffect
     {
         /// <summary>
-        /// How much eye damage to remove.
+        /// How much eye damage to add.
         /// </summary>
         [DataField("amount")]
         public int Amount = -1;
 
         public override void Effect(ReagentEffectArgs args)
         {
-            if (args.Scale != 1f)
+            if (args.Scale != 1f) // huh?
                 return;
 
-            args.EntityManager.EntitySysManager.GetEntitySystem<SharedBlindingSystem>().AdjustEyeDamage(args.SolutionEntity, Amount);
+            args.EntityManager.EntitySysManager.GetEntitySystem<BlindableSystem>().AdjustEyeDamage(args.SolutionEntity, Amount);
         }
     }
 }
index 4b5d3d3eef89b58678f5c0440e827715f0252eb7..cbecba701c691cbce1d7c1c80a23f5218db73c46 100644 (file)
@@ -1,6 +1,8 @@
 using Content.Shared.Eye.Blinding;
 using Content.Server.UserInterface;
 using Content.Server.Popups;
+using Content.Shared.Eye.Blinding.Components;
+using Content.Shared.Eye.Blinding.Systems;
 using Robust.Shared.Player;
 using Robust.Server.GameObjects;
 
@@ -23,14 +25,14 @@ public sealed class ActivatableUIRequiresVisionSystem : EntitySystem
         if (args.Cancelled)
             return;
 
-        if (TryComp<BlindableComponent>(args.User, out var blindable) && blindable.Sources > 0)
+        if (TryComp<BlindableComponent>(args.User, out var blindable) && blindable.IsBlind)
         {
             _popupSystem.PopupCursor(Loc.GetString("blindness-fail-attempt"), args.User, Shared.Popups.PopupType.MediumCaution);
             args.Cancel();
         }
     }
 
-    private void OnBlindnessChanged(EntityUid uid, BlindableComponent component, BlindnessChangedEvent args)
+    private void OnBlindnessChanged(EntityUid uid, BlindableComponent component, ref BlindnessChangedEvent args)
     {
         if (!args.Blind)
             return;
index 4872cd359a40f2a7925c9e45db58c5dbc4188e70..d31f9eeed64cb638f7eb582cae74b886dd2e2e61 100644 (file)
@@ -1,10 +1,9 @@
-using Content.Shared.Eye.Blinding.EyeProtection; // why aren't tools predicted 🙂
 using Content.Shared.Eye.Blinding;
 using Content.Shared.StatusEffect;
-using Content.Shared.Clothing.Components;
 using Content.Shared.Inventory;
-using Content.Shared.Inventory.Events;
 using Content.Server.Tools;
+using Content.Shared.Eye.Blinding.Components;
+using Content.Shared.Eye.Blinding.Systems;
 using Content.Shared.Tools.Components;
 
 namespace Content.Server.Eye.Blinding.EyeProtection
@@ -12,67 +11,53 @@ namespace Content.Server.Eye.Blinding.EyeProtection
     public sealed class EyeProtectionSystem : EntitySystem
     {
         [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
-        [Dependency] private readonly SharedBlindingSystem _blindingSystem = default!;
+        [Dependency] private readonly BlindableSystem _blindingSystem = default!;
         public override void Initialize()
         {
             base.Initialize();
             SubscribeLocalEvent<RequiresEyeProtectionComponent, ToolUseAttemptEvent>(OnUseAttempt);
             SubscribeLocalEvent<RequiresEyeProtectionComponent, WelderToggledEvent>(OnWelderToggled);
 
-            SubscribeLocalEvent<EyeProtectionComponent, GotEquippedEvent>(OnEquipped);
-            SubscribeLocalEvent<EyeProtectionComponent, GotUnequippedEvent>(OnUnequipped);
+            SubscribeLocalEvent<EyeProtectionComponent, GetEyeProtectionEvent>(OnGetProtection);
+            SubscribeLocalEvent<EyeProtectionComponent, InventoryRelayedEvent<GetEyeProtectionEvent>>(OnGetRelayedProtection);
         }
 
-        private void OnUseAttempt(EntityUid uid, RequiresEyeProtectionComponent component, ToolUseAttemptEvent args)
+        private void OnGetRelayedProtection(EntityUid uid, EyeProtectionComponent component,
+            InventoryRelayedEvent<GetEyeProtectionEvent> args)
         {
-            if (!component.Toggled)
-                return;
-
-            if (!HasComp<StatusEffectsComponent>(args.User) || !TryComp<BlindableComponent>(args.User, out var blindable))
-                return;
-
-            if (blindable.Sources > 0)
-                return;
-
-            var statusTime = (float) component.StatusEffectTime.TotalSeconds - blindable.BlindResistance;
-
-            if (statusTime <= 0)
-                return;
-
-            var statusTimeSpan = TimeSpan.FromSeconds(statusTime * (blindable.EyeDamage + 1));
-            // Add permanent eye damage if they had zero protection, also scale their temporary blindness by how much they already accumulated.
-            if (_statusEffectsSystem.TryAddStatusEffect(args.User, SharedBlindingSystem.BlindingStatusEffect, statusTimeSpan, false, "TemporaryBlindness") && blindable.BlindResistance <= 0)
-                _blindingSystem.AdjustEyeDamage(args.User, 1, blindable);
+            OnGetProtection(uid, component, args.Args);
         }
-        private void OnWelderToggled(EntityUid uid, RequiresEyeProtectionComponent component, WelderToggledEvent args)
+
+        private void OnGetProtection(EntityUid uid, EyeProtectionComponent component, GetEyeProtectionEvent args)
         {
-            component.Toggled = args.WelderOn;
+            args.Protection += component.ProtectionTime;
         }
 
-        private void OnEquipped(EntityUid uid, EyeProtectionComponent component, GotEquippedEvent args)
+        private void OnUseAttempt(EntityUid uid, RequiresEyeProtectionComponent component, ToolUseAttemptEvent args)
         {
-            if (!TryComp<ClothingComponent>(uid, out var clothing) || clothing.Slots == SlotFlags.PREVENTEQUIP)
+            if (!component.Toggled)
                 return;
 
-            if (!clothing.Slots.HasFlag(args.SlotFlags))
+            if (!TryComp<BlindableComponent>(args.User, out var blindable) || blindable.IsBlind)
                 return;
 
-            component.IsActive = true;
-            if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
+            var ev = new GetEyeProtectionEvent();
+            RaiseLocalEvent(args.User, ev);
+
+            var time = (float) (component.StatusEffectTime- ev.Protection).TotalSeconds;
+            if (time <= 0)
                 return;
 
-            blindComp.BlindResistance += (float) component.ProtectionTime.TotalSeconds;
+            // Add permanent eye damage if they had zero protection, also somewhat scale their temporary blindness by
+            // how much damage they already accumulated.
+            _blindingSystem.AdjustEyeDamage(args.User, 1, blindable);
+            var statusTimeSpan = TimeSpan.FromSeconds(time * MathF.Sqrt(blindable.EyeDamage));
+            _statusEffectsSystem.TryAddStatusEffect(args.User, TemporaryBlindnessSystem.BlindingStatusEffect,
+                statusTimeSpan, false, TemporaryBlindnessSystem.BlindingStatusEffect);
         }
-
-        private void OnUnequipped(EntityUid uid, EyeProtectionComponent component, GotUnequippedEvent args)
+        private void OnWelderToggled(EntityUid uid, RequiresEyeProtectionComponent component, WelderToggledEvent args)
         {
-            if (!component.IsActive)
-                return;
-            component.IsActive = false;
-            if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
-                return;
-
-            blindComp.BlindResistance -= (float) component.ProtectionTime.TotalSeconds;
+            component.Toggled = args.WelderOn;
         }
     }
 }
index b10864b829239a747694e7d4faf5af47f8454e94..016ea7e7818c54e1778b9eab3a5a9d32b7ddb11e 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.Light.EntitySystems;
 using Content.Server.Stunnable;
 using Content.Shared.Examine;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Components;
 using Content.Shared.Flash;
 using Content.Shared.IdentityManagement;
 using Content.Shared.Interaction;
index 2435711c71113baac21d45383c16e349f80381be..458a69b6215e8dda0c2be8e9ac38b54b3eec0cbc 100644 (file)
@@ -1,20 +1,21 @@
-using Content.Shared.Eye.Blinding;
 using Content.Shared.Speech;
 using Content.Shared.Actions;
 using Content.Shared.Bed.Sleep;
+using Content.Shared.Eye.Blinding.Systems;
 
 namespace Content.Server.Bed.Sleep
 {
     public abstract class SharedSleepingSystem : EntitySystem
     {
-        [Dependency] private readonly SharedBlindingSystem _blindingSystem = default!;
+        [Dependency] private readonly BlindableSystem _blindableSystem = default!;
 
         public override void Initialize()
         {
             base.Initialize();
-            SubscribeLocalEvent<SleepingComponent, ComponentInit>(OnInit);
+            SubscribeLocalEvent<SleepingComponent, ComponentStartup>(OnStartup);
             SubscribeLocalEvent<SleepingComponent, ComponentShutdown>(OnShutdown);
             SubscribeLocalEvent<SleepingComponent, SpeakAttemptEvent>(OnSpeakAttempt);
+            SubscribeLocalEvent<SleepingComponent, CanSeeAttemptEvent>(OnSeeAttempt);
             SubscribeLocalEvent<SleepingComponent, EntityUnpausedEvent>(OnSleepUnpaused);
         }
 
@@ -24,24 +25,30 @@ namespace Content.Server.Bed.Sleep
             Dirty(component);
         }
 
-        private void OnInit(EntityUid uid, SleepingComponent component, ComponentInit args)
+        private void OnStartup(EntityUid uid, SleepingComponent component, ComponentStartup args)
         {
             var ev = new SleepStateChangedEvent(true);
             RaiseLocalEvent(uid, ev);
-            _blindingSystem.AdjustBlindSources(uid, 1);
+            _blindableSystem.UpdateIsBlind(uid);
         }
 
         private void OnShutdown(EntityUid uid, SleepingComponent component, ComponentShutdown args)
         {
             var ev = new SleepStateChangedEvent(false);
             RaiseLocalEvent(uid, ev);
-            _blindingSystem.AdjustBlindSources(uid, -1);
+            _blindableSystem.UpdateIsBlind(uid);
         }
 
         private void OnSpeakAttempt(EntityUid uid, SleepingComponent component, SpeakAttemptEvent args)
         {
             args.Cancel();
         }
+
+        private void OnSeeAttempt(EntityUid uid, SleepingComponent component, CanSeeAttemptEvent args)
+        {
+            if (component.LifeStage <= ComponentLifeStage.Running)
+                args.Cancel();
+        }
     }
 }
 
index 1eed657d0f0092064115867013c794cbd1b0d212..77ab083a2f5f27b2b853328215c4664470b9f6c2 100644 (file)
@@ -2,6 +2,7 @@ using System.Linq;
 using Content.Shared.DragDrop;
 using Content.Shared.Interaction;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Components;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Mobs.Systems;
 using JetBrains.Annotations;
@@ -122,14 +123,12 @@ namespace Content.Shared.Examine
             {
                 if (MobStateSystem.IsDead(examiner, mobState))
                     return DeadExamineRange;
-                else if (MobStateSystem.IsCritical(examiner, mobState) || (TryComp<BlindableComponent>(examiner, out var blind) && blind.Sources > 0))
+
+                if (MobStateSystem.IsCritical(examiner, mobState) || TryComp<BlindableComponent>(examiner, out var blind) && blind.IsBlind)
                     return CritExamineRange;
 
-                else if (TryComp<BlurryVisionComponent>(examiner, out var blurry) && blurry.Magnitude != 0)
-                {
-                    float range = ExamineRange - (2 * (8 - blurry.Magnitude));
-                    return Math.Clamp(range, 2, 16);
-                }
+                if (TryComp<BlurryVisionComponent>(examiner, out var blurry))
+                    return Math.Clamp(ExamineRange - blurry.Magnitude, 2, ExamineRange);
             }
             return ExamineRange;
         }
diff --git a/Content.Shared/Eye/Blinding/BlindableComponent.cs b/Content.Shared/Eye/Blinding/BlindableComponent.cs
deleted file mode 100644 (file)
index 8cb34bc..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Eye.Blinding
-{
-    [RegisterComponent]
-    [NetworkedComponent]
-    public sealed class BlindableComponent : Component
-    {
-        /// <description>
-        /// How many sources of blindness are affecting us?
-        /// </description>
-        [DataField("sources")]
-        public int Sources = 0;
-
-        /// <summary>
-        /// How many seconds will be subtracted from each attempt to add blindness to us?
-        /// </summary>
-        [DataField("blindResistance")]
-        public float BlindResistance = 0;
-
-        /// <summary>
-        /// Replace with actual eye damage after bobby I guess
-        /// </summary>
-        [ViewVariables]
-        public int EyeDamage = 0;
-
-        /// <summary>
-        /// Whether eye damage has accumulated enough to blind them.
-        /// </summary>
-        [ViewVariables]
-        public bool EyeTooDamaged = false;
-
-        /// <description>
-        /// Used to ensure that this doesn't break with sandbox or admin tools.
-        /// This is not "enabled/disabled".
-        /// </description>
-        public bool LightSetup = false;
-
-        /// <description>
-        /// Gives an extra frame of blindness to reenable light manager during
-        /// </description>
-        public bool GraceFrame = false;
-    }
-
-    [Serializable, NetSerializable]
-    public sealed class BlindableComponentState : ComponentState
-    {
-        public readonly int Sources;
-
-        public BlindableComponentState(int sources)
-        {
-            Sources = sources;
-        }
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/BlindfoldComponent.cs b/Content.Shared/Eye/Blinding/BlindfoldComponent.cs
deleted file mode 100644 (file)
index d1bdce4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Eye.Blinding
-{
-    [RegisterComponent]
-    [NetworkedComponent]
-    public sealed class BlindfoldComponent : Component
-    {
-        [ViewVariables]
-        public bool IsActive = false;
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/BlurryVisionComponent.cs b/Content.Shared/Eye/Blinding/BlurryVisionComponent.cs
deleted file mode 100644 (file)
index bbf518b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Eye.Blinding
-{
-    [RegisterComponent]
-    [NetworkedComponent]
-    public sealed class BlurryVisionComponent : Component
-    {
-        [DataField("mangitude")]
-        public float Magnitude = 1f;
-
-        public bool Active => Magnitude < 10f;
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/Components/BlindableComponent.cs b/Content.Shared/Eye/Blinding/Components/BlindableComponent.cs
new file mode 100644 (file)
index 0000000..32bd4c1
--- /dev/null
@@ -0,0 +1,41 @@
+using Content.Shared.Eye.Blinding.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+[RegisterComponent]
+[NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(BlindableSystem))]
+public sealed partial class BlindableComponent : Component
+{
+    /// <summary>
+    /// How many seconds will be subtracted from each attempt to add blindness to us?
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField("isBlind"), AutoNetworkedField]
+    public bool IsBlind;
+
+    /// <summary>
+    /// Eye damage due to things like staring directly at welders. Causes blurry vision or outright
+    /// blindness if greater than or equal to <see cref="MaxDamage"/>.
+    /// </summary>
+    /// <remarks>
+    /// Should eventually be replaced with a proper eye health system when we have bobby.
+    /// </remarks>
+    [ViewVariables(VVAccess.ReadWrite), DataField("EyeDamage"), AutoNetworkedField]
+    public int EyeDamage = 0;
+
+    public const int MaxDamage = 8;
+
+    /// <description>
+    /// Used to ensure that this doesn't break with sandbox or admin tools.
+    /// This is not "enabled/disabled".
+    /// </description>
+    [Access(Other = AccessPermissions.ReadWriteExecute)]
+    public bool LightSetup = false;
+
+    /// <description>
+    /// Gives an extra frame of blindness to reenable light manager during
+    /// </description>
+    [Access(Other = AccessPermissions.ReadWriteExecute)]
+    public bool GraceFrame = false;
+}
diff --git a/Content.Shared/Eye/Blinding/Components/BlindfoldComponent.cs b/Content.Shared/Eye/Blinding/Components/BlindfoldComponent.cs
new file mode 100644 (file)
index 0000000..85268d8
--- /dev/null
@@ -0,0 +1,12 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+///     Blinds a person when an item with this component is equipped to the eye, head, or mask slot.
+/// </summary>
+[RegisterComponent]
+[NetworkedComponent]
+public sealed class BlindfoldComponent : Component
+{
+}
diff --git a/Content.Shared/Eye/Blinding/Components/BlurryVisionComponent.cs b/Content.Shared/Eye/Blinding/Components/BlurryVisionComponent.cs
new file mode 100644 (file)
index 0000000..8182dfe
--- /dev/null
@@ -0,0 +1,21 @@
+using Content.Shared.Eye.Blinding.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+///     This component adds a white overlay to the viewport. It does not actually cause blurring.
+/// </summary>
+[RegisterComponent]
+[NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(BlurryVisionSystem))]
+public sealed partial class BlurryVisionComponent : Component
+{
+    /// <summary>
+    ///     Amount of "blurring". Also modifies examine ranges.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField("magnitude"), AutoNetworkedField]
+    public float Magnitude;
+
+    public const float MaxMagnitude = 10;
+}
diff --git a/Content.Shared/Eye/Blinding/Components/EyeProtectionComponent.cs b/Content.Shared/Eye/Blinding/Components/EyeProtectionComponent.cs
new file mode 100644 (file)
index 0000000..eaf3bdb
--- /dev/null
@@ -0,0 +1,15 @@
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+/// For welding masks, sunglasses, etc.
+/// </summary>
+[RegisterComponent]
+public sealed class EyeProtectionComponent : Component
+{
+    /// <summary>
+    /// How many seconds to subtract from the status effect. If it's greater than the source
+    /// of blindness, do not blind.
+    /// </summary>
+    [DataField("protectionTime")]
+    public readonly TimeSpan ProtectionTime = TimeSpan.FromSeconds(10);
+}
diff --git a/Content.Shared/Eye/Blinding/Components/RequiresEyeProtectionComponent.cs b/Content.Shared/Eye/Blinding/Components/RequiresEyeProtectionComponent.cs
new file mode 100644 (file)
index 0000000..f12d174
--- /dev/null
@@ -0,0 +1,22 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+/// For tools like welders that will damage your eyes when you use them.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class RequiresEyeProtectionComponent : Component
+{
+    /// <summary>
+    /// How long to apply temporary blindness to the user.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField("statusEffectTime"), AutoNetworkedField]
+    public TimeSpan StatusEffectTime = TimeSpan.FromSeconds(10);
+
+    /// <summary>
+    /// You probably want to turn this on in yaml if it's something always on and not a welder.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite), DataField("toggled"), AutoNetworkedField]
+    public bool Toggled;
+}
diff --git a/Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs b/Content.Shared/Eye/Blinding/Components/TemporaryBlindnessComponent.cs
new file mode 100644 (file)
index 0000000..41049e3
--- /dev/null
@@ -0,0 +1,11 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+/// Component used for the blind status effect.
+/// </summary>
+[NetworkedComponent, RegisterComponent]
+public sealed class TemporaryBlindnessComponent : Component
+{
+}
diff --git a/Content.Shared/Eye/Blinding/Components/VisionCorrectionComponent.cs b/Content.Shared/Eye/Blinding/Components/VisionCorrectionComponent.cs
new file mode 100644 (file)
index 0000000..54f0833
--- /dev/null
@@ -0,0 +1,14 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Eye.Blinding.Components;
+
+/// <summary>
+///     This component allows equipment to offset blurry vision.
+/// </summary>
+[RegisterComponent]
+[NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class VisionCorrectionComponent : Component
+{
+    [ViewVariables(VVAccess.ReadWrite), DataField("visionBonus"), AutoNetworkedField]
+    public float VisionBonus = 3f;
+}
diff --git a/Content.Shared/Eye/Blinding/EyeProtection/EyeProtectionComponent.cs b/Content.Shared/Eye/Blinding/EyeProtection/EyeProtectionComponent.cs
deleted file mode 100644 (file)
index 0eb360b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Content.Shared.Eye.Blinding.EyeProtection
-{
-    /// <summary>
-    /// For welding masks, sunglasses, etc.
-    /// </summary>
-    [RegisterComponent]
-    public sealed class EyeProtectionComponent : Component
-    {
-        /// <summary>
-        /// How many seconds to subtract from the status effect. If it's greater than the source
-        /// of blindness, do not blind.
-        /// </summary>
-        [DataField("protectionTime")]
-        public TimeSpan ProtectionTime = TimeSpan.FromSeconds(10);
-
-        public bool IsActive = false;
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/EyeProtection/RequiresEyeProtectionComponent.cs b/Content.Shared/Eye/Blinding/EyeProtection/RequiresEyeProtectionComponent.cs
deleted file mode 100644 (file)
index 7ec3eef..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Content.Shared.Eye.Blinding.EyeProtection
-{
-    /// <summary>
-    /// For tools like welders that will damage your eyes when you use them.
-    /// </summary>
-    [RegisterComponent]
-    public sealed class RequiresEyeProtectionComponent : Component
-    {
-        /// <summary>
-        /// How long to apply temporary blindness to the user.
-        /// </summary>
-        [DataField("statusEffectTime")]
-        public TimeSpan StatusEffectTime = TimeSpan.FromSeconds(10);
-
-        /// <summary>
-        /// You probably want to turn this on in yaml if it's something always on and not a welder.
-        /// </summary>
-        [DataField("toggled")]
-        public bool Toggled = false;
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/SharedBlindingSystem.cs b/Content.Shared/Eye/Blinding/SharedBlindingSystem.cs
deleted file mode 100644 (file)
index aa5e2b8..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-using Content.Shared.Clothing.Components;
-using Content.Shared.Inventory.Events;
-using Content.Shared.Inventory;
-using Content.Shared.Rejuvenate;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-using JetBrains.Annotations;
-
-namespace Content.Shared.Eye.Blinding
-{
-    public sealed class SharedBlindingSystem : EntitySystem
-    {
-        public const string BlindingStatusEffect = "TemporaryBlindness";
-        public override void Initialize()
-        {
-            base.Initialize();
-
-            SubscribeLocalEvent<BlindableComponent, ComponentGetState>(OnGetBlindableState);
-            SubscribeLocalEvent<BlindableComponent, ComponentHandleState>(OnHandleBlindableState);
-
-            SubscribeLocalEvent<BlindfoldComponent, GotEquippedEvent>(OnEquipped);
-            SubscribeLocalEvent<BlindfoldComponent, GotUnequippedEvent>(OnUnequipped);
-
-            SubscribeLocalEvent<VisionCorrectionComponent, GotEquippedEvent>(OnGlassesEquipped);
-            SubscribeLocalEvent<VisionCorrectionComponent, GotUnequippedEvent>(OnGlassesUnequipped);
-
-            SubscribeLocalEvent<BlurryVisionComponent, ComponentGetState>(OnGetState);
-
-            SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentInit>(OnInit);
-            SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentShutdown>(OnShutdown);
-
-            SubscribeLocalEvent<BlindableComponent, RejuvenateEvent>(OnRejuvenate);
-        }
-
-        private void OnGetBlindableState(EntityUid uid, BlindableComponent component, ref ComponentGetState args)
-        {
-            args.State = new BlindableComponentState(component.Sources);
-        }
-
-        private void OnHandleBlindableState(EntityUid uid, BlindableComponent component, ref ComponentHandleState args)
-        {
-            if (args.Current is not BlindableComponentState cast)
-                return;
-
-            component.Sources = cast.Sources;
-        }
-
-        private void OnEquipped(EntityUid uid, BlindfoldComponent component, GotEquippedEvent args)
-        {
-            if (!TryComp<ClothingComponent>(uid, out var clothing) || clothing.Slots == SlotFlags.PREVENTEQUIP) // we live in a society
-                return;
-            // Is the clothing in its actual slot?
-            if (!clothing.Slots.HasFlag(args.SlotFlags))
-                return;
-
-            component.IsActive = true;
-            if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
-                return;
-            AdjustBlindSources(args.Equipee, 1, blindComp);
-        }
-
-        private void OnUnequipped(EntityUid uid, BlindfoldComponent component, GotUnequippedEvent args)
-        {
-            if (!component.IsActive)
-                return;
-            component.IsActive = false;
-            if (!TryComp<BlindableComponent>(args.Equipee, out var blindComp))
-                return;
-            AdjustBlindSources(args.Equipee, -1, blindComp);
-        }
-
-        private void OnGlassesEquipped(EntityUid uid, VisionCorrectionComponent component, GotEquippedEvent args)
-        {
-            if (!TryComp<ClothingComponent>(uid, out var clothing) || clothing.Slots == SlotFlags.PREVENTEQUIP) // we live in a society
-                return;
-            // Is the clothing in its actual slot?
-            if (!clothing.Slots.HasFlag(args.SlotFlags))
-                return;
-
-            if (!TryComp<BlurryVisionComponent>(args.Equipee, out var blur))
-                return;
-
-            component.IsActive = true;
-            blur.Magnitude += component.VisionBonus;
-            Dirty(blur);
-        }
-
-        private void OnGlassesUnequipped(EntityUid uid, VisionCorrectionComponent component, GotUnequippedEvent args)
-        {
-            if (!component.IsActive || !TryComp<BlurryVisionComponent>(args.Equipee, out var blur))
-                return;
-            component.IsActive = false;
-            blur.Magnitude -= component.VisionBonus;
-            Dirty(blur);
-        }
-
-        private void OnGetState(EntityUid uid, BlurryVisionComponent component, ref ComponentGetState args)
-        {
-            args.State = new BlurryVisionComponentState(component.Magnitude);
-        }
-
-        private void OnInit(EntityUid uid, TemporaryBlindnessComponent component, ComponentInit args)
-        {
-            AdjustBlindSources(uid, 1);
-        }
-
-        private void OnShutdown(EntityUid uid, TemporaryBlindnessComponent component, ComponentShutdown args)
-        {
-            AdjustBlindSources(uid, -1);
-        }
-
-        private void OnRejuvenate(EntityUid uid, BlindableComponent component, RejuvenateEvent args)
-        {
-            AdjustEyeDamage(uid, -component.EyeDamage, component);
-        }
-
-        [PublicAPI]
-        public void AdjustBlindSources(EntityUid uid, int amount, BlindableComponent? blindable = null)
-        {
-            if (!Resolve(uid, ref blindable, false))
-                return;
-
-            var oldSources = blindable.Sources;
-
-            blindable.Sources += amount;
-            blindable.Sources = Math.Max(blindable.Sources, 0);
-
-            if (oldSources == 0 && blindable.Sources > 0)
-            {
-                var ev = new BlindnessChangedEvent(true);
-                RaiseLocalEvent(uid, ev, false);
-            }
-            else if (blindable.Sources == 0 && oldSources > 0)
-            {
-                var ev = new BlindnessChangedEvent(false);
-                RaiseLocalEvent(uid, ev, false);
-            }
-
-            Dirty(blindable);
-        }
-
-        public void AdjustEyeDamage(EntityUid uid, int amount, BlindableComponent? blindable = null)
-        {
-            if (!Resolve(uid, ref blindable, false))
-                return;
-
-            blindable.EyeDamage += amount;
-
-            if (blindable.EyeDamage > 0)
-            {
-                var blurry = EnsureComp<BlurryVisionComponent>(uid);
-                blurry.Magnitude = (9 - blindable.EyeDamage);
-                Dirty(blurry);
-            }
-            else
-            {
-                RemComp<BlurryVisionComponent>(uid);
-            }
-
-            if (!blindable.EyeTooDamaged && blindable.EyeDamage >= 8)
-            {
-                blindable.EyeTooDamaged = true;
-                AdjustBlindSources(uid, 1, blindable);
-            }
-            if (blindable.EyeTooDamaged && blindable.EyeDamage < 8)
-            {
-                blindable.EyeTooDamaged = false;
-                AdjustBlindSources(uid, -1, blindable);
-            }
-
-            blindable.EyeDamage = Math.Clamp(blindable.EyeDamage, 0, 8);
-        }
-    }
-
-    // I have no idea why blurry vision needs this but blindness doesn't
-    [Serializable, NetSerializable]
-    public sealed class BlurryVisionComponentState : ComponentState
-    {
-        public float Magnitude;
-        public BlurryVisionComponentState(float magnitude)
-        {
-            Magnitude = magnitude;
-        }
-    }
-
-    /// <summary>
-    ///     You became blind or lost blindess, not just changed # of sources.
-    /// </summary>
-    public sealed class BlindnessChangedEvent : EntityEventArgs
-    {
-        public bool Blind;
-
-        public BlindnessChangedEvent(bool blind)
-        {
-            Blind = blind;
-        }
-    }
-}
diff --git a/Content.Shared/Eye/Blinding/Systems/BlindableSystem.cs b/Content.Shared/Eye/Blinding/Systems/BlindableSystem.cs
new file mode 100644 (file)
index 0000000..65ecc1d
--- /dev/null
@@ -0,0 +1,93 @@
+using Content.Shared.Eye.Blinding.Components;
+using Content.Shared.Inventory;
+using Content.Shared.Rejuvenate;
+using JetBrains.Annotations;
+
+namespace Content.Shared.Eye.Blinding.Systems;
+
+public sealed class BlindableSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+        SubscribeLocalEvent<BlindableComponent, RejuvenateEvent>(OnRejuvenate);
+    }
+
+    private void OnRejuvenate(EntityUid uid, BlindableComponent component, RejuvenateEvent args)
+    {
+        AdjustEyeDamage(uid, -component.EyeDamage, component);
+    }
+
+    [PublicAPI]
+    public void UpdateIsBlind(EntityUid uid, BlindableComponent? blindable = null)
+    {
+        if (!Resolve(uid, ref blindable, false))
+            return;
+
+        var old = blindable.IsBlind;
+
+        // Don't bother raising an event if the eye is too damaged.
+        if (blindable.EyeDamage >= BlindableComponent.MaxDamage)
+        {
+            blindable.IsBlind = true;
+        }
+        else
+        {
+            var ev = new CanSeeAttemptEvent();
+            RaiseLocalEvent(uid, ev);
+            blindable.IsBlind = ev.Blind;
+        }
+
+        if (old == blindable.IsBlind)
+            return;
+
+        var changeEv = new BlindnessChangedEvent(blindable.IsBlind);
+        RaiseLocalEvent(uid, ref changeEv);
+        Dirty(blindable);
+    }
+
+    public void AdjustEyeDamage(EntityUid uid, int amount, BlindableComponent? blindable = null)
+    {
+        if (!Resolve(uid, ref blindable, false) || amount == 0)
+            return;
+
+        blindable.EyeDamage += amount;
+        blindable.EyeDamage = Math.Clamp(blindable.EyeDamage, 0, BlindableComponent.MaxDamage);
+        Dirty(blindable);
+        UpdateIsBlind(uid, blindable);
+
+        var ev = new EyeDamageChangedEvent(blindable.EyeDamage);
+        RaiseLocalEvent(uid, ref ev);
+    }
+}
+
+/// <summary>
+///     This event is raised when an entity's blindness changes
+/// </summary>
+[ByRefEvent]
+public record struct BlindnessChangedEvent(bool Blind);
+
+/// <summary>
+///     This event is raised when an entity's eye damage changes
+/// </summary>
+[ByRefEvent]
+public record struct  EyeDamageChangedEvent(int Damage);
+
+/// <summary>
+///     Raised directed at an entity to see whether the entity is currently blind or not.
+/// </summary>
+public sealed class CanSeeAttemptEvent : CancellableEntityEventArgs, IInventoryRelayEvent
+{
+    public bool Blind => Cancelled;
+    public SlotFlags TargetSlots => SlotFlags.EYES | SlotFlags.MASK | SlotFlags.HEAD;
+}
+
+public sealed class GetEyeProtectionEvent : EntityEventArgs, IInventoryRelayEvent
+{
+    /// <summary>
+    ///     Time to subtract from any temporary blindness sources.
+    /// </summary>
+    public TimeSpan Protection;
+
+    public SlotFlags TargetSlots => SlotFlags.EYES | SlotFlags.MASK | SlotFlags.HEAD;
+}
diff --git a/Content.Shared/Eye/Blinding/Systems/BlindfoldSystem.cs b/Content.Shared/Eye/Blinding/Systems/BlindfoldSystem.cs
new file mode 100644 (file)
index 0000000..b875c13
--- /dev/null
@@ -0,0 +1,34 @@
+using Content.Shared.Eye.Blinding.Components;
+using Content.Shared.Inventory.Events;
+using Content.Shared.Inventory;
+
+namespace Content.Shared.Eye.Blinding.Systems;
+
+public sealed class BlindfoldSystem : EntitySystem
+{
+    [Dependency] private readonly BlindableSystem _blindableSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<BlindfoldComponent, GotEquippedEvent>(OnEquipped);
+        SubscribeLocalEvent<BlindfoldComponent, GotUnequippedEvent>(OnUnequipped);
+        SubscribeLocalEvent<BlindfoldComponent, InventoryRelayedEvent<CanSeeAttemptEvent>>(OnBlindfoldTrySee);
+    }
+
+    private void OnBlindfoldTrySee(EntityUid uid, BlindfoldComponent component, InventoryRelayedEvent<CanSeeAttemptEvent> args)
+    {
+        args.Args.Cancel();
+    }
+
+    private void OnEquipped(EntityUid uid, BlindfoldComponent component, GotEquippedEvent args)
+    {
+        _blindableSystem.UpdateIsBlind(args.Equipee);
+    }
+
+    private void OnUnequipped(EntityUid uid, BlindfoldComponent component, GotUnequippedEvent args)
+    {
+        _blindableSystem.UpdateIsBlind(args.Equipee);
+    }
+}
diff --git a/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs b/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs
new file mode 100644 (file)
index 0000000..4c9fb02
--- /dev/null
@@ -0,0 +1,72 @@
+using Content.Shared.Eye.Blinding.Components;
+using Content.Shared.Inventory.Events;
+using Content.Shared.Inventory;
+
+namespace Content.Shared.Eye.Blinding.Systems;
+
+public sealed class BlurryVisionSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<BlindableComponent, EyeDamageChangedEvent>(OnDamageChanged);
+        SubscribeLocalEvent<VisionCorrectionComponent, GotEquippedEvent>(OnGlassesEquipped);
+        SubscribeLocalEvent<VisionCorrectionComponent, GotUnequippedEvent>(OnGlassesUnequipped);
+        SubscribeLocalEvent<VisionCorrectionComponent, InventoryRelayedEvent<GetBlurEvent>>(OnGetBlur);
+    }
+
+    private void OnGetBlur(EntityUid uid, VisionCorrectionComponent component, InventoryRelayedEvent<GetBlurEvent> args)
+    {
+        args.Args.Blur += component.VisionBonus;
+    }
+
+    private void OnDamageChanged(EntityUid uid, BlindableComponent component, ref EyeDamageChangedEvent args)
+    {
+        UpdateBlurMagnitude(uid, component);
+    }
+
+    private void UpdateBlurMagnitude(EntityUid uid, BlindableComponent? component = null)
+    {
+        if (!Resolve(uid, ref component, false))
+            return;
+
+        var ev = new GetBlurEvent(component.EyeDamage);
+        RaiseLocalEvent(uid, ev);
+
+        var blur = Math.Clamp(0, ev.Blur, BlurryVisionComponent.MaxMagnitude);
+        if (blur <= 0)
+        {
+            RemCompDeferred<BlurryVisionComponent>(uid);
+            return;
+        }
+
+        var blurry = EnsureComp<BlurryVisionComponent>(uid);
+        blurry.Magnitude = blur;
+        Dirty(blurry);
+    }
+
+    private void OnGlassesEquipped(EntityUid uid, VisionCorrectionComponent component, GotEquippedEvent args)
+    {
+        UpdateBlurMagnitude(uid);
+    }
+
+    private void OnGlassesUnequipped(EntityUid uid, VisionCorrectionComponent component, GotUnequippedEvent args)
+    {
+        UpdateBlurMagnitude(uid);
+    }
+}
+
+public sealed class GetBlurEvent : EntityEventArgs, IInventoryRelayEvent
+{
+    public readonly float BaseBlur;
+    public float Blur;
+
+    public GetBlurEvent(float blur)
+    {
+        Blur = blur;
+        BaseBlur = blur;
+    }
+
+    public SlotFlags TargetSlots => SlotFlags.HEAD | SlotFlags.MASK | SlotFlags.EYES;
+}
diff --git a/Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs b/Content.Shared/Eye/Blinding/Systems/TemporaryBlindnessSystem.cs
new file mode 100644 (file)
index 0000000..431c40d
--- /dev/null
@@ -0,0 +1,35 @@
+using Content.Shared.Eye.Blinding.Components;
+
+namespace Content.Shared.Eye.Blinding.Systems;
+
+public sealed class TemporaryBlindnessSystem : EntitySystem
+{
+    public const string BlindingStatusEffect = "TemporaryBlindness";
+
+    [Dependency] private readonly BlindableSystem _blindableSystem = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentStartup>(OnStartup);
+        SubscribeLocalEvent<TemporaryBlindnessComponent, ComponentShutdown>(OnShutdown);
+        SubscribeLocalEvent<TemporaryBlindnessComponent, CanSeeAttemptEvent>(OnBlindTrySee);
+    }
+
+    private void OnStartup(EntityUid uid, TemporaryBlindnessComponent component, ComponentStartup args)
+    {
+        _blindableSystem.UpdateIsBlind(uid);
+    }
+
+    private void OnShutdown(EntityUid uid, TemporaryBlindnessComponent component, ComponentShutdown args)
+    {
+        _blindableSystem.UpdateIsBlind(uid);
+    }
+
+    private void OnBlindTrySee(EntityUid uid, TemporaryBlindnessComponent component, CanSeeAttemptEvent args)
+    {
+        if (component.LifeStage <= ComponentLifeStage.Running)
+            args.Cancel();
+    }
+}
diff --git a/Content.Shared/Eye/Blinding/TemporaryBlindnessComponent.cs b/Content.Shared/Eye/Blinding/TemporaryBlindnessComponent.cs
deleted file mode 100644 (file)
index 0c6ccc3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Eye.Blinding
-{
-    /// <summary>
-    /// Blind status effect.
-    /// </summary>
-    [NetworkedComponent, RegisterComponent]
-    public sealed class TemporaryBlindnessComponent : Component
-    {}
-}
diff --git a/Content.Shared/Eye/Blinding/VisionCorrectionComponent.cs b/Content.Shared/Eye/Blinding/VisionCorrectionComponent.cs
deleted file mode 100644 (file)
index dbc9750..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-using Robust.Shared.GameStates;
-
-namespace Content.Shared.Eye.Blinding
-{
-    [RegisterComponent]
-    [NetworkedComponent]
-    public sealed class VisionCorrectionComponent : Component
-    {
-        [ViewVariables]
-        public bool IsActive = false;
-
-        [DataField("visionBonus")]
-        public float VisionBonus = 3f;
-    }
-}
index a46399797c186c1b38770f3b87131bea4cb442a0..3a792589713bf60a542631f13a6bca6bea8e7a86 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Damage;
 using Content.Shared.Electrocution;
 using Content.Shared.Explosion;
+using Content.Shared.Eye.Blinding.Systems;
 using Content.Shared.IdentityManagement.Components;
 using Content.Shared.Movement.Systems;
 using Content.Shared.Radio;
@@ -26,6 +27,11 @@ public partial class InventorySystem
         SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent);
         SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
 
+        // Eye/vision events
+        SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent);
+        SubscribeLocalEvent<InventoryComponent, GetEyeProtectionEvent>(RelayInventoryEvent);
+        SubscribeLocalEvent<InventoryComponent, GetBlurEvent>(RelayInventoryEvent);
+
         SubscribeLocalEvent<InventoryComponent, GetVerbsEvent<EquipmentVerb>>(OnGetStrippingVerbs);
     }
 
index 49b82a09667dfd93830534759665938c3cb2e83b..a9bdb2816851f3a8a9fe68025bb60ef130926ba6 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Examine;
 using Content.Shared.Eye.Blinding;
+using Content.Shared.Eye.Blinding.Systems;
 using Content.Shared.IdentityManagement;
 using Robust.Shared.Network;
 
@@ -11,13 +12,14 @@ namespace Content.Shared.Traits.Assorted;
 public sealed class PermanentBlindnessSystem : EntitySystem
 {
     [Dependency] private readonly INetManager _net = default!;
-    [Dependency] private readonly SharedBlindingSystem _blinding = default!;
+    [Dependency] private readonly BlindableSystem _blinding = default!;
 
     /// <inheritdoc/>
     public override void Initialize()
     {
         SubscribeLocalEvent<PermanentBlindnessComponent, ComponentStartup>(OnStartup);
         SubscribeLocalEvent<PermanentBlindnessComponent, ComponentShutdown>(OnShutdown);
+        SubscribeLocalEvent<PermanentBlindnessComponent, CanSeeAttemptEvent>(OnTrySee);
         SubscribeLocalEvent<PermanentBlindnessComponent, ExaminedEvent>(OnExamined);
     }
 
@@ -31,11 +33,17 @@ public sealed class PermanentBlindnessSystem : EntitySystem
 
     private void OnShutdown(EntityUid uid, PermanentBlindnessComponent component, ComponentShutdown args)
     {
-        _blinding.AdjustBlindSources(uid, -1);
+        _blinding.UpdateIsBlind(uid);
     }
 
     private void OnStartup(EntityUid uid, PermanentBlindnessComponent component, ComponentStartup args)
     {
-        _blinding.AdjustBlindSources(uid, 1);
+        _blinding.UpdateIsBlind(uid);
+    }
+
+    private void OnTrySee(EntityUid uid, PermanentBlindnessComponent component, CanSeeAttemptEvent args)
+    {
+        if (component.LifeStage <= ComponentLifeStage.Running)
+            args.Cancel();
     }
 }
index 74d715ee255f6255c25877e58fa22c7778ae90dc..462c6292227b879fe5b9a755c0dd5c85dd702f22 100644 (file)
   kind: source
   path: "/Textures/Shaders/blurryy.swsl"
 
-- type: shader
-  id: Dim
-  kind: source
-  path: "/Textures/Shaders/dim.swsl"
-
 # cloaking distortion effect
 - type: shader
   id: Stealth
diff --git a/Resources/Textures/Shaders/dim.swsl b/Resources/Textures/Shaders/dim.swsl
deleted file mode 100644 (file)
index 19ae636..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-uniform highp float DAMAGE_AMOUNT;
-
-void fragment() {
-
-     // Higher exponent -> stronger blinding effect
-
-     // Gradually mixes between the texture mix and a full-white texture, causing the "blinding" effect
-     highp vec4 mixed = mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), DAMAGE_AMOUNT);
-
-     COLOR = vec4(mixed.rgb, DAMAGE_AMOUNT);
-}
-