From 9b1a7dea1da1086eab0eb2421f53b0a49f3185e4 Mon Sep 17 00:00:00 2001
From: Errant <35878406+Errant-4@users.noreply.github.com>
Date: Thu, 17 Apr 2025 13:24:47 +0200
Subject: [PATCH] Geiger counters can now be heard by everyone nearby (#30463)
* haha geiger counter go brrrrrrr
* move hardcoded values to datafields
* syntax cleanup
---
.../Radiation/Systems/GeigerSystem.cs | 18 +++---
.../Radiation/Components/GeigerComponent.cs | 18 ++++++
.../Entities/Objects/Devices/geiger.yml | 62 +++++++++----------
3 files changed, 59 insertions(+), 39 deletions(-)
diff --git a/Content.Server/Radiation/Systems/GeigerSystem.cs b/Content.Server/Radiation/Systems/GeigerSystem.cs
index 9b6ed31781..6cf17c49c8 100644
--- a/Content.Server/Radiation/Systems/GeigerSystem.cs
+++ b/Content.Server/Radiation/Systems/GeigerSystem.cs
@@ -8,6 +8,7 @@ using Content.Shared.Radiation.Systems;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Server.Player;
+using Robust.Shared.Player;
namespace Content.Server.Radiation.Systems;
@@ -155,16 +156,17 @@ public sealed class GeigerSystem : SharedGeigerSystem
if (!component.Sounds.TryGetValue(component.DangerLevel, out var sounds))
return;
- if (component.User == null)
- return;
-
- if (!_player.TryGetSessionByEntity(component.User.Value, out var session))
- return;
-
var sound = _audio.ResolveSound(sounds);
- var param = sounds.Params.WithLoop(true).WithVolume(-4f);
+ var param = sounds.Params.WithLoop(true).WithVolume(component.Volume);
- component.Stream = _audio.PlayGlobal(sound, session, param)?.Entity;
+ if (component.BroadcastAudio)
+ {
+ // For some reason PlayPvs sounds quieter even at distance 0, so we need to boost the volume a bit for consistency
+ param = sounds.Params.WithLoop(true).WithVolume(component.Volume + 1.5f).WithMaxDistance(component.BroadcastRange);
+ component.Stream = _audio.PlayPvs(sound, uid, param)?.Entity;
+ }
+ else if(component.User is not null && _player.TryGetSessionByEntity(component.User.Value, out var session))
+ component.Stream = _audio.PlayGlobal(sound, session, param)?.Entity;
}
public static GeigerDangerLevel RadsToLevel(float rads)
diff --git a/Content.Shared/Radiation/Components/GeigerComponent.cs b/Content.Shared/Radiation/Components/GeigerComponent.cs
index 71edb70b37..34a262e131 100644
--- a/Content.Shared/Radiation/Components/GeigerComponent.cs
+++ b/Content.Shared/Radiation/Components/GeigerComponent.cs
@@ -83,6 +83,24 @@ public sealed partial class GeigerComponent : Component
/// Played only for current user.
///
public EntityUid? Stream;
+
+ ///
+ /// Mark true if the audio should be heard by everyone around the device
+ ///
+ [DataField]
+ public bool BroadcastAudio = false;
+
+ ///
+ /// The distance within which the broadcast tone can be heard.
+ ///
+ [DataField]
+ public float BroadcastRange = 4f;
+
+ ///
+ /// The volume of the warning tone.
+ ///
+ [DataField]
+ public float Volume = -4f;
}
[Serializable, NetSerializable]
diff --git a/Resources/Prototypes/Entities/Objects/Devices/geiger.yml b/Resources/Prototypes/Entities/Objects/Devices/geiger.yml
index f8ee24c5c6..518d28f2ee 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/geiger.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/geiger.yml
@@ -4,34 +4,34 @@
name: Geiger counter
description: A handheld device used for detecting and measuring radiation pulses.
components:
- - type: Sprite
- sprite: Objects/Tools/geiger.rsi
- layers:
- - state: geiger_base
- - state: geiger_on_idle
- map: ["enum.GeigerLayers.Screen"]
- shader: unshaded
- visible: false
- - type: Item
- sprite: Objects/Tools/geiger.rsi
- - type: Geiger
- showControl: true
- showExamine: true
- - type: Appearance
- - type: GenericVisualizer
- visuals:
- enum.GeigerVisuals.IsEnabled:
- GeigerLayers.Screen:
- True: { visible: True }
- False: { visible: False }
- enum.GeigerVisuals.DangerLevel:
- GeigerLayers.Screen:
- None: {state: geiger_on_idle}
- Low: {state: geiger_on_low}
- Med: {state: geiger_on_med}
- High: {state: geiger_on_high}
- Extreme: {state: geiger_on_ext}
- - type: PhysicalComposition
- materialComposition:
- Plastic: 100
-
+ - type: Sprite
+ sprite: Objects/Tools/geiger.rsi
+ layers:
+ - state: geiger_base
+ - state: geiger_on_idle
+ map: ["enum.GeigerLayers.Screen"]
+ shader: unshaded
+ visible: false
+ - type: Item
+ sprite: Objects/Tools/geiger.rsi
+ - type: Geiger
+ showControl: true
+ showExamine: true
+ broadcastAudio: true
+ - type: Appearance
+ - type: GenericVisualizer
+ visuals:
+ enum.GeigerVisuals.IsEnabled:
+ GeigerLayers.Screen:
+ True: { visible: True }
+ False: { visible: False }
+ enum.GeigerVisuals.DangerLevel:
+ GeigerLayers.Screen:
+ None: {state: geiger_on_idle}
+ Low: {state: geiger_on_low}
+ Med: {state: geiger_on_med}
+ High: {state: geiger_on_high}
+ Extreme: {state: geiger_on_ext}
+ - type: PhysicalComposition
+ materialComposition:
+ Plastic: 100
--
2.51.2