Skip to content

Commit

Permalink
Mind Over Machine, Machine Over Mind (#1665)
Browse files Browse the repository at this point in the history
# Description

I'm going to go put powergamers on suicide watch. This PR makes it so
that specializing in psionic traits, and specializing in cybernetic
traits are both mutually exclusive. You are only allowed to have a
single cybernetric trait if you wish to have psionic traits. And you are
only allowed to have Latent Psychic with no other traits if you wish to
have Cybernetics.

Also fixes a bug with Thermographic Vision not correctly being measured
in seconds. You now get a 2 second pulse with Thermographic vision, as
intended.

# Changelog

:cl:
- tweak: Psionic traits are now mutually exclusive with cybernetic
traits, and vice versa.
- fix: Thermographic Vision now correctly measures its pulse duration in
seconds instead of nanoseconds. It provides a 2 second scan.

---------

Co-authored-by: stellar-novas <stellar_novas@riseup.net>
  • Loading branch information
VMSolidus and stellar-novas authored Jan 30, 2025
1 parent ebbada9 commit 87eb664
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Content.Client/Overlays/Switchable/BaseSwitchableOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ protected override void Draw(in OverlayDrawArgs args)

var worldHandle = args.WorldHandle;

var accumulator = Math.Clamp(Comp.PulseAccumulator, 0f, Comp.PulseTime);
var alpha = Comp.PulseTime <= 0f ? 1f : float.Lerp(1f, 0f, accumulator / Comp.PulseTime);
var accumulator = Math.Clamp((float) Comp.PulseAccumulator.TotalSeconds, 0f, Comp.PulseTime);
var alpha = Comp.PulseTime <= 0 ? 1f : float.Lerp(1f, 0f, accumulator / Comp.PulseTime);

worldHandle.SetTransform(Matrix3x2.Identity);
worldHandle.UseShader(_shader);
Expand Down
27 changes: 12 additions & 15 deletions Content.Client/Overlays/Switchable/NightVisionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System.Reflection.Metadata;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Content.Shared.Overlays.Switchable;
using Robust.Client.Graphics;
using Robust.Shared.Timing;

namespace Content.Client.Overlays.Switchable;

public sealed class NightVisionSystem : EquipmentHudSystem<NightVisionComponent>
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly ILightManager _lightManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;

private BaseSwitchableOverlay<NightVisionComponent> _overlay = default!;

Expand All @@ -27,7 +30,7 @@ protected override void OnRefreshComponentHud(EntityUid uid,
{
if (component.IsEquipment)
return;

base.OnRefreshComponentHud(uid, component, args);
}

Expand All @@ -37,7 +40,7 @@ protected override void OnRefreshEquipmentHud(EntityUid uid,
{
if (!component.IsEquipment)
return;

base.OnRefreshEquipmentHud(uid, component, args);
}

Expand All @@ -54,21 +57,15 @@ protected override void UpdateInternal(RefreshEquipmentHudEvent<NightVisionCompo
NightVisionComponent? nvComp = null;
foreach (var comp in args.Components)
{
if (comp.IsActive || comp.PulseTime > 0f && comp.PulseAccumulator < comp.PulseTime)
active = true;
else
if (!comp.IsActive && (comp.PulseTime <= 0 || _timing.CurTime < comp.PulseEndTime))
continue;

if (comp.DrawOverlay)
{
if (nvComp == null)
nvComp = comp;
else if (nvComp.PulseTime > 0f && comp.PulseTime <= 0f)
nvComp = comp;
}

if (active && nvComp is { PulseTime: <= 0 })
break;
if (nvComp == null)
nvComp = comp;
else if (!nvComp.DrawOverlay && comp.DrawOverlay)
nvComp = comp;
else if (nvComp.DrawOverlay == comp.DrawOverlay && nvComp.PulseTime > 0 && comp.PulseTime <= 0)
nvComp = comp;
}

UpdateNightVision(active);
Expand Down
4 changes: 2 additions & 2 deletions Content.Client/Overlays/Switchable/ThermalVisionOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ protected override void Draw(in OverlayDrawArgs args)
if (!_entity.TryGetComponent(player, out TransformComponent? playerXform))
return;

var accumulator = Math.Clamp(Comp.PulseAccumulator, 0f, Comp.PulseTime);
var alpha = Comp.PulseTime <= 0f ? 1f : float.Lerp(1f, 0f, accumulator / Comp.PulseTime);
var accumulator = Math.Clamp((float) Comp.PulseAccumulator.TotalSeconds, 0f, Comp.PulseTime);
var alpha = Comp.PulseTime <= 0 ? 1f : float.Lerp(1f, 0f, accumulator / Comp.PulseTime);

// Thermal vision grants some night vision (clientside light)
if (LightRadius > 0)
Expand Down
10 changes: 6 additions & 4 deletions Content.Client/Overlays/Switchable/ThermalVisionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using Content.Shared.Inventory.Events;
using Content.Shared.Overlays.Switchable;
using Robust.Client.Graphics;
using Robust.Shared.Timing;

namespace Content.Client.Overlays.Switchable;

public sealed class ThermalVisionSystem : EquipmentHudSystem<ThermalVisionComponent>
{
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly IGameTiming _timing = default!;

private ThermalVisionOverlay _thermalOverlay = default!;
private BaseSwitchableOverlay<ThermalVisionComponent> _overlay = default!;
Expand All @@ -28,7 +30,7 @@ protected override void OnRefreshComponentHud(EntityUid uid,
{
if (component.IsEquipment)
return;

base.OnRefreshComponentHud(uid, component, args);
}

Expand All @@ -38,7 +40,7 @@ protected override void OnRefreshEquipmentHud(EntityUid uid,
{
if (!component.IsEquipment)
return;

base.OnRefreshEquipmentHud(uid, component, args);
}

Expand All @@ -54,14 +56,14 @@ protected override void UpdateInternal(RefreshEquipmentHudEvent<ThermalVisionCom
var lightRadius = 0f;
foreach (var comp in args.Components)
{
if (!comp.IsActive && (comp.PulseTime <= 0f || comp.PulseAccumulator >= comp.PulseTime))
if (!comp.IsActive && (comp.PulseTime <= 0 || _timing.CurTime < comp.PulseEndTime))
continue;

if (tvComp == null)
tvComp = comp;
else if (!tvComp.DrawOverlay && comp.DrawOverlay)
tvComp = comp;
else if (tvComp.DrawOverlay == comp.DrawOverlay && tvComp.PulseTime > 0f && comp.PulseTime <= 0f)
else if (tvComp.DrawOverlay == comp.DrawOverlay && tvComp.PulseTime > 0 && comp.PulseTime <= 0)
tvComp = comp;

lightRadius = MathF.Max(lightRadius, comp.LightRadius);
Expand Down
12 changes: 7 additions & 5 deletions Content.Shared/Overlays/Switchable/SwitchableOverlayComponent.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Dynamic;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
Expand All @@ -18,14 +19,15 @@ public abstract partial class SwitchableOverlayComponent : BaseOverlayComponent
[DataField]
public bool IsEquipment;

/// <summary>
/// If it is greater than 0, overlay isn't toggled but pulsed instead
/// </summary>

[DataField]
public float PulseTime;
public float PulseTime = 0;

[ViewVariables(VVAccess.ReadOnly)]
public TimeSpan PulseAccumulator = TimeSpan.Zero;

[ViewVariables(VVAccess.ReadOnly)]
public float PulseAccumulator;
public TimeSpan PulseEndTime = TimeSpan.Zero;

[DataField]
public virtual SoundSpecifier? ActivateSound { get; set; } =
Expand Down
18 changes: 11 additions & 7 deletions Content.Shared/Overlays/Switchable/SwitchableOverlaySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ private void ActiveTick(float frameTime)

while (query.MoveNext(out var uid, out var comp))
{
if (comp.PulseTime <= 0f || comp.PulseAccumulator >= comp.PulseTime)
if (comp.PulseTime <= 0)
continue;

comp.PulseAccumulator += frameTime;
// The accumulator is for visually rendering the pulse strength decaying.
comp.PulseAccumulator += comp.PulseEndTime - _timing.CurTime;

if (comp.PulseAccumulator < comp.PulseTime)
// This line is for the actual check that shuts off the pulse when its time is up.
if (_timing.CurTime < comp.PulseEndTime)
continue;

Toggle(uid, comp, false, false);
Expand Down Expand Up @@ -101,6 +103,8 @@ private void OnHandleState(EntityUid uid, TComp component, ref ComponentHandleSt
return;

component.IsActive = state.IsActive;
if (component.PulseTime != 0)
component.PulseEndTime = _timing.CurTime + TimeSpan.FromSeconds(component.PulseTime);

RaiseSwitchableOverlayToggledEvent(uid,
component.IsEquipment ? Transform(uid).ParentUid : uid,
Expand All @@ -117,13 +121,13 @@ private void OnShutdown(EntityUid uid, TComp component, ComponentShutdown args)
{
if (component.IsEquipment)
return;

_actions.RemoveAction(uid, component.ToggleActionEntity);
}

private void OnInit(EntityUid uid, TComp component, ComponentInit args)
{
component.PulseAccumulator = component.PulseTime;
component.PulseAccumulator = TimeSpan.FromSeconds(component.PulseTime);
}

private void OnMapInit(EntityUid uid, TComp component, MapInitEvent args)
Expand All @@ -149,9 +153,9 @@ private void Toggle(EntityUid uid, TComp component, bool activate, bool playSoun
false);
}

if (component.PulseTime > 0f)
if (component.PulseTime > 0)
{
component.PulseAccumulator = activate ? 0f : component.PulseTime;
component.PulseAccumulator = activate ? TimeSpan.Zero : TimeSpan.FromSeconds(component.PulseTime);
return;
}

Expand Down
4 changes: 4 additions & 0 deletions Resources/Locale/en-US/loadouts/itemgroups.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -797,3 +797,7 @@ character-item-group-LoadoutReporterUniforms = Reporter Uniforms
# Traits - Languages
character-item-group-TraitsLanguagesBasic = Basic Languages
character-item-group-TraitsAccents = Accents
# Traits - Mind Or Machine
character-item-group-TraitsMind = Mind Over Machine
character-item-group-TraitsMachine = Machine Over Mind
59 changes: 59 additions & 0 deletions Resources/Prototypes/CharacterItemGroups/Generic/mindormachine.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
- type: characterItemGroup
id: TraitsMind
maxItems: 2
items:
- type: trait
id: HighPotential
- type: trait
id: LowPotential
- type: trait
id: LowAmplification
- type: trait
id: HighAmplification
- type: trait
id: PowerOverwhelming
- type: trait
id: LowDampening
- type: trait
id: HighDampening
- type: trait
id: DispelPower
- type: trait
id: MetapsionicPower
- type: trait
id: XenoglossyPower
- type: trait
id: PsychognomyPower
- type: trait
id: LatentPsychic

- type: characterItemGroup
id: TraitsMachine
maxItems: 2
items:
- type: trait
id: StrikingCalluses
- type: trait
id: Spinarette
- type: trait
id: BionicArm
- type: trait
id: PlateletFactories
- type: trait
id: DermalArmor
- type: trait
id: CyberEyes
- type: trait
id: FlareShielding
- type: trait
id: CyberEyesSecurity
- type: trait
id: CyberEyesMedical
- type: trait
id: CyberEyesDiagnostic
- type: trait
id: CyberEyesOmni
- type: trait
id: LightAmplification
- type: trait
id: ThermographicVision
22 changes: 22 additions & 0 deletions Resources/Prototypes/Traits/mental.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
inverted: true
traits:
- LowPotential
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitReplaceComponent
components:
Expand Down Expand Up @@ -78,6 +80,8 @@
inverted: true
traits:
- HighPotential
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitReplaceComponent
components:
Expand Down Expand Up @@ -118,6 +122,8 @@
traits:
- HighAmplification
- PowerOverwhelming
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -153,6 +159,8 @@
traits:
- LowAmplification
- PowerOverwhelming
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -188,6 +196,8 @@
traits:
- LowAmplification
- HighAmplification
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -222,6 +232,8 @@
inverted: true
traits:
- HighDampening
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -256,6 +268,8 @@
inverted: true
traits:
- LowDampening
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -289,6 +303,8 @@
inverted: true
jobs:
- ResearchDirector
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -322,6 +338,8 @@
jobs:
- ResearchDirector
- ForensicMantis
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -356,6 +374,8 @@
inverted: true
jobs:
- Librarian
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down Expand Up @@ -387,6 +407,8 @@
- !type:CharacterTraitRequirement
traits:
- AnomalousPositronics
- !type:CharacterItemGroupRequirement
group: TraitsMachine
functions:
- !type:TraitAddPsionics
psionicPowers:
Expand Down
Loading

0 comments on commit 87eb664

Please sign in to comment.