SleepZoneSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using Content.Shared.Coordinates;
  2. using Robust.Shared.Map;
  3. using Robust.Shared.GameObjects;
  4. using Robust.Shared.Log; // Added for ILogManager and ISawmill
  5. using Robust.Shared.IoC; // Added for Dependency attribute
  6. using Robust.Shared.GameStates; // Needed for [RegisterComponent] if SleepZoneComponent wasn't partial
  7. using Robust.Shared.Serialization.Manager.Attributes; // Needed for [DataField]
  8. using System.Numerics;
  9. namespace Content.Shared.Civ14.SleepZone;
  10. public sealed partial class SleepZoneSystem : EntitySystem
  11. {
  12. [Dependency] private readonly ILogManager _log = default!;
  13. [Dependency] private readonly SharedTransformSystem _xform = default!;
  14. [Dependency] private readonly IEntityManager _entities = default!;
  15. private ISawmill _sawmill = default!;
  16. public override void Initialize()
  17. {
  18. base.Initialize();
  19. _sawmill = _log.GetSawmill("sleepzone");
  20. }
  21. /// <summary>
  22. /// Tries to find the first entity with the prototype "SleepZoneBed".
  23. /// </summary>
  24. /// <param name="bedId">The EntityUid of the found bed, or EntityUid.Invalid if none was found.</param>
  25. /// <returns>True if a bed was found, false otherwise.</returns>
  26. public bool TryFindSleepZoneBed(out EntityUid bedId)
  27. {
  28. const string bedPrototypeId = "SleepZoneBed";
  29. // More efficient: directly query for the prototype we want
  30. var query = _entities.EntityQueryEnumerator<MetaDataComponent, TransformComponent>();
  31. while (query.MoveNext(out var uid, out var meta, out _))
  32. {
  33. if (meta.EntityPrototype?.ID == bedPrototypeId)
  34. {
  35. bedId = uid;
  36. return true;
  37. }
  38. }
  39. bedId = EntityUid.Invalid;
  40. return false;
  41. }
  42. public void StartSleep(EntityUid entity)
  43. {
  44. // Use TryComp for cleaner component checking
  45. if (!_entities.TryGetComponent<SleepZoneComponent>(entity, out var sleepZone))
  46. {
  47. _sawmill.Debug($"Entity {entity} does not have a SleepZoneComponent, cannot start sleep.");
  48. return;
  49. }
  50. if (sleepZone.IsSleeping)
  51. {
  52. _sawmill.Debug($"Entity {entity} is already sleeping.");
  53. return;
  54. }
  55. // Store the original absolute world position
  56. sleepZone.Origin = Transform(entity).Coordinates;
  57. _sawmill.Info($"Saved origin {sleepZone.Origin} for entity {entity}.");
  58. if (TryTeleportToBed(entity))
  59. {
  60. sleepZone.IsSleeping = true;
  61. _sawmill.Info($"Entity {entity} started sleeping successfully.");
  62. }
  63. else
  64. {
  65. _sawmill.Warning($"Entity {entity} failed to start sleeping because teleportation to bed failed.");
  66. // Reset origin if teleport fails, as the entity hasn't moved.
  67. sleepZone.Origin = EntityCoordinates.Invalid;
  68. }
  69. }
  70. private bool TryTeleportToBed(EntityUid entityToTeleport)
  71. {
  72. if (TryFindSleepZoneBed(out var bedEntity))
  73. {
  74. // Use EntityExists for clarity
  75. if (!_entities.EntityExists(bedEntity))
  76. {
  77. _sawmill.Warning($"Found bed {bedEntity} but it no longer exists.");
  78. return false;
  79. }
  80. var targetCoords = Transform(bedEntity).Coordinates;
  81. _sawmill.Info($"Found bed {bedEntity}, teleporting {entityToTeleport} into it at {targetCoords}.");
  82. // Use _xform for SetCoordinates
  83. _xform.SetCoordinates(entityToTeleport, targetCoords);
  84. return true; // Teleport successful
  85. }
  86. else
  87. {
  88. _sawmill.Warning($"Could not find any entity with prototype 'SleepZoneBed' to teleport {entityToTeleport} to.");
  89. return false;
  90. }
  91. }
  92. public void WakeUp(EntityUid entity)
  93. {
  94. // Use TryComp for cleaner component checking
  95. if (_entities.TryGetComponent<SleepZoneComponent>(entity, out var sleepZone))
  96. {
  97. if (!sleepZone.IsSleeping)
  98. {
  99. _sawmill.Debug($"Entity {entity} is not sleeping, cannot wake up.");
  100. return;
  101. }
  102. // Check if the origin is valid before teleporting
  103. if (!sleepZone.Origin.HasValue) // Use .HasValue for nullable types
  104. {
  105. // Use ToPrettyString for better entity logging if available, otherwise fallback
  106. var entityString = _entities.ToPrettyString(entity);
  107. _sawmill.Warning($"Entity {entityString} has no Origin coordinates stored, cannot teleport back.");
  108. // Decide what to do here - maybe leave them in bed? Or teleport to a default spot?
  109. // For now, just mark as not sleeping.
  110. sleepZone.IsSleeping = false;
  111. return;
  112. }
  113. _sawmill.Info($"Waking up entity {_entities.ToPrettyString(entity)}, returning to {sleepZone.Origin.Value}."); // Log the .Value
  114. _xform.SetCoordinates(entity, sleepZone.Origin.Value);
  115. sleepZone.IsSleeping = false;
  116. // Clear the origin after use
  117. sleepZone.Origin = null;
  118. }
  119. else
  120. {
  121. _sawmill.Debug($"Entity {entity} does not have a SleepZoneComponent, cannot wake up.");
  122. }
  123. }
  124. }