using System.Linq; using Content.Shared.Alert; using Content.Shared.Mobs.Systems; using Content.Shared.Mobs; using Content.Shared.StatusEffectNew; using Robust.Shared.Prototypes; namespace Content.Shared._Offbrand.Wounds; public sealed partial class BrainDamageThresholdsSystem : EntitySystem { [Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnAfterBrainDamageChanged); SubscribeLocalEvent(OnAfterBrainOxygenChanged); SubscribeLocalEvent(OnUpdateMobState); SubscribeLocalEvent(OnShutdown); } private void OnShutdown(Entity ent, ref ComponentShutdown args) { if (ent.Comp.CurrentDamageEffect is { } dEffect) _statusEffects.TryRemoveStatusEffect(ent, dEffect); if (ent.Comp.CurrentOxygenEffect is { } oEffect) _statusEffects.TryRemoveStatusEffect(ent, oEffect); } private void UpdateState(Entity ent) { var brain = Comp(ent); var damageState = ent.Comp.DamageStateThresholds.HighestMatch(brain.Damage) ?? MobState.Alive; var oxygenState = ent.Comp.OxygenStateThresholds.LowestMatch(brain.Oxygen) ?? MobState.Alive; var state = ThresholdHelpers.Max(damageState, oxygenState); if (state == ent.Comp.CurrentState) return; ent.Comp.CurrentState = state; Dirty(ent); _mobState.UpdateMobState(ent); } private void OnAfterBrainDamageChanged(Entity ent, ref AfterBrainDamageChanged args) { var brain = Comp(ent); UpdateState(ent); UpdateAlert((ent.Owner, ent.Comp, brain)); var damageEffect = ent.Comp.DamageEffectThresholds.HighestMatch(brain.Damage); if (damageEffect == ent.Comp.CurrentDamageEffect) return; if (ent.Comp.CurrentDamageEffect is { } oldEffect) _statusEffects.TryRemoveStatusEffect(ent, oldEffect); if (damageEffect is { } newEffect) _statusEffects.TryUpdateStatusEffectDuration(ent, newEffect, out _); ent.Comp.CurrentDamageEffect = damageEffect; Dirty(ent); var overlays = new PotentiallyUpdateDamageOverlayEvent(ent); RaiseLocalEvent(ent, ref overlays, true); } private void OnAfterBrainOxygenChanged(Entity ent, ref AfterBrainOxygenChanged args) { var brain = Comp(ent); UpdateState(ent); var oxygenEffect = ent.Comp.OxygenEffectThresholds.LowestMatch(brain.Oxygen); if (oxygenEffect == ent.Comp.CurrentOxygenEffect) return; if (ent.Comp.CurrentOxygenEffect is { } oldEffect) _statusEffects.TryRemoveStatusEffect(ent, oldEffect); if (oxygenEffect is { } newEffect) _statusEffects.TryUpdateStatusEffectDuration(ent, newEffect, out _); ent.Comp.CurrentOxygenEffect = oxygenEffect; Dirty(ent); var overlays = new PotentiallyUpdateDamageOverlayEvent(ent); RaiseLocalEvent(ent, ref overlays, true); } private void UpdateAlert(Entity ent) { var targetEffect = ent.Comp1.DamageAlertThresholds.HighestMatch(ent.Comp2.Damage); if (targetEffect == ent.Comp1.CurrentDamageAlertThresholdState) return; ent.Comp1.CurrentDamageAlertThresholdState = targetEffect; Dirty(ent); if (targetEffect is { } effect) { _alerts.ShowAlert(ent.Owner, effect); } else { _alerts.ClearAlertCategory(ent.Owner, ent.Comp1.DamageAlertCategory); } } private void OnUpdateMobState(Entity ent, ref UpdateMobStateEvent args) { args.State = ThresholdHelpers.Max(ent.Comp.CurrentState, args.State); var overlays = new PotentiallyUpdateDamageOverlayEvent(ent); RaiseLocalEvent(ent, ref overlays, true); } }