2023-02-24 19:01:25 -05:00
using Content.Server.Medical.Components ;
2023-05-28 03:59:27 -05:00
using Content.Shared.Administration.Logs ;
2023-02-14 00:29:34 +11:00
using Content.Shared.Body.Components ;
2023-05-28 03:59:27 -05:00
using Content.Shared.Database ;
2023-04-09 15:28:19 -07:00
using Content.Shared.DoAfter ;
2023-02-14 00:29:34 +11:00
using Content.Shared.DragDrop ;
2022-12-25 12:35:51 +01:00
using Content.Shared.Emag.Systems ;
2023-01-13 16:57:10 -08:00
using Content.Shared.Mobs.Components ;
using Content.Shared.Mobs.Systems ;
2022-12-25 12:35:51 +01:00
using Content.Shared.Popups ;
using Content.Shared.Standing ;
using Content.Shared.Stunnable ;
using Content.Shared.Verbs ;
using Robust.Shared.Containers ;
2023-04-03 13:13:48 +12:00
using Robust.Shared.Serialization ;
2022-12-25 12:35:51 +01:00
namespace Content.Shared.Medical.Cryogenics ;
public abstract partial class SharedCryoPodSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default ! ;
[Dependency] private readonly StandingStateSystem _standingStateSystem = default ! ;
2023-01-13 16:57:10 -08:00
[Dependency] private readonly MobStateSystem _mobStateSystem = default ! ;
2022-12-25 12:35:51 +01:00
[Dependency] private readonly SharedPopupSystem _popupSystem = default ! ;
[Dependency] private readonly SharedContainerSystem _containerSystem = default ! ;
2023-09-11 19:18:06 +10:00
[Dependency] private readonly SharedPointLightSystem _light = default ! ;
2023-05-28 03:59:27 -05:00
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
2022-12-25 12:35:51 +01:00
public override void Initialize ( )
{
base . Initialize ( ) ;
2023-04-09 15:28:19 -07:00
SubscribeLocalEvent < CryoPodComponent , CanDropTargetEvent > ( OnCryoPodCanDropOn ) ;
2022-12-25 12:35:51 +01:00
InitializeInsideCryoPod ( ) ;
}
2023-04-09 15:28:19 -07:00
private void OnCryoPodCanDropOn ( EntityUid uid , CryoPodComponent component , ref CanDropTargetEvent args )
2023-02-14 00:29:34 +11:00
{
2023-04-03 08:30:03 +12:00
if ( args . Handled )
return ;
args . CanDrop = HasComp < BodyComponent > ( args . Dragged ) ;
2023-02-14 00:29:34 +11:00
args . Handled = true ;
}
2023-04-09 15:28:19 -07:00
protected void OnComponentInit ( EntityUid uid , CryoPodComponent cryoPodComponent , ComponentInit args )
2022-12-25 12:35:51 +01:00
{
cryoPodComponent . BodyContainer = _containerSystem . EnsureContainer < ContainerSlot > ( uid , "scanner-body" ) ;
}
2023-04-09 15:28:19 -07:00
protected void UpdateAppearance ( EntityUid uid , CryoPodComponent ? cryoPod = null , AppearanceComponent ? appearance = null )
2022-12-25 12:35:51 +01:00
{
if ( ! Resolve ( uid , ref cryoPod ) )
return ;
2023-09-11 19:18:06 +10:00
2022-12-25 12:35:51 +01:00
var cryoPodEnabled = HasComp < ActiveCryoPodComponent > ( uid ) ;
2023-09-11 19:18:06 +10:00
if ( _light . TryGetLight ( uid , out var light ) )
2022-12-25 12:35:51 +01:00
{
2023-09-11 19:18:06 +10:00
_light . SetEnabled ( uid , cryoPodEnabled & & cryoPod . BodyContainer . ContainedEntity ! = null , light ) ;
2022-12-25 12:35:51 +01:00
}
if ( ! Resolve ( uid , ref appearance ) )
return ;
2023-09-11 19:18:06 +10:00
2023-04-09 15:28:19 -07:00
_appearanceSystem . SetData ( uid , CryoPodComponent . CryoPodVisuals . ContainsEntity , cryoPod . BodyContainer . ContainedEntity = = null , appearance ) ;
_appearanceSystem . SetData ( uid , CryoPodComponent . CryoPodVisuals . IsOn , cryoPodEnabled , appearance ) ;
2022-12-25 12:35:51 +01:00
}
2023-05-28 03:59:27 -05:00
public bool InsertBody ( EntityUid uid , EntityUid target , CryoPodComponent cryoPodComponent )
2022-12-25 12:35:51 +01:00
{
if ( cryoPodComponent . BodyContainer . ContainedEntity ! = null )
2023-05-28 03:59:27 -05:00
return false ;
2022-12-25 12:35:51 +01:00
if ( ! HasComp < MobStateComponent > ( target ) )
2023-05-28 03:59:27 -05:00
return false ;
2022-12-25 12:35:51 +01:00
var xform = Transform ( target ) ;
2023-12-27 21:30:03 -08:00
_containerSystem . Insert ( ( target , xform ) , cryoPodComponent . BodyContainer ) ;
2022-12-25 12:35:51 +01:00
EnsureComp < InsideCryoPodComponent > ( target ) ;
_standingStateSystem . Stand ( target , force : true ) ; // Force-stand the mob so that the cryo pod sprite overlays it fully
UpdateAppearance ( uid , cryoPodComponent ) ;
2023-05-28 03:59:27 -05:00
return true ;
2022-12-25 12:35:51 +01:00
}
2023-04-09 15:28:19 -07:00
public void TryEjectBody ( EntityUid uid , EntityUid userId , CryoPodComponent ? cryoPodComponent )
2022-12-25 12:35:51 +01:00
{
if ( ! Resolve ( uid , ref cryoPodComponent ) )
{
return ;
}
if ( cryoPodComponent . Locked )
{
_popupSystem . PopupEntity ( Loc . GetString ( "cryo-pod-locked" ) , uid , userId ) ;
return ;
}
2023-05-28 03:59:27 -05:00
var ejected = EjectBody ( uid , cryoPodComponent ) ;
if ( ejected ! = null )
_adminLogger . Add ( LogType . Action , LogImpact . Medium , $"{ToPrettyString(ejected.Value)} ejected from {ToPrettyString(uid)} by {ToPrettyString(userId)}" ) ;
2022-12-25 12:35:51 +01:00
}
2023-05-28 03:59:27 -05:00
/// <summary>
/// Ejects the contained body
/// </summary>
/// <param name="uid">The cryopod entity</param>
/// <param name="cryoPodComponent">Cryopod component of <see cref="uid"/></param>
/// <returns>Ejected entity</returns>
public virtual EntityUid ? EjectBody ( EntityUid uid , CryoPodComponent ? cryoPodComponent )
2022-12-25 12:35:51 +01:00
{
if ( ! Resolve ( uid , ref cryoPodComponent ) )
2023-05-28 03:59:27 -05:00
return null ;
2022-12-25 12:35:51 +01:00
if ( cryoPodComponent . BodyContainer . ContainedEntity is not { Valid : true } contained )
2023-05-28 03:59:27 -05:00
return null ;
2022-12-25 12:35:51 +01:00
2023-12-27 21:30:03 -08:00
_containerSystem . Remove ( contained , cryoPodComponent . BodyContainer ) ;
2022-12-25 12:35:51 +01:00
// InsideCryoPodComponent is removed automatically in its EntGotRemovedFromContainerMessage listener
// RemComp<InsideCryoPodComponent>(contained);
// Restore the correct position of the patient. Checking the components manually feels hacky, but I did not find a better way for now.
if ( HasComp < KnockedDownComponent > ( contained ) | | _mobStateSystem . IsIncapacitated ( contained ) )
{
_standingStateSystem . Down ( contained ) ;
}
else
{
_standingStateSystem . Stand ( contained ) ;
}
UpdateAppearance ( uid , cryoPodComponent ) ;
2023-05-28 03:59:27 -05:00
return contained ;
2022-12-25 12:35:51 +01:00
}
2023-04-09 15:28:19 -07:00
protected void AddAlternativeVerbs ( EntityUid uid , CryoPodComponent cryoPodComponent , GetVerbsEvent < AlternativeVerb > args )
2022-12-25 12:35:51 +01:00
{
if ( ! args . CanAccess | | ! args . CanInteract )
return ;
// Eject verb
if ( cryoPodComponent . BodyContainer . ContainedEntity ! = null )
{
args . Verbs . Add ( new AlternativeVerb
{
Text = Loc . GetString ( "cryo-pod-verb-noun-occupant" ) ,
Category = VerbCategory . Eject ,
Priority = 1 , // Promote to top to make ejecting the ALT-click action
Act = ( ) = > TryEjectBody ( uid , args . User , cryoPodComponent )
} ) ;
}
}
2023-04-09 15:28:19 -07:00
protected void OnEmagged ( EntityUid uid , CryoPodComponent ? cryoPodComponent , ref GotEmaggedEvent args )
2022-12-25 12:35:51 +01:00
{
if ( ! Resolve ( uid , ref cryoPodComponent ) )
{
return ;
}
cryoPodComponent . PermaLocked = true ;
cryoPodComponent . Locked = true ;
args . Handled = true ;
}
2023-04-09 15:28:19 -07:00
protected void OnCryoPodPryFinished ( EntityUid uid , CryoPodComponent cryoPodComponent , CryoPodPryFinished args )
2022-12-25 12:35:51 +01:00
{
2023-04-03 13:13:48 +12:00
if ( args . Cancelled )
return ;
2023-05-28 03:59:27 -05:00
var ejected = EjectBody ( uid , cryoPodComponent ) ;
if ( ejected ! = null )
_adminLogger . Add ( LogType . Action , LogImpact . Medium , $"{ToPrettyString(ejected.Value)} pried out of {ToPrettyString(uid)} by {ToPrettyString(args.User)}" ) ;
2022-12-25 12:35:51 +01:00
}
2023-04-03 13:13:48 +12:00
[Serializable, NetSerializable]
2023-08-22 18:14:33 -07:00
public sealed partial class CryoPodPryFinished : SimpleDoAfterEvent
2022-12-25 12:35:51 +01:00
{
}
2023-04-03 13:13:48 +12:00
[Serializable, NetSerializable]
2023-08-22 18:14:33 -07:00
public sealed partial class CryoPodDragFinished : SimpleDoAfterEvent
2023-04-03 13:13:48 +12:00
{
}
2022-12-25 12:35:51 +01:00
}