fish-station/Content.Server/_Sunrise/Heartbeat/Systems/HeartbeatSystem.Crit.cs
2025-12-26 17:44:36 +03:00

62 lines
2.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Content.Server._Sunrise.Heartbeat.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs;
namespace Content.Server._Sunrise.Heartbeat.Systems;
public sealed partial class HeartbeatSystem
{
// Минимальное и максимальное время между ударами сердца
private const float MinimumCooldown = 0.5f;
private const float MaximumCooldown = 3f;
private void OnMobStateChanged(Entity<CritHeartbeatComponent> ent, ref MobStateChangedEvent args)
{
if (args.NewMobState != MobState.Critical)
{
RemComp<ActiveHeartbeatComponent>(ent);
return;
}
var activeHeartbeat = EnsureComp<ActiveHeartbeatComponent>(ent);
TryCalculateCurrentState((ent.Owner, activeHeartbeat));
SetNextTime(activeHeartbeat);
}
/// <summary>
/// Подтягивает значения эффектов в зависимости от того, насколько игрок продамажен
/// Чем выше урон -> тем медленнее бьется сердце и тем более глухой звук
/// </summary>
private void OnDamage(Entity<ActiveHeartbeatComponent> ent, ref DamageChangedEvent args)
{
TryCalculateCurrentState(ent, args.Damageable);
}
/// <summary>
/// Подсчитывает нужные данные о текущем уроне тела и в зависимости от них задает нужный pitch и cooldown для сердцебиения
/// </summary>
/// <param name="ent"></param>
/// <param name="damageable"></param>
/// <returns></returns>
private bool TryCalculateCurrentState(Entity<ActiveHeartbeatComponent> ent, DamageableComponent? damageable = null)
{
if (!Resolve(ent.Owner, ref damageable))
return false;
var totalDamage = damageable.TotalDamage.Float();
var pitch = Math.Min(1f, 100f / totalDamage);
var excess = Math.Max(0f, totalDamage - 100f);
var cooldownSeconds = MinimumCooldown + (excess / 100f) * (MaximumCooldown - MinimumCooldown);
ent.Comp.Pitch = pitch;
ent.Comp.NextHeartbeatCooldown = TimeSpan.FromSeconds(cooldownSeconds);
return true;
}
}