StaminaActiveSystem.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using Content.Shared._Stalker.Stamina;
  2. using Content.Shared.Damage.Components;
  3. using Content.Shared.Damage.Systems;
  4. using Content.Shared.Movement.Components;
  5. using Content.Shared.Movement.Systems;
  6. using Robust.Shared.Physics.Components;
  7. using Content.Server.Chat.Systems;
  8. using Robust.Shared.Random;
  9. using Robust.Shared.Timing;
  10. namespace Content.Server._Stalker.Stamina;
  11. public sealed class StaminaActiveSystem : EntitySystem
  12. {
  13. [Dependency] private readonly StaminaSystem _stamina = default!;
  14. [Dependency] private readonly MovementSpeedModifierSystem _speed = default!;
  15. [Dependency] private readonly ChatSystem _chat = default!;
  16. [Dependency] private readonly IRobustRandom _random = default!;
  17. [Dependency] private readonly IGameTiming _gameTiming = default!;
  18. private ISawmill _sawmill = default!;
  19. public override void Initialize()
  20. {
  21. SubscribeLocalEvent<StaminaActiveComponent, RefreshMovementSpeedModifiersEvent>(OnRefresh);
  22. }
  23. public override void Update(float frameTime)
  24. {
  25. base.Update(frameTime);
  26. var query = EntityQueryEnumerator<StaminaComponent, MovementSpeedModifierComponent, StaminaActiveComponent, InputMoverComponent>();
  27. while (query.MoveNext(out var uid, out var stamina, out var modifier, out var active, out var input))
  28. {
  29. var curTime = _gameTiming.CurTime;
  30. if (stamina.StaminaDamage > stamina.SlowdownThreshold)
  31. {
  32. if ((curTime - stamina.LastMessageTime).TotalSeconds >= 6)
  33. {
  34. _chat.TryEmoteWithChat(uid, "BreathGasp");
  35. stamina.LastMessageTime = curTime; // Update last message time
  36. }
  37. }
  38. // If our entity is slowed, we can't apply new speed/speed modifiers
  39. // Because CurrentSprintSpeed will change
  40. if (!active.Slowed)
  41. {
  42. active.SprintModifier = modifier.BaseWalkSpeed / modifier.BaseSprintSpeed;
  43. }
  44. if (!TryComp<PhysicsComponent>(uid, out var phys))
  45. return;
  46. // If Walk button pressed we will apply stamina damage.
  47. if (input.HeldMoveButtons.HasFlag(MoveButtons.Walk) && !active.Slowed && phys.LinearVelocity.Length() != 0)
  48. {
  49. _stamina.TakeStaminaDamage(uid, active.RunStaminaDamage, stamina, visual: false);
  50. }
  51. // If our entity gets through SlowThreshold, we will apply slowing.
  52. // If our entity is slowed already, we don't need to multiply SprintModifier.
  53. if (stamina.StaminaDamage >= active.SlowThreshold && active.Slowed == false)
  54. {
  55. active.Slowed = true;
  56. active.Change = true;
  57. _speed.RefreshMovementSpeedModifiers(uid);
  58. return;
  59. }
  60. // If our entity revives until ReviveStaminaLevel we will remove same SprintModifier.
  61. // If our entity is already revived, we _don't need to remove SprintModifier.
  62. if (stamina.StaminaDamage <= active.ReviveStaminaLevel && active.Slowed)
  63. {
  64. active.Slowed = false;
  65. active.Change = true;
  66. _speed.RefreshMovementSpeedModifiers(uid);
  67. return;
  68. }
  69. }
  70. }
  71. private void OnRefresh(EntityUid uid, StaminaActiveComponent component, RefreshMovementSpeedModifiersEvent args)
  72. {
  73. if (!component.Change)
  74. return;
  75. var sprint = component.Slowed
  76. ? component.SprintModifier
  77. : args.SprintSpeedModifier;
  78. args.ModifySpeed(args.WalkSpeedModifier, sprint);
  79. }
  80. }