| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using Content.Server.Radiation.Components;
- using Content.Server.Radiation.Events;
- using Content.Shared.Hands;
- using Content.Shared.Interaction;
- using Content.Shared.Inventory.Events;
- using Content.Shared.Radiation.Components;
- using Content.Shared.Radiation.Systems;
- using Robust.Server.Audio;
- using Robust.Server.GameObjects;
- using Robust.Server.Player;
- namespace Content.Server.Radiation.Systems;
- public sealed class GeigerSystem : SharedGeigerSystem
- {
- [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
- [Dependency] private readonly RadiationSystem _radiation = default!;
- [Dependency] private readonly AudioSystem _audio = default!;
- [Dependency] private readonly IPlayerManager _player = default!;
- private static readonly float ApproxEqual = 0.01f;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<GeigerComponent, ActivateInWorldEvent>(OnActivate);
- SubscribeLocalEvent<GeigerComponent, GotEquippedEvent>(OnEquipped);
- SubscribeLocalEvent<GeigerComponent, GotEquippedHandEvent>(OnEquippedHand);
- SubscribeLocalEvent<GeigerComponent, GotUnequippedEvent>(OnUnequipped);
- SubscribeLocalEvent<GeigerComponent, GotUnequippedHandEvent>(OnUnequippedHand);
- SubscribeLocalEvent<RadiationSystemUpdatedEvent>(OnUpdate);
- }
- private void OnActivate(Entity<GeigerComponent> geiger, ref ActivateInWorldEvent args)
- {
- if (args.Handled || !args.Complex || geiger.Comp.AttachedToSuit)
- return;
- args.Handled = true;
- SetEnabled(geiger, !geiger.Comp.IsEnabled);
- }
- private void OnEquipped(Entity<GeigerComponent> geiger, ref GotEquippedEvent args)
- {
- if (geiger.Comp.AttachedToSuit)
- SetEnabled(geiger, true);
- SetUser(geiger, args.Equipee);
- }
- private void OnEquippedHand(Entity<GeigerComponent> geiger, ref GotEquippedHandEvent args)
- {
- if (geiger.Comp.AttachedToSuit)
- return;
- SetUser(geiger, args.User);
- }
- private void OnUnequipped(Entity<GeigerComponent> geiger, ref GotUnequippedEvent args)
- {
- if (geiger.Comp.AttachedToSuit)
- SetEnabled(geiger, false);
- SetUser(geiger, null);
- }
- private void OnUnequippedHand(Entity<GeigerComponent> geiger, ref GotUnequippedHandEvent args)
- {
- if (geiger.Comp.AttachedToSuit)
- return;
- SetUser(geiger, null);
- }
- private void OnUpdate(RadiationSystemUpdatedEvent ev)
- {
- // update only active geiger counters
- // deactivated shouldn't have rad receiver component
- var query = EntityQueryEnumerator<GeigerComponent, RadiationReceiverComponent>();
- while (query.MoveNext(out var uid, out var geiger, out var receiver))
- {
- var rads = receiver.CurrentRadiation;
- SetCurrentRadiation(uid, geiger, rads);
- }
- }
- private void SetCurrentRadiation(EntityUid uid, GeigerComponent component, float rads)
- {
- // check that it's approx equal
- if (MathHelper.CloseTo(component.CurrentRadiation, rads, ApproxEqual))
- return;
- var curLevel = component.DangerLevel;
- var newLevel = RadsToLevel(rads);
- component.CurrentRadiation = rads;
- component.DangerLevel = newLevel;
- if (curLevel != newLevel)
- {
- UpdateAppearance(uid, component);
- UpdateSound(uid, component);
- }
- Dirty(uid, component);
- }
- private void SetUser(Entity<GeigerComponent> component, EntityUid? user)
- {
- if (component.Comp.User == user)
- return;
- component.Comp.User = user;
- Dirty(component);
- UpdateSound(component, component);
- }
- private void SetEnabled(Entity<GeigerComponent> geiger, bool isEnabled)
- {
- var component = geiger.Comp;
- if (component.IsEnabled == isEnabled)
- return;
- component.IsEnabled = isEnabled;
- if (!isEnabled)
- {
- component.CurrentRadiation = 0f;
- component.DangerLevel = GeigerDangerLevel.None;
- }
- _radiation.SetCanReceive(geiger, isEnabled);
- UpdateAppearance(geiger, component);
- UpdateSound(geiger, component);
- Dirty(geiger, component);
- }
- private void UpdateAppearance(EntityUid uid, GeigerComponent? component = null,
- AppearanceComponent? appearance = null)
- {
- if (!Resolve(uid, ref component, ref appearance, false))
- return;
- _appearance.SetData(uid, GeigerVisuals.IsEnabled, component.IsEnabled, appearance);
- _appearance.SetData(uid, GeigerVisuals.DangerLevel, component.DangerLevel, appearance);
- }
- private void UpdateSound(EntityUid uid, GeigerComponent? component = null)
- {
- if (!Resolve(uid, ref component, false))
- return;
- component.Stream = _audio.Stop(component.Stream);
- 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);
- component.Stream = _audio.PlayGlobal(sound, session, param)?.Entity;
- }
- public static GeigerDangerLevel RadsToLevel(float rads)
- {
- return rads switch
- {
- < 0.2f => GeigerDangerLevel.None,
- < 1f => GeigerDangerLevel.Low,
- < 3f => GeigerDangerLevel.Med,
- < 6f => GeigerDangerLevel.High,
- _ => GeigerDangerLevel.Extreme
- };
- }
- }
|