using Content.Server._Sunrise.Heartbeat.Components; using Content.Shared._Sunrise.Heartbeat; using Content.Shared.Damage; using Content.Shared.Damage.Systems; using Content.Shared.GameTicking; using Content.Shared.Mobs; using Robust.Server.Audio; using Robust.Shared.Audio; using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server._Sunrise.Heartbeat.Systems; // TODO: Сделать возможность с помощью стетоскопа услышать сердцебиение человека public sealed partial class HeartbeatSystem : EntitySystem { [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly ISharedPlayerManager _player = default!; [Dependency] private readonly IGameTiming _timing = default!; private static readonly SoundSpecifier HeartbeatSound = new SoundPathSpecifier("/Audio/_Sunrise/Effects/heartbeat.ogg", AudioParams.Default.WithVolume(-3f)); private static readonly HashSet DisabledSessions = []; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMobStateChanged); SubscribeLocalEvent(OnDamage); SubscribeNetworkEvent(OnOptionsChanged); SubscribeLocalEvent(_ => DisabledSessions.Clear()); } public override void Update(float frameTime) { base.Update(frameTime); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var activeHeartbeat)) { if (_timing.CurTime < activeHeartbeat.NextHeartbeatTime) continue; if (IsDisabledByClient(uid)) continue; _audio.PlayGlobal(HeartbeatSound, uid, AudioParams.Default.WithPitchScale(activeHeartbeat.Pitch)); SetNextTime(activeHeartbeat); } } /// /// Устанавливает время следующего удара сердца /// private void SetNextTime(ActiveHeartbeatComponent component) { component.NextHeartbeatTime = _timing.CurTime + component.NextHeartbeatCooldown; } private bool IsDisabledByClient(EntityUid player) { if (!_player.TryGetSessionByEntity(player, out var session)) return true; if (DisabledSessions.Contains(session)) return true; return false; } private static void OnOptionsChanged(HeartbeatOptionsChangedEvent ev, EntitySessionEventArgs args) { if (ev.Enabled) DisabledSessions.Remove(args.SenderSession); else DisabledSessions.Add(args.SenderSession); } }