MeteorSystem.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using Content.Server.Administration.Logs;
  2. using Content.Server.Destructible;
  3. using Content.Shared.Damage;
  4. using Content.Shared.Database;
  5. using Content.Shared.FixedPoint;
  6. using Content.Shared.Mobs.Systems;
  7. using Robust.Shared.Physics.Events;
  8. using Robust.Shared.Player;
  9. namespace Content.Server.Mining;
  10. public sealed class MeteorSystem : EntitySystem
  11. {
  12. [Dependency] private readonly IAdminLogManager _adminLog = default!;
  13. [Dependency] private readonly DamageableSystem _damageable = default!;
  14. [Dependency] private readonly DestructibleSystem _destructible = default!;
  15. [Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
  16. /// <inheritdoc/>
  17. public override void Initialize()
  18. {
  19. SubscribeLocalEvent<MeteorComponent, StartCollideEvent>(OnCollide);
  20. }
  21. private void OnCollide(EntityUid uid, MeteorComponent component, ref StartCollideEvent args)
  22. {
  23. if (TerminatingOrDeleted(args.OtherEntity) || TerminatingOrDeleted(uid))
  24. return;
  25. if (component.HitList.Contains(args.OtherEntity))
  26. return;
  27. FixedPoint2 threshold;
  28. if (_mobThreshold.TryGetDeadThreshold(args.OtherEntity, out var mobThreshold))
  29. {
  30. threshold = mobThreshold.Value;
  31. if (HasComp<ActorComponent>(args.OtherEntity))
  32. _adminLog.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.OtherEntity):player} was struck by meteor {ToPrettyString(uid):ent} and killed instantly.");
  33. }
  34. else if (_destructible.TryGetDestroyedAt(args.OtherEntity, out var destroyThreshold))
  35. {
  36. threshold = destroyThreshold.Value;
  37. }
  38. else
  39. {
  40. threshold = FixedPoint2.MaxValue;
  41. }
  42. var otherEntDamage = CompOrNull<DamageableComponent>(args.OtherEntity)?.TotalDamage ?? FixedPoint2.Zero;
  43. // account for the damage that the other entity has already taken: don't overkill
  44. threshold -= otherEntDamage;
  45. // The max amount of damage our meteor can take before breaking.
  46. var maxMeteorDamage = _destructible.DestroyedAt(uid) - CompOrNull<DamageableComponent>(uid)?.TotalDamage ?? FixedPoint2.Zero;
  47. // Cap damage so we don't overkill the meteor
  48. var trueDamage = FixedPoint2.Min(maxMeteorDamage, threshold);
  49. var damage = component.DamageTypes * trueDamage;
  50. _damageable.TryChangeDamage(args.OtherEntity, damage, true, origin: uid);
  51. _damageable.TryChangeDamage(uid, damage);
  52. if (!TerminatingOrDeleted(args.OtherEntity))
  53. component.HitList.Add(args.OtherEntity);
  54. }
  55. }