From 78373ba74104eedf77206f28ea7adb21d0f8b1c5 Mon Sep 17 00:00:00 2001 From: Whatstone <166147148+whatston3@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:36:41 -0500 Subject: [PATCH] Cryosleep Fallbacks (#2482) --- .../CryoSleep/CryosleepWakeupWindow.cs | 2 +- .../CryoSleep/CryoSleepFallbackComponent.cs | 6 ++++ .../CryoSleep/CryoSleepSystem.Returning.cs | 30 +++++++++++++++---- .../_NF/CryoSleep/SharedCryoSleepSystem.cs | 2 +- .../_NF/cryosleep/cryosleep-component.ftl | 2 +- Resources/Maps/_NF/Outpost/frontier.yml | 2 +- .../Entities/Structures/Machines/cryopod.yml | 9 +++++- 7 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 Content.Server/_NF/CryoSleep/CryoSleepFallbackComponent.cs diff --git a/Content.Client/CryoSleep/CryosleepWakeupWindow.cs b/Content.Client/CryoSleep/CryosleepWakeupWindow.cs index 35c9129bc6c..205676d1833 100644 --- a/Content.Client/CryoSleep/CryosleepWakeupWindow.cs +++ b/Content.Client/CryoSleep/CryosleepWakeupWindow.cs @@ -97,7 +97,7 @@ private void OnWakeupResponse(WakeupRequestMessage.Response response) DenyButton.Disabled = false; if (response.Status == ReturnToBodyStatus.Occupied) Label.SetMessage(Loc.GetString("cryo-wakeup-result-occupied")); - else if (response.Status == ReturnToBodyStatus.CryopodMissing) + else if (response.Status == ReturnToBodyStatus.NoCryopodAvailable) Label.SetMessage(Loc.GetString("cryo-wakeup-result-no-cryopod")); else if (response.Status == ReturnToBodyStatus.BodyMissing) Label.SetMessage(Loc.GetString("cryo-wakeup-result-no-body")); diff --git a/Content.Server/_NF/CryoSleep/CryoSleepFallbackComponent.cs b/Content.Server/_NF/CryoSleep/CryoSleepFallbackComponent.cs new file mode 100644 index 00000000000..93d026e62e6 --- /dev/null +++ b/Content.Server/_NF/CryoSleep/CryoSleepFallbackComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server.CryoSleep; + +// In the case a user's body cannot be revived in a cryopod, this component denotes an entity as being +// a fallback to revive them at. +[RegisterComponent] +public sealed partial class CryoSleepFallbackComponent : Component; diff --git a/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs b/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs index cd316180a95..f8b108d9631 100644 --- a/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs +++ b/Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs @@ -59,12 +59,30 @@ public ReturnToBodyStatus TryReturnToBody(MindComponent mind, bool force = false return ReturnToBodyStatus.NotAGhost; var cryopod = storedBody!.Value.Cryopod; - if (!Exists(cryopod) || Deleted(cryopod) || !TryComp(cryopod, out var cryoComp)) - return ReturnToBodyStatus.CryopodMissing; - var body = storedBody.Value.Body; - if (IsOccupied(cryoComp) || !_container.Insert(body, cryoComp.BodyContainer)) - return ReturnToBodyStatus.Occupied; + if (!Exists(cryopod) || Deleted(cryopod) || !TryComp(cryopod, out var cryoComp)) + { + var fallbackQuery = EntityQueryEnumerator(); + bool foundFallback = false; + while (fallbackQuery.MoveNext(out cryopod, out _, out cryoComp)) + { + if (!IsOccupied(cryoComp) && _container.Insert(body, cryoComp.BodyContainer)) + { + foundFallback = true; + break; + } + } + + // No valid cryopod, all fallbacks occupied or missing. + if (!foundFallback) + return ReturnToBodyStatus.NoCryopodAvailable; + } + else + { + // NOTE: if the pod is occupied but still exists, do not let the user teleport. + if (IsOccupied(cryoComp!) || !_container.Insert(body, cryoComp!.BodyContainer)) + return ReturnToBodyStatus.Occupied; + } _storedBodies.Remove(id.Value); _mind.ControlMob(id.Value, body); @@ -74,7 +92,7 @@ public ReturnToBodyStatus TryReturnToBody(MindComponent mind, bool force = false _popup.PopupEntity(Loc.GetString("cryopod-wake-up", ("entity", body)), body); - RaiseLocalEvent(body, new CryosleepWakeUpEvent(storedBody.Value.Cryopod, id), true); + RaiseLocalEvent(body, new CryosleepWakeUpEvent(cryopod, id), true); _adminLogger.Add(LogType.LateJoin, LogImpact.Medium, $"{id.Value} has returned from cryosleep!"); return ReturnToBodyStatus.Success; diff --git a/Content.Shared/_NF/CryoSleep/SharedCryoSleepSystem.cs b/Content.Shared/_NF/CryoSleep/SharedCryoSleepSystem.cs index eca2a460fd0..109c25225c7 100644 --- a/Content.Shared/_NF/CryoSleep/SharedCryoSleepSystem.cs +++ b/Content.Shared/_NF/CryoSleep/SharedCryoSleepSystem.cs @@ -64,7 +64,7 @@ public enum ReturnToBodyStatus : byte Success, Occupied, BodyMissing, - CryopodMissing, + NoCryopodAvailable, NotAGhost, Disabled } diff --git a/Resources/Locale/en-US/_NF/cryosleep/cryosleep-component.ftl b/Resources/Locale/en-US/_NF/cryosleep/cryosleep-component.ftl index eaefd477674..480cd9209a8 100644 --- a/Resources/Locale/en-US/_NF/cryosleep/cryosleep-component.ftl +++ b/Resources/Locale/en-US/_NF/cryosleep/cryosleep-component.ftl @@ -11,7 +11,7 @@ cryo-wakeup-window-accept-button = Accept cryo-wakeup-window-deny-button = Cancel cryo-wakeup-window-rules = You are going to try to return from your cryosleep! You do not know anything that happened since the moment you went to sleep. Accept this and continue? cryo-wakeup-result-occupied = The cryopod is occupied! Try waiting a bit. -cryo-wakeup-result-no-cryopod = The cryopod went missing! Uh oh. +cryo-wakeup-result-no-cryopod = No cryopods were available to return your body to. cryo-wakeup-result-no-body = You do not have a cryosleeping body! cryo-wakeup-result-disabled = Returning from cryosleep is disabled on this server. diff --git a/Resources/Maps/_NF/Outpost/frontier.yml b/Resources/Maps/_NF/Outpost/frontier.yml index 52e74899159..a3d549ebd3c 100644 --- a/Resources/Maps/_NF/Outpost/frontier.yml +++ b/Resources/Maps/_NF/Outpost/frontier.yml @@ -27613,7 +27613,7 @@ entities: rot: -1.5707963267948966 rad pos: 33.5,17.5 parent: 2173 -- proto: MachineCryoSleepPod +- proto: MachineCryoSleepPodFallback entities: - uid: 1394 components: diff --git a/Resources/Prototypes/_NF/Entities/Structures/Machines/cryopod.yml b/Resources/Prototypes/_NF/Entities/Structures/Machines/cryopod.yml index 7fe8f3f28a5..3953ed59c02 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Machines/cryopod.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Machines/cryopod.yml @@ -30,7 +30,14 @@ containers: body_container: !type:ContainerSlot -# WIP for a medical bounty reclaimer machine +# If cryopods get deleted, this one is considered as a safe fallback. +- type: entity + id: MachineCryoSleepPodFallback + parent: MachineCryoSleepPod + suffix: Fallback + components: + - type: CryoSleepFallback + - type: entity parent: [BaseStructureDisableToolUse, BaseStructureIndestructible, BaseMachinePowered] id: MachineMedicalBountyRedemption