Add a toggle for colorblind friendly progress bar colors (#25318)

* Add a toggle for progress bar colors

* yeah this thing

* PJB review

* optimization
This commit is contained in:
Nemanja
2024-03-09 06:43:19 -05:00
committed by GitHub
parent 3f32fa804c
commit f3f4616c49
8 changed files with 169 additions and 84 deletions

View File

@@ -1,9 +1,9 @@
using System.Numerics; using System.Numerics;
using Content.Shared.DoAfter; using Content.Shared.DoAfter;
using Content.Client.UserInterface.Systems;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Graphics;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -18,6 +18,7 @@ public sealed class DoAfterOverlay : Overlay
private readonly IPlayerManager _player; private readonly IPlayerManager _player;
private readonly SharedTransformSystem _transform; private readonly SharedTransformSystem _transform;
private readonly MetaDataSystem _meta; private readonly MetaDataSystem _meta;
private readonly ProgressColorSystem _progressColor;
private readonly Texture _barTexture; private readonly Texture _barTexture;
private readonly ShaderInstance _shader; private readonly ShaderInstance _shader;
@@ -40,6 +41,7 @@ public sealed class DoAfterOverlay : Overlay
_player = player; _player = player;
_transform = _entManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>(); _transform = _entManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
_meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>(); _meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>();
_progressColor = _entManager.System<ProgressColorSystem>();
var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon"); var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite); _barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
@@ -125,7 +127,7 @@ public sealed class DoAfterOverlay : Overlay
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds); elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds; var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds;
var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0; var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0;
color = new Color(1f, 0f, 0f, flash ? alpha : 0f); color = GetProgressColor(0, flash ? alpha : 0);
} }
else else
{ {
@@ -146,14 +148,8 @@ public sealed class DoAfterOverlay : Overlay
handle.SetTransform(Matrix3.Identity); handle.SetTransform(Matrix3.Identity);
} }
public static Color GetProgressColor(float progress, float alpha = 1f) public Color GetProgressColor(float progress, float alpha = 1f)
{ {
if (progress >= 1.0f) return _progressColor.GetProgressColor(progress).WithAlpha(alpha);
{
return new Color(0f, 1f, 0f, alpha);
}
// lerp
var hue = (5f / 18f) * progress;
return Color.FromHsv((hue, 1f, 0.75f, alpha));
} }
} }

View File

@@ -4,57 +4,59 @@
xmlns:xNamespace="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:xNamespace="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:Content.Client.Stylesheets"> xmlns:s="clr-namespace:Content.Client.Stylesheets">
<BoxContainer Orientation="Vertical"> <BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Vertical" Margin="8 8 8 8" VerticalExpand="True"> <ScrollContainer VerticalExpand="True" HorizontalExpand="True">
<Label Text="{Loc 'ui-options-general-ui-style'}" <BoxContainer Orientation="Vertical" Margin="8 8 8 8" VerticalExpand="True">
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}" <Label Text="{Loc 'ui-options-general-ui-style'}"
StyleClasses="LabelKeyText"/> FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
<BoxContainer Orientation="Horizontal"> StyleClasses="LabelKeyText"/>
<Label Text="{Loc 'ui-options-hud-theme'}" /> <BoxContainer Orientation="Horizontal">
<Control MinSize="4 0" /> <Label Text="{Loc 'ui-options-hud-theme'}" />
<OptionButton Name="HudThemeOption" /> <Control MinSize="4 0" />
<OptionButton Name="HudThemeOption" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'ui-options-hud-layout'}" />
<Control MinSize="4 0" />
<OptionButton Name="HudLayoutOption" />
</BoxContainer>
<Label Text="{Loc 'ui-options-general-accessibility'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'ui-options-screen-shake-intensity'}" Margin="8 0" />
<Slider Name="ScreenShakeIntensitySlider"
MinValue="0"
MaxValue="100"
Rounded="True"
MinWidth="200" />
<Label Name="ScreenShakeIntensityLabel" Margin="8 0" />
</BoxContainer>
<Label Text="{Loc 'ui-options-general-discord'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="DiscordRich" Text="{Loc 'ui-options-discordrich'}" />
<Label Text="{Loc 'ui-options-general-speech'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowLoocAboveHeadCheckBox" Text="{Loc 'ui-options-show-looc-on-head'}" />
<CheckBox Name="FancySpeechBubblesCheckBox" Text="{Loc 'ui-options-fancy-speech'}" />
<CheckBox Name="FancyNameBackgroundsCheckBox" Text="{Loc 'ui-options-fancy-name-background'}" />
<Label Text="{Loc 'ui-options-general-cursor'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowHeldItemCheckBox" Text="{Loc 'ui-options-show-held-item'}" />
<CheckBox Name="ShowCombatModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-combat-mode-indicators'}" />
<Label Text="{Loc 'ui-options-general-storage'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="OpaqueStorageWindowCheckBox" Text="{Loc 'ui-options-opaque-storage-window'}" />
<CheckBox Name="StaticStorageUI" Text="{Loc 'ui-options-static-storage-ui'}" />
<!-- <CheckBox Name="ToggleWalk" Text="{Loc 'ui-options-hotkey-toggle-walk'}" /> -->
</BoxContainer> </BoxContainer>
<BoxContainer Orientation="Horizontal"> </ScrollContainer>
<Label Text="{Loc 'ui-options-hud-layout'}" />
<Control MinSize="4 0" />
<OptionButton Name="HudLayoutOption" />
</BoxContainer>
<Label Text="{Loc 'ui-options-general-accessibility'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'ui-options-screen-shake-intensity'}" Margin="8 0" />
<Slider Name="ScreenShakeIntensitySlider"
MinValue="0"
MaxValue="100"
Rounded="True"
MinWidth="200" />
<Label Name="ScreenShakeIntensityLabel" Margin="8 0" />
</BoxContainer>
<Label Text="{Loc 'ui-options-general-discord'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="DiscordRich" Text="{Loc 'ui-options-discordrich'}" />
<Label Text="{Loc 'ui-options-general-speech'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowLoocAboveHeadCheckBox" Text="{Loc 'ui-options-show-looc-on-head'}" />
<CheckBox Name="FancySpeechBubblesCheckBox" Text="{Loc 'ui-options-fancy-speech'}" />
<CheckBox Name="FancyNameBackgroundsCheckBox" Text="{Loc 'ui-options-fancy-name-background'}" />
<Label Text="{Loc 'ui-options-general-cursor'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="ShowHeldItemCheckBox" Text="{Loc 'ui-options-show-held-item'}" />
<CheckBox Name="ShowCombatModeIndicatorsCheckBox" Text="{Loc 'ui-options-show-combat-mode-indicators'}" />
<Label Text="{Loc 'ui-options-general-storage'}"
FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}"
StyleClasses="LabelKeyText"/>
<CheckBox Name="OpaqueStorageWindowCheckBox" Text="{Loc 'ui-options-opaque-storage-window'}" />
<CheckBox Name="StaticStorageUI" Text="{Loc 'ui-options-static-storage-ui'}" />
<!-- <CheckBox Name="ToggleWalk" Text="{Loc 'ui-options-hotkey-toggle-walk'}" /> -->
</BoxContainer>
<controls:StripeBack HasBottomEdge="False" HasMargins="False"> <controls:StripeBack HasBottomEdge="False" HasMargins="False">
<Button Name="ApplyButton" <Button Name="ApplyButton"
Text="{Loc 'ui-options-apply'}" Text="{Loc 'ui-options-apply'}"

View File

@@ -64,6 +64,7 @@ namespace Content.Client.Options.UI.Tabs
FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled; FancySpeechBubblesCheckBox.OnToggled += OnCheckBoxToggled;
FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled; FancyNameBackgroundsCheckBox.OnToggled += OnCheckBoxToggled;
EnableColorNameCheckBox.OnToggled += OnCheckBoxToggled; EnableColorNameCheckBox.OnToggled += OnCheckBoxToggled;
ColorblindFriendlyCheckBox.OnToggled += OnCheckBoxToggled;
ReducedMotionCheckBox.OnToggled += OnCheckBoxToggled; ReducedMotionCheckBox.OnToggled += OnCheckBoxToggled;
ScreenShakeIntensitySlider.OnValueChanged += OnScreenShakeIntensitySliderChanged; ScreenShakeIntensitySlider.OnValueChanged += OnScreenShakeIntensitySliderChanged;
// ToggleWalk.OnToggled += OnCheckBoxToggled; // ToggleWalk.OnToggled += OnCheckBoxToggled;
@@ -78,6 +79,7 @@ namespace Content.Client.Options.UI.Tabs
FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles); FancySpeechBubblesCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground); FancyNameBackgroundsCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatFancyNameBackground);
EnableColorNameCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableColorName); EnableColorNameCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableColorName);
ColorblindFriendlyCheckBox.Pressed = _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly);
ReducedMotionCheckBox.Pressed = _cfg.GetCVar(CCVars.ReducedMotion); ReducedMotionCheckBox.Pressed = _cfg.GetCVar(CCVars.ReducedMotion);
ScreenShakeIntensitySlider.Value = _cfg.GetCVar(CCVars.ScreenShakeIntensity) * 100f; ScreenShakeIntensitySlider.Value = _cfg.GetCVar(CCVars.ScreenShakeIntensity) * 100f;
// ToggleWalk.Pressed = _cfg.GetCVar(CCVars.ToggleWalk); // ToggleWalk.Pressed = _cfg.GetCVar(CCVars.ToggleWalk);
@@ -123,6 +125,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed); _cfg.SetCVar(CCVars.ChatEnableFancyBubbles, FancySpeechBubblesCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed); _cfg.SetCVar(CCVars.ChatFancyNameBackground, FancyNameBackgroundsCheckBox.Pressed);
_cfg.SetCVar(CCVars.ChatEnableColorName, EnableColorNameCheckBox.Pressed); _cfg.SetCVar(CCVars.ChatEnableColorName, EnableColorNameCheckBox.Pressed);
_cfg.SetCVar(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox.Pressed);
_cfg.SetCVar(CCVars.ReducedMotion, ReducedMotionCheckBox.Pressed); _cfg.SetCVar(CCVars.ReducedMotion, ReducedMotionCheckBox.Pressed);
_cfg.SetCVar(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider.Value / 100f); _cfg.SetCVar(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider.Value / 100f);
// _cfg.SetCVar(CCVars.ToggleWalk, ToggleWalk.Pressed); // _cfg.SetCVar(CCVars.ToggleWalk, ToggleWalk.Pressed);
@@ -149,6 +152,7 @@ namespace Content.Client.Options.UI.Tabs
var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles); var isFancyChatSame = FancySpeechBubblesCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableFancyBubbles);
var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground); var isFancyBackgroundSame = FancyNameBackgroundsCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatFancyNameBackground);
var isEnableColorNameSame = EnableColorNameCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableColorName); var isEnableColorNameSame = EnableColorNameCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableColorName);
var isColorblindFriendly = ColorblindFriendlyCheckBox.Pressed == _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly);
var isReducedMotionSame = ReducedMotionCheckBox.Pressed == _cfg.GetCVar(CCVars.ReducedMotion); var isReducedMotionSame = ReducedMotionCheckBox.Pressed == _cfg.GetCVar(CCVars.ReducedMotion);
var isScreenShakeIntensitySame = Math.Abs(ScreenShakeIntensitySlider.Value / 100f - _cfg.GetCVar(CCVars.ScreenShakeIntensity)) < 0.01f; var isScreenShakeIntensitySame = Math.Abs(ScreenShakeIntensitySlider.Value / 100f - _cfg.GetCVar(CCVars.ScreenShakeIntensity)) < 0.01f;
// var isToggleWalkSame = ToggleWalk.Pressed == _cfg.GetCVar(CCVars.ToggleWalk); // var isToggleWalkSame = ToggleWalk.Pressed == _cfg.GetCVar(CCVars.ToggleWalk);
@@ -164,6 +168,7 @@ namespace Content.Client.Options.UI.Tabs
isFancyChatSame && isFancyChatSame &&
isFancyBackgroundSame && isFancyBackgroundSame &&
isEnableColorNameSame && isEnableColorNameSame &&
isColorblindFriendly &&
isReducedMotionSame && isReducedMotionSame &&
isScreenShakeIntensitySame && isScreenShakeIntensitySame &&
// isToggleWalkSame && // isToggleWalkSame &&

View File

@@ -8,6 +8,8 @@ using Robust.Client.Graphics;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using System.Numerics; using System.Numerics;
using Content.Shared.StatusIcon.Components; using Content.Shared.StatusIcon.Components;
using Content.Client.UserInterface.Systems;
using Robust.Shared.Prototypes;
using static Robust.Shared.Maths.Color; using static Robust.Shared.Maths.Color;
namespace Content.Client.Overlays; namespace Content.Client.Overlays;
@@ -17,19 +19,25 @@ namespace Content.Client.Overlays;
/// </summary> /// </summary>
public sealed class EntityHealthBarOverlay : Overlay public sealed class EntityHealthBarOverlay : Overlay
{ {
[Dependency] private readonly IPrototypeManager _prototype = default!;
private readonly IEntityManager _entManager; private readonly IEntityManager _entManager;
private readonly SharedTransformSystem _transform; private readonly SharedTransformSystem _transform;
private readonly MobStateSystem _mobStateSystem; private readonly MobStateSystem _mobStateSystem;
private readonly MobThresholdSystem _mobThresholdSystem; private readonly MobThresholdSystem _mobThresholdSystem;
private readonly ProgressColorSystem _progressColor;
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV; public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
public HashSet<string> DamageContainers = new(); public HashSet<string> DamageContainers = new();
private readonly ShaderInstance _shader;
public EntityHealthBarOverlay(IEntityManager entManager) public EntityHealthBarOverlay(IEntityManager entManager)
{ {
IoCManager.InjectDependencies(this);
_entManager = entManager; _entManager = entManager;
_transform = _entManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>(); _transform = _entManager.System<SharedTransformSystem>();
_mobStateSystem = _entManager.EntitySysManager.GetEntitySystem<MobStateSystem>(); _mobStateSystem = _entManager.System<MobStateSystem>();
_mobThresholdSystem = _entManager.EntitySysManager.GetEntitySystem<MobThresholdSystem>(); _mobThresholdSystem = _entManager.System<MobThresholdSystem>();
_progressColor = _entManager.System<ProgressColorSystem>();
_shader = _prototype.Index<ShaderPrototype>("unshaded").Instance();
} }
protected override void Draw(in OverlayDrawArgs args) protected override void Draw(in OverlayDrawArgs args)
@@ -42,6 +50,8 @@ public sealed class EntityHealthBarOverlay : Overlay
var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale)); var scaleMatrix = Matrix3.CreateScale(new Vector2(scale, scale));
var rotationMatrix = Matrix3.CreateRotation(-rotation); var rotationMatrix = Matrix3.CreateRotation(-rotation);
handle.UseShader(_shader);
var query = _entManager.AllEntityQueryEnumerator<MobThresholdsComponent, MobStateComponent, DamageableComponent, SpriteComponent>(); var query = _entManager.AllEntityQueryEnumerator<MobThresholdsComponent, MobStateComponent, DamageableComponent, SpriteComponent>();
while (query.MoveNext(out var uid, while (query.MoveNext(out var uid,
out var mobThresholdsComponent, out var mobThresholdsComponent,
@@ -147,26 +157,11 @@ public sealed class EntityHealthBarOverlay : Overlay
return (0, true); return (0, true);
} }
public static Color GetProgressColor(float progress, bool crit) public Color GetProgressColor(float progress, bool crit)
{ {
if (progress >= 1.0f) if (crit)
{ progress = 0;
return SeaBlue;
}
if (!crit) return _progressColor.GetProgressColor(progress);
{
switch (progress)
{
case > 0.90F:
return SeaBlue;
case > 0.50F:
return Violet;
case > 0.15F:
return Ruber;
}
}
return VividGamboge;
} }
} }

View File

@@ -1,5 +1,5 @@
using System.Numerics; using System.Numerics;
using Content.Client.DoAfter; using Content.Client.UserInterface.Systems;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
@@ -9,11 +9,13 @@ namespace Content.Client.UserInterface.Controls
{ {
public float Progress; public float Progress;
private readonly ProgressColorSystem _progressColor = IoCManager.Resolve<IEntityManager>().System<ProgressColorSystem>();
protected override void Draw(DrawingHandleScreen handle) protected override void Draw(DrawingHandleScreen handle)
{ {
var dims = Texture != null ? GetDrawDimensions(Texture) : UIBox2.FromDimensions(Vector2.Zero, PixelSize); var dims = Texture != null ? GetDrawDimensions(Texture) : UIBox2.FromDimensions(Vector2.Zero, PixelSize);
dims.Top = Math.Max(dims.Bottom - dims.Bottom * Progress,0); dims.Top = Math.Max(dims.Bottom - dims.Bottom * Progress,0);
handle.DrawRect(dims, DoAfterOverlay.GetProgressColor(Progress)); handle.DrawRect(dims, _progressColor.GetProgressColor(Progress));
base.Draw(handle); base.Draw(handle);
} }

View File

@@ -0,0 +1,77 @@
using Content.Shared.CCVar;
using Robust.Shared.Configuration;
namespace Content.Client.UserInterface.Systems;
/// <summary>
/// This system handles getting an interpolated color based on the value of a cvar.
/// </summary>
public sealed class ProgressColorSystem : EntitySystem
{
[Dependency] private readonly IConfigurationManager _configuration = default!;
private bool _colorBlindFriendly;
private static readonly Color[] Plasma =
{
new(240, 249, 33),
new(248, 149, 64),
new(204, 71, 120),
new(126, 3, 168),
new(13, 8, 135)
};
/// <inheritdoc/>
public override void Initialize()
{
Subs.CVar(_configuration, CCVars.AccessibilityColorblindFriendly, OnColorBlindFriendlyChanged, true);
}
private void OnColorBlindFriendlyChanged(bool value, in CVarChangeInfo info)
{
_colorBlindFriendly = value;
}
public Color GetProgressColor(float progress)
{
if (!_colorBlindFriendly)
{
if (progress >= 1.0f)
{
return new Color(0f, 1f, 0f);
}
// lerp
var hue = 5f / 18f * progress;
return Color.FromHsv((hue, 1f, 0.75f, 1f));
}
return InterpolateColorGaussian(Plasma, progress);
}
/// <summary>
/// Interpolates between multiple colors based on a gaussian distribution.
/// Taken from https://stackoverflow.com/a/26103117
/// </summary>
public static Color InterpolateColorGaussian(Color[] colors, double x)
{
double r = 0.0, g = 0.0, b = 0.0;
var total = 0f;
var step = 1.0 / (colors.Length - 1);
var mu = 0.0;
const double sigma2 = 0.035;
foreach(var color in colors)
{
var percent = Math.Exp(-(x - mu) * (x - mu) / (2.0 * sigma2)) / Math.Sqrt(2.0 * Math.PI * sigma2);
total += (float) percent;
mu += step;
r += color.R * percent;
g += color.G * percent;
b += color.B * percent;
}
return new Color((float) r / total, (float) g / total, (float) b / total);
}
}

View File

@@ -1578,6 +1578,13 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<float> ScreenShakeIntensity = public static readonly CVarDef<float> ScreenShakeIntensity =
CVarDef.Create("accessibility.screen_shake_intensity", 1f, CVar.CLIENTONLY | CVar.ARCHIVE); CVarDef.Create("accessibility.screen_shake_intensity", 1f, CVar.CLIENTONLY | CVar.ARCHIVE);
/// <summary>
/// A generic toggle for various visual effects that are color sensitive.
/// As of 2/16/24, only applies to progress bar colors.
/// </summary>
public static readonly CVarDef<bool> AccessibilityColorblindFriendly =
CVarDef.Create("accessibility.colorblind_friendly", false, CVar.CLIENTONLY | CVar.ARCHIVE);
/* /*
* CHAT * CHAT
*/ */

View File

@@ -46,6 +46,7 @@ ui-options-show-looc-on-head = Show LOOC chat above characters head
ui-options-fancy-speech = Show names in speech bubbles ui-options-fancy-speech = Show names in speech bubbles
ui-options-fancy-name-background = Add background to speech bubble names ui-options-fancy-name-background = Add background to speech bubble names
ui-options-enable-color-name = Add colors to character names ui-options-enable-color-name = Add colors to character names
ui-options-colorblind-friendly = Colorblind friendly mode
ui-options-reduced-motion = Reduce motion of visual effects ui-options-reduced-motion = Reduce motion of visual effects
ui-options-screen-shake-intensity = Screen shake intensity ui-options-screen-shake-intensity = Screen shake intensity
ui-options-screen-shake-percent = { TOSTRING($intensity, "P0") } ui-options-screen-shake-percent = { TOSTRING($intensity, "P0") }