NarcolepsySystem.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using Content.Shared.Bed.Sleep;
  2. using Content.Shared.StatusEffect;
  3. using Robust.Shared.Random;
  4. namespace Content.Server.Traits.Assorted;
  5. /// <summary>
  6. /// This handles narcolepsy, causing the affected to fall asleep uncontrollably at a random interval.
  7. /// </summary>
  8. public sealed class NarcolepsySystem : EntitySystem
  9. {
  10. [ValidatePrototypeId<StatusEffectPrototype>]
  11. private const string StatusEffectKey = "ForcedSleep"; // Same one used by N2O and other sleep chems.
  12. [Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
  13. [Dependency] private readonly IRobustRandom _random = default!;
  14. /// <inheritdoc/>
  15. public override void Initialize()
  16. {
  17. SubscribeLocalEvent<NarcolepsyComponent, ComponentStartup>(SetupNarcolepsy);
  18. }
  19. private void SetupNarcolepsy(EntityUid uid, NarcolepsyComponent component, ComponentStartup args)
  20. {
  21. component.NextIncidentTime =
  22. _random.NextFloat(component.TimeBetweenIncidents.X, component.TimeBetweenIncidents.Y);
  23. }
  24. public void AdjustNarcolepsyTimer(EntityUid uid, int TimerReset, NarcolepsyComponent? narcolepsy = null)
  25. {
  26. if (!Resolve(uid, ref narcolepsy, false))
  27. return;
  28. narcolepsy.NextIncidentTime = TimerReset;
  29. }
  30. public override void Update(float frameTime)
  31. {
  32. base.Update(frameTime);
  33. var query = EntityQueryEnumerator<NarcolepsyComponent>();
  34. while (query.MoveNext(out var uid, out var narcolepsy))
  35. {
  36. narcolepsy.NextIncidentTime -= frameTime;
  37. if (narcolepsy.NextIncidentTime >= 0)
  38. continue;
  39. // Set the new time.
  40. narcolepsy.NextIncidentTime +=
  41. _random.NextFloat(narcolepsy.TimeBetweenIncidents.X, narcolepsy.TimeBetweenIncidents.Y);
  42. var duration = _random.NextFloat(narcolepsy.DurationOfIncident.X, narcolepsy.DurationOfIncident.Y);
  43. // Make sure the sleep time doesn't cut into the time to next incident.
  44. narcolepsy.NextIncidentTime += duration;
  45. _statusEffects.TryAddStatusEffect<ForcedSleepingComponent>(uid, StatusEffectKey,
  46. TimeSpan.FromSeconds(duration), false);
  47. }
  48. }
  49. }