using Content.Shared.Coordinates; using Robust.Shared.Map; using Robust.Shared.GameObjects; using Robust.Shared.Log; // Added for ILogManager and ISawmill using Robust.Shared.IoC; // Added for Dependency attribute using Robust.Shared.GameStates; // Needed for [RegisterComponent] if SleepZoneComponent wasn't partial using Robust.Shared.Serialization.Manager.Attributes; // Needed for [DataField] using System.Numerics; namespace Content.Shared.Civ14.SleepZone; public sealed partial class SleepZoneSystem : EntitySystem { [Dependency] private readonly ILogManager _log = default!; [Dependency] private readonly SharedTransformSystem _xform = default!; [Dependency] private readonly IEntityManager _entities = default!; private ISawmill _sawmill = default!; public override void Initialize() { base.Initialize(); _sawmill = _log.GetSawmill("sleepzone"); } /// /// Tries to find the first entity with the prototype "SleepZoneBed". /// /// The EntityUid of the found bed, or EntityUid.Invalid if none was found. /// True if a bed was found, false otherwise. public bool TryFindSleepZoneBed(out EntityUid bedId) { const string bedPrototypeId = "SleepZoneBed"; // More efficient: directly query for the prototype we want var query = _entities.EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var meta, out _)) { if (meta.EntityPrototype?.ID == bedPrototypeId) { bedId = uid; return true; } } bedId = EntityUid.Invalid; return false; } public void StartSleep(EntityUid entity) { // Use TryComp for cleaner component checking if (!_entities.TryGetComponent(entity, out var sleepZone)) { _sawmill.Debug($"Entity {entity} does not have a SleepZoneComponent, cannot start sleep."); return; } if (sleepZone.IsSleeping) { _sawmill.Debug($"Entity {entity} is already sleeping."); return; } // Store the original absolute world position sleepZone.Origin = Transform(entity).Coordinates; _sawmill.Info($"Saved origin {sleepZone.Origin} for entity {entity}."); if (TryTeleportToBed(entity)) { sleepZone.IsSleeping = true; _sawmill.Info($"Entity {entity} started sleeping successfully."); } else { _sawmill.Warning($"Entity {entity} failed to start sleeping because teleportation to bed failed."); // Reset origin if teleport fails, as the entity hasn't moved. sleepZone.Origin = EntityCoordinates.Invalid; } } private bool TryTeleportToBed(EntityUid entityToTeleport) { if (TryFindSleepZoneBed(out var bedEntity)) { // Use EntityExists for clarity if (!_entities.EntityExists(bedEntity)) { _sawmill.Warning($"Found bed {bedEntity} but it no longer exists."); return false; } var targetCoords = Transform(bedEntity).Coordinates; _sawmill.Info($"Found bed {bedEntity}, teleporting {entityToTeleport} into it at {targetCoords}."); // Use _xform for SetCoordinates _xform.SetCoordinates(entityToTeleport, targetCoords); return true; // Teleport successful } else { _sawmill.Warning($"Could not find any entity with prototype 'SleepZoneBed' to teleport {entityToTeleport} to."); return false; } } public void WakeUp(EntityUid entity) { // Use TryComp for cleaner component checking if (_entities.TryGetComponent(entity, out var sleepZone)) { if (!sleepZone.IsSleeping) { _sawmill.Debug($"Entity {entity} is not sleeping, cannot wake up."); return; } // Check if the origin is valid before teleporting if (!sleepZone.Origin.HasValue) // Use .HasValue for nullable types { // Use ToPrettyString for better entity logging if available, otherwise fallback var entityString = _entities.ToPrettyString(entity); _sawmill.Warning($"Entity {entityString} has no Origin coordinates stored, cannot teleport back."); // Decide what to do here - maybe leave them in bed? Or teleport to a default spot? // For now, just mark as not sleeping. sleepZone.IsSleeping = false; return; } _sawmill.Info($"Waking up entity {_entities.ToPrettyString(entity)}, returning to {sleepZone.Origin.Value}."); // Log the .Value _xform.SetCoordinates(entity, sleepZone.Origin.Value); sleepZone.IsSleeping = false; // Clear the origin after use sleepZone.Origin = null; } else { _sawmill.Debug($"Entity {entity} does not have a SleepZoneComponent, cannot wake up."); } } }