| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- using Content.Shared.Damage;
- using Content.Shared.FixedPoint;
- using Content.Shared.Mobs;
- using Content.Shared.Mobs.Components;
- using Content.Shared.Mobs.Systems;
- using Content.Shared.Traits.Assorted;
- using JetBrains.Annotations;
- using Robust.Client.Graphics;
- using Robust.Client.Player;
- using Robust.Client.UserInterface;
- using Robust.Client.UserInterface.Controllers;
- using Robust.Shared.Player;
- namespace Content.Client.UserInterface.Systems.DamageOverlays;
- [UsedImplicitly]
- public sealed class DamageOverlayUiController : UIController
- {
- [Dependency] private readonly IOverlayManager _overlayManager = default!;
- [Dependency] private readonly IPlayerManager _playerManager = default!;
- [UISystemDependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
- private Overlays.DamageOverlay _overlay = default!;
- public override void Initialize()
- {
- _overlay = new Overlays.DamageOverlay();
- SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttach);
- SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
- SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
- SubscribeLocalEvent<MobThresholdChecked>(OnThresholdCheck);
- }
- private void OnPlayerAttach(LocalPlayerAttachedEvent args)
- {
- ClearOverlay();
- if (!EntityManager.TryGetComponent<MobStateComponent>(args.Entity, out var mobState))
- return;
- if (mobState.CurrentState != MobState.Dead)
- UpdateOverlays(args.Entity, mobState);
- _overlayManager.AddOverlay(_overlay);
- }
- private void OnPlayerDetached(LocalPlayerDetachedEvent args)
- {
- _overlayManager.RemoveOverlay(_overlay);
- ClearOverlay();
- }
- private void OnMobStateChanged(MobStateChangedEvent args)
- {
- if (args.Target != _playerManager.LocalEntity)
- return;
- UpdateOverlays(args.Target, args.Component);
- }
- private void OnThresholdCheck(ref MobThresholdChecked args)
- {
- if (args.Target != _playerManager.LocalEntity)
- return;
- UpdateOverlays(args.Target, args.MobState, args.Damageable, args.Threshold);
- }
- private void ClearOverlay()
- {
- _overlay.DeadLevel = 0f;
- _overlay.CritLevel = 0f;
- _overlay.PainLevel = 0f;
- _overlay.OxygenLevel = 0f;
- }
- //TODO: Jezi: adjust oxygen and hp overlays to use appropriate systems once bodysim is implemented
- private void UpdateOverlays(EntityUid entity, MobStateComponent? mobState, DamageableComponent? damageable = null, MobThresholdsComponent? thresholds = null)
- {
- if (mobState == null && !EntityManager.TryGetComponent(entity, out mobState) ||
- thresholds == null && !EntityManager.TryGetComponent(entity, out thresholds) ||
- damageable == null && !EntityManager.TryGetComponent(entity, out damageable))
- return;
- if (!_mobThresholdSystem.TryGetIncapThreshold(entity, out var foundThreshold, thresholds))
- return; //this entity cannot die or crit!!
- if (!thresholds.ShowOverlays)
- {
- ClearOverlay();
- return; //this entity intentionally has no overlays
- }
- var critThreshold = foundThreshold.Value;
- _overlay.State = mobState.CurrentState;
- switch (mobState.CurrentState)
- {
- case MobState.Alive:
- {
- FixedPoint2 painLevel = 0;
- _overlay.PainLevel = 0;
- if (!EntityManager.HasComponent<PainNumbnessComponent>(entity))
- {
- foreach (var painDamageType in damageable.PainDamageGroups)
- {
- damageable.DamagePerGroup.TryGetValue(painDamageType, out var painDamage);
- painLevel += painDamage;
- }
- _overlay.PainLevel = FixedPoint2.Min(1f, painLevel / critThreshold).Float();
- if (_overlay.PainLevel < 0.05f) // Don't show damage overlay if they're near enough to max.
- {
- _overlay.PainLevel = 0;
- }
- }
- if (damageable.DamagePerGroup.TryGetValue("Airloss", out var oxyDamage))
- {
- _overlay.OxygenLevel = FixedPoint2.Min(1f, oxyDamage / critThreshold).Float();
- }
- _overlay.CritLevel = 0;
- _overlay.DeadLevel = 0;
- break;
- }
- case MobState.Critical:
- {
- if (!_mobThresholdSystem.TryGetDeadPercentage(entity,
- FixedPoint2.Max(0.0, damageable.TotalDamage), out var critLevel))
- return;
- _overlay.CritLevel = critLevel.Value.Float();
- _overlay.PainLevel = 0;
- _overlay.DeadLevel = 0;
- break;
- }
- case MobState.Dead:
- {
- _overlay.PainLevel = 0;
- _overlay.CritLevel = 0;
- break;
- }
- }
- }
- }
|