forked from new-frontiers-14/frontier-station-14
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat/better cryo (new-frontiers-14#706)
* Allowed to put others to cryosleep; added a do-after for this exact purpose * Added drag & drop support + made it wheelchair friendly * minor fixes * Fix those pesky errors I've made * Implement returning from cryo * New cryosleep events, various changes * Refuse to accept "passengers" when someone goes cryo * Add a way to disable returning from cryo on a server level * Delete bodies after a certain time * Fix popups
- Loading branch information
1 parent
77b0b29
commit f2d6c0d
Showing
14 changed files
with
540 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
using Robust.Client.UserInterface; | ||
using Robust.Client.UserInterface.Controls; | ||
using Robust.Client.UserInterface.CustomControls; | ||
using Robust.Shared.Configuration; | ||
using static Content.Shared.CryoSleep.SharedCryoSleepSystem; | ||
|
||
namespace Content.Client.CryoSleep; | ||
|
||
public sealed class CryosleepWakeupWindow : DefaultWindow, IEntityEventSubscriber | ||
{ | ||
[Dependency] private readonly EntityManager _entityManager = default!; | ||
|
||
public RichTextLabel Label; | ||
public Button DenyButton; | ||
public Button AcceptButton; | ||
|
||
public CryosleepWakeupWindow() | ||
{ | ||
IoCManager.InjectDependencies(this); | ||
|
||
Title = Loc.GetString("cryo-wakeup-window-title"); | ||
|
||
Contents.AddChild(new BoxContainer | ||
{ | ||
Orientation = BoxContainer.LayoutOrientation.Vertical, | ||
Children = | ||
{ | ||
new BoxContainer | ||
{ | ||
Orientation = BoxContainer.LayoutOrientation.Vertical, | ||
Children = | ||
{ | ||
(Label = new RichTextLabel() | ||
{ | ||
HorizontalExpand = true, | ||
MaxWidth = 300, | ||
StyleClasses = { } | ||
}), | ||
new BoxContainer | ||
{ | ||
Orientation = BoxContainer.LayoutOrientation.Horizontal, | ||
Align = BoxContainer.AlignMode.Center, | ||
Children = | ||
{ | ||
(AcceptButton = new Button | ||
{ | ||
Text = Loc.GetString("cryo-wakeup-window-accept-button"), | ||
}), | ||
|
||
(new Control() | ||
{ | ||
MinSize = new Vector2i(20, 0) | ||
}), | ||
|
||
(DenyButton = new Button | ||
{ | ||
Text = Loc.GetString("cryo-wakeup-window-deny-button"), | ||
}) | ||
} | ||
}, | ||
} | ||
}, | ||
} | ||
}); | ||
|
||
_entityManager.EventBus.SubscribeEvent<WakeupRequestMessage.Response>(EventSource.Network, this, OnWakeupResponse); | ||
DenyButton.OnPressed += _ => Close(); | ||
AcceptButton.OnPressed += _ => OnAccept(); | ||
} | ||
|
||
protected override void Opened() | ||
{ | ||
Label.SetMessage(Loc.GetString("cryo-wakeup-window-rules")); | ||
DenyButton.Disabled = false; | ||
AcceptButton.Disabled = false; | ||
} | ||
|
||
private void OnAccept() | ||
{ | ||
var message = new WakeupRequestMessage(); | ||
_entityManager.EntityNetManager?.SendSystemNetworkMessage(message); | ||
|
||
// Disable the buttons to make the user wait for a response | ||
AcceptButton.Disabled = true; | ||
DenyButton.Disabled = true; | ||
} | ||
|
||
private void OnWakeupResponse(WakeupRequestMessage.Response response) | ||
{ | ||
if (response.Status == ReturnToBodyStatus.Success) | ||
{ | ||
Close(); | ||
return; | ||
} | ||
|
||
// Failure | ||
DenyButton.Disabled = false; | ||
if (response.Status == ReturnToBodyStatus.Occupied) | ||
Label.SetMessage(Loc.GetString("cryo-wakeup-result-occupied")); | ||
else if (response.Status == ReturnToBodyStatus.CryopodMissing) | ||
Label.SetMessage(Loc.GetString("cryo-wakeup-result-no-cryopod")); | ||
else if (response.Status == ReturnToBodyStatus.BodyMissing) | ||
Label.SetMessage(Loc.GetString("cryo-wakeup-result-no-body")); | ||
else if (response.Status == ReturnToBodyStatus.Disabled) | ||
Label.SetMessage(Loc.GetString("cryo-wakeup-result-disabled")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
Content.Server/_NF/CryoSleep/CryoSleepSystem.Returning.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
using System.Threading; | ||
using Content.Server.Administration.Logs; | ||
using Content.Server.GameTicking; | ||
using Content.Shared.Bed.Sleep; | ||
using Content.Shared.Database; | ||
using Content.Shared.Ghost; | ||
using Content.Shared.Mind; | ||
using Content.Shared.NF14.CCVar; | ||
using Content.Shared.Players; | ||
using Robust.Shared.Configuration; | ||
using Robust.Shared.Network; | ||
|
||
namespace Content.Server.CryoSleep; | ||
|
||
public sealed partial class CryoSleepSystem | ||
{ | ||
[Dependency] private readonly IConfigurationManager _configurationManager = default!; | ||
[Dependency] private readonly IAdminLogManager _adminLogger = default!; | ||
|
||
private void InitReturning() | ||
{ | ||
SubscribeNetworkEvent<WakeupRequestMessage>(OnWakeupMessage); | ||
SubscribeNetworkEvent<GetStatusMessage>(OnGetStatusMessage); | ||
SubscribeLocalEvent<PlayerJoinedLobbyEvent>(e => ResetCryosleepState(e.PlayerSession.UserId)); | ||
SubscribeLocalEvent<PlayerBeforeSpawnEvent>(e => ResetCryosleepState(e.Player.UserId)); | ||
} | ||
|
||
private void OnWakeupMessage(WakeupRequestMessage message, EntitySessionEventArgs session) | ||
{ | ||
var entity = session.SenderSession.GetMind(); | ||
|
||
var result = entity == null || !TryComp<MindComponent>(entity, out var mind) | ||
? ReturnToBodyStatus.NotAGhost | ||
: TryReturnToBody(mind); | ||
|
||
var msg = new WakeupRequestMessage.Response(result); | ||
RaiseNetworkEvent(msg, session.SenderSession); | ||
} | ||
|
||
public void OnGetStatusMessage(GetStatusMessage message, EntitySessionEventArgs args) | ||
{ | ||
var msg = new GetStatusMessage.Response(HasCryosleepingBody(args.SenderSession.UserId)); | ||
RaiseNetworkEvent(msg, args.SenderSession); | ||
} | ||
|
||
/// <summary> | ||
/// Returns the mind to the original body, if any. The mind must be possessing a ghost, unless [force] is true. | ||
/// </summary> | ||
public ReturnToBodyStatus TryReturnToBody(MindComponent mind, bool force = false) | ||
{ | ||
if (!_configurationManager.GetCVar(NF14CVars.CryoReturnEnabled)) | ||
return ReturnToBodyStatus.Disabled; | ||
|
||
var id = mind.UserId; | ||
if (id == null || !_storedBodies.TryGetValue(id.Value, out var storedBody)) | ||
return ReturnToBodyStatus.BodyMissing; | ||
|
||
if (!force && (mind.CurrentEntity is not { Valid: true } ghost || !HasComp<GhostComponent>(ghost))) | ||
return ReturnToBodyStatus.NotAGhost; | ||
|
||
var cryopod = storedBody!.Value.Cryopod; | ||
if (!Exists(cryopod) || Deleted(cryopod) || !TryComp<CryoSleepComponent>(cryopod, out var cryoComp)) | ||
return ReturnToBodyStatus.CryopodMissing; | ||
|
||
var body = storedBody.Value.Body; | ||
if (IsOccupied(cryoComp) || !cryoComp.BodyContainer.Insert(body, EntityManager)) | ||
return ReturnToBodyStatus.Occupied; | ||
|
||
_storedBodies.Remove(id.Value); | ||
_mind.ControlMob(id.Value, body); | ||
// Force the mob to sleep | ||
var sleep = EnsureComp<SleepingComponent>(body); | ||
sleep.CoolDownEnd = TimeSpan.FromSeconds(5); | ||
|
||
_popup.PopupEntity(Loc.GetString("cryopod-wake-up", ("entity", body)), body); | ||
|
||
RaiseLocalEvent(body, new CryosleepWakeUpEvent(storedBody.Value.Cryopod, id), true); | ||
|
||
_adminLogger.Add(LogType.LateJoin, LogImpact.Medium, $"{id.Value} has returned from cryosleep!"); | ||
return ReturnToBodyStatus.Success; | ||
} | ||
|
||
/// <summary> | ||
/// Removes the body of the given user from the cryosleep dictionary, making them unable to return to it. | ||
/// Also actually deletes the body if it's still on that map. | ||
/// </summary> | ||
public void ResetCryosleepState(NetUserId id) | ||
{ | ||
var body = _storedBodies.GetValueOrDefault(id, null); | ||
|
||
if (body != null && _storedBodies.Remove(id) && Transform(body!.Value.Body).ParentUid == _storageMap) | ||
{ | ||
QueueDel(body.Value.Body); | ||
} | ||
} | ||
|
||
public bool HasCryosleepingBody(NetUserId id) | ||
{ | ||
return _storedBodies.ContainsKey(id); | ||
} | ||
} |
Oops, something went wrong.