Skip to content

Commit

Permalink
Merge pull request #1702 from hivehum/new-vision-disabilities
Browse files Browse the repository at this point in the history
[DV/Nyano/Frontier Port] Deuteranopia (DogVision) and Tritanopia (UltraVision) traits
  • Loading branch information
formlessnameless authored Feb 17, 2025
2 parents 4106daa + 3328df3 commit 9c0abfc
Show file tree
Hide file tree
Showing 17 changed files with 318 additions and 0 deletions.
1 change: 1 addition & 0 deletions Content.Client/Options/UI/OptionsMenu.xaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:tabs="clr-namespace:Content.Client.Options.UI.Tabs"
xmlns:dtabs="clr-namespace:Content.Client._DV.Options.UI.Tabs"
Title="{Loc 'ui-options-title'}"
MinSize="800 450">
<TabContainer Name="Tabs" Access="Public">
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/AccessibilityTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<CheckBox Name="DisableSinguloWarpingCheckBox" Text="{Loc 'ui-options-disable-singulo-warp'}" />
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
<CheckBox Name="DisableFiltersCheckBox" Text="{Loc 'ui-options-no-filters'}" />
<ui:OptionSlider Name="ChatWindowOpacitySlider" Title="{Loc 'ui-options-chat-window-opacity'}" />
<ui:OptionSlider Name="ScreenShakeIntensitySlider" Title="{Loc 'ui-options-screen-shake-intensity'}" />
<CheckBox Name="AutoFillHighlightsCheckBox" Text="{Loc 'ui-options-auto-fill-highlights'}" />
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/Options/UI/Tabs/AccessibilityTab.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Shared._Impstation.CCVar;
using Content.Shared._DV.CCVars;
using Content.Shared.CCVar;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
Expand All @@ -17,6 +18,7 @@ public AccessibilityTab()
Control.AddOptionCheckBox(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox);
Control.AddOptionCheckBox(CCVars.ReducedMotion, ReducedMotionCheckBox);
Control.AddOptionCheckBox(ImpCCVars.DisableSinguloWarping, DisableSinguloWarpingCheckBox);
Control.AddOptionCheckBox(DCCVars.NoVisionFilters, DisableFiltersCheckBox);
Control.AddOptionPercentSlider(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider);
Control.AddOptionPercentSlider(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider);
Control.AddOptionCheckBox(ImpCCVars.ChatAutoFillHighlights, AutoFillHighlightsCheckBox);
Expand Down
52 changes: 52 additions & 0 deletions Content.Client/_DV/Overlays/UltraVisionOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Content.Shared.Abilities;
using System.Numerics;

namespace Content.Client._DV.Overlays;

public sealed partial class UltraVisionOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] IEntityManager _entityManager = default!;


public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _ultraVisionShader;

public UltraVisionOverlay()
{
IoCManager.InjectDependencies(this);
_ultraVisionShader = _prototypeManager.Index<ShaderPrototype>("UltraVision").Instance().Duplicate();
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (_playerManager.LocalEntity is not { Valid: true } player
|| !_entityManager.HasComponent<UltraVisionComponent>(player))
{
return false;
}

return base.BeforeDraw(in args);
}

protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture is null)
return;

_ultraVisionShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);

var worldHandle = args.WorldHandle;
var viewport = args.WorldBounds;
worldHandle.SetTransform(Matrix3x2.Identity);
worldHandle.UseShader(_ultraVisionShader);
worldHandle.DrawRect(viewport, Color.White);
worldHandle.UseShader(null); // important - as of writing, construction overlay breaks without this
}
}
61 changes: 61 additions & 0 deletions Content.Client/_DV/Overlays/UltraVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Content.Shared.Abilities;
using Content.Shared._DV.CCVars;
using Robust.Client.Graphics;
using Robust.Shared.Configuration;
using Robust.Shared.Player;

namespace Content.Client._DV.Overlays;

public sealed partial class UltraVisionSystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly ISharedPlayerManager _playerMan = default!;

private UltraVisionOverlay _overlay = default!;

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

SubscribeLocalEvent<UltraVisionComponent, ComponentInit>(OnUltraVisionInit);
SubscribeLocalEvent<UltraVisionComponent, ComponentShutdown>(OnUltraVisionShutdown);
SubscribeLocalEvent<UltraVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<UltraVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);

Subs.CVar(_cfg, DCCVars.NoVisionFilters, OnNoVisionFiltersChanged);

_overlay = new();
}

private void OnUltraVisionInit(EntityUid uid, UltraVisionComponent component, ComponentInit args)
{
if (uid == _playerMan.LocalEntity && !_cfg.GetCVar(DCCVars.NoVisionFilters))
_overlayMan.AddOverlay(_overlay);
}

private void OnUltraVisionShutdown(EntityUid uid, UltraVisionComponent component, ComponentShutdown args)
{
if (uid == _playerMan.LocalEntity)
_overlayMan.RemoveOverlay(_overlay);
}

private void OnPlayerAttached(EntityUid uid, UltraVisionComponent component, LocalPlayerAttachedEvent args)
{
if (!_cfg.GetCVar(DCCVars.NoVisionFilters))
_overlayMan.AddOverlay(_overlay);
}

private void OnPlayerDetached(EntityUid uid, UltraVisionComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}

private void OnNoVisionFiltersChanged(bool enabled)
{
if (enabled)
_overlayMan.RemoveOverlay(_overlay);
else
_overlayMan.AddOverlay(_overlay);
}
}
52 changes: 52 additions & 0 deletions Content.Client/_Nyanotrasen/Overlays/DogVisionOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Content.Shared.Abilities;

namespace Content.Client._Nyanotrasen.Overlays;

public sealed partial class DogVisionOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] IEntityManager _entityManager = default!;


public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _dogVisionShader;

public DogVisionOverlay()
{
IoCManager.InjectDependencies(this);
_dogVisionShader = _prototypeManager.Index<ShaderPrototype>("DogVision").Instance().Duplicate();
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (_playerManager.LocalEntity is not { Valid: true } player
|| !_entityManager.HasComponent<DogVisionComponent>(player))
{
return false;
}

return base.BeforeDraw(in args);
}

protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture is null)
return;

_dogVisionShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);

var worldHandle = args.WorldHandle;
var viewport = args.WorldBounds;
worldHandle.SetTransform(Matrix3x2.Identity);
worldHandle.UseShader(_dogVisionShader);
worldHandle.DrawRect(viewport, Color.White);
worldHandle.UseShader(null); // important - as of writing, construction overlay breaks without this
}
}
61 changes: 61 additions & 0 deletions Content.Client/_Nyanotrasen/Overlays/DogVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Content.Shared.Abilities;
using Content.Shared._DV.CCVars;
using Robust.Client.Graphics;
using Robust.Shared.Configuration;
using Robust.Shared.Player;

namespace Content.Client._Nyanotrasen.Overlays;

public sealed partial class DogVisionSystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly ISharedPlayerManager _playerMan = default!;

private DogVisionOverlay _overlay = default!;

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

SubscribeLocalEvent<DogVisionComponent, ComponentInit>(OnDogVisionInit);
SubscribeLocalEvent<DogVisionComponent, ComponentShutdown>(OnDogVisionShutdown);
SubscribeLocalEvent<DogVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DogVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);

Subs.CVar(_cfg, DCCVars.NoVisionFilters, OnNoVisionFiltersChanged);

_overlay = new();
}

private void OnDogVisionInit(EntityUid uid, DogVisionComponent component, ComponentInit args)
{
if (uid == _playerMan.LocalEntity && !_cfg.GetCVar(DCCVars.NoVisionFilters))
_overlayMan.AddOverlay(_overlay);
}

private void OnDogVisionShutdown(EntityUid uid, DogVisionComponent component, ComponentShutdown args)
{
if (uid == _playerMan.LocalEntity)
_overlayMan.RemoveOverlay(_overlay);
}

private void OnPlayerAttached(EntityUid uid, DogVisionComponent component, LocalPlayerAttachedEvent args)
{
if (!_cfg.GetCVar(DCCVars.NoVisionFilters))
_overlayMan.AddOverlay(_overlay);
}

private void OnPlayerDetached(EntityUid uid, DogVisionComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}

private void OnNoVisionFiltersChanged(bool enabled)
{
if (enabled)
_overlayMan.RemoveOverlay(_overlay);
else
_overlayMan.AddOverlay(_overlay);
}
}
8 changes: 8 additions & 0 deletions Content.Shared/_DV/Abilities/UltraVisionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Abilities;

[RegisterComponent]
[NetworkedComponent]

public sealed partial class UltraVisionComponent : Component
{}
5 changes: 5 additions & 0 deletions Content.Shared/_DV/CCVars/DCCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,9 @@ public sealed class DCCVars
public static readonly CVarDef<int> MailLargeMalus =
CVarDef.Create("mail.largemalus", -250, CVar.SERVERONLY);

/// <summary>
/// Disables all vision filters for species like Vulpkanin or Harpies. There are good reasons someone might want to disable these.
/// </summary>
public static readonly CVarDef<bool> NoVisionFilters =
CVarDef.Create("accessibility.no_vision_filters", false, CVar.CLIENTONLY | CVar.ARCHIVE);
}
10 changes: 10 additions & 0 deletions Content.Shared/_Nyanotrasen/Abilities/DogVisionComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;

namespace Content.Shared.Abilities
{
[RegisterComponent]
[NetworkedComponent]

public sealed partial class DogVisionComponent : Component
{}
}
4 changes: 4 additions & 0 deletions Resources/Locale/en-US/_DV/escape-menu/options-menu.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ui-options-tab-extra = Extra
ui-options-general-forknotice = Note: These settings are fork-specific and might not apply on other servers.
ui-options-no-filters = Disable trait-specific shaders
10 changes: 10 additions & 0 deletions Resources/Locale/en-US/_DV/traits/traits.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,13 @@ trait-estradiol-sensitive-desc = Your body is capable of taking on Nanotrasen's
trait-testosterone-sensitive-name = Testosterone sensitive
trait-testosterone-sensitive-desc = Your body is capable of taking on Nanotrasen's special masculinization medicines.
# impstation edit - removing mentions of unimplemented species

trait-ultravision-name = Ultraviolet vision
trait-ultravision-desc = Whether through custom bionic eyes, random mutation,
or something else, you perceive the world with ultraviolet light.
trait-deuteranopia-name = Deuteranopia
trait-deuteranopia-desc = Whether through custom bionic eyes, random mutation,
or something else, you have red-green colour blindness.
4 changes: 4 additions & 0 deletions Resources/Prototypes/_DV/Shaders/birdvision.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- type: shader
id: UltraVision
kind: source
path: "/Textures/_DV/Shaders/ultravision.swsl"
15 changes: 15 additions & 0 deletions Resources/Prototypes/_DV/Traits/disabilities.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- type: trait
id: UltraVision
name: trait-ultravision-name
description: trait-ultravision-desc
category: Disabilities
components:
- type: UltraVision

- type: trait
id: DogVision
name: trait-deuteranopia-name
description: trait-deuteranopia-desc
category: Disabilities
components:
- type: DogVision
4 changes: 4 additions & 0 deletions Resources/Prototypes/_Nyanotrasen/Shaders/dogvision.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- type: shader
id: DogVision
kind: source
path: "/Textures/_Nyanotrasen/Shaders/dogvision.swsl"
14 changes: 14 additions & 0 deletions Resources/Textures/_DV/Shaders/ultravision.swsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
uniform sampler2D SCREEN_TEXTURE;

void fragment() {
highp vec4 color = zTextureSpec(SCREEN_TEXTURE, UV);

highp mat3 m = mat3(
vec3(0.000,1.000,0.000),
vec3(0.000,0.000,1.000),
vec3(-0.165,0.165,1.000)
);
highp vec3 result = color.rgb * m;

COLOR = vec4(result, 1);
}
14 changes: 14 additions & 0 deletions Resources/Textures/_Nyanotrasen/Shaders/dogvision.swsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
uniform sampler2D SCREEN_TEXTURE;

void fragment() {
highp vec4 color = zTextureSpec(SCREEN_TEXTURE, UV);

highp mat3 m = mat3(
vec3(0.625,0.375,0.000),
vec3(0.700,0.300,0.000),
vec3(0.000,0.300,0.700)
);
highp vec3 result = color.rgb * m;

COLOR = vec4(result, 1);
}

0 comments on commit 9c0abfc

Please sign in to comment.