2023-01-10 03:37:26 -06:00
using Content.Server.Administration.Logs ;
2022-02-05 13:33:24 +00:00
using Content.Server.Doors.Systems ;
2022-06-16 06:36:36 -07:00
using Content.Server.Power.EntitySystems ;
2025-01-18 23:32:33 -06:00
using Content.Shared.Access.Components ;
2023-01-10 03:37:26 -06:00
using Content.Shared.Database ;
2025-01-18 23:32:33 -06:00
using Content.Shared.Doors.Components ;
2024-02-10 02:22:19 -08:00
using Content.Shared.Examine ;
2025-01-18 23:32:33 -06:00
using Content.Shared.Interaction ;
2024-03-21 17:19:52 -07:00
using Content.Shared.Remotes.Components ;
2025-01-18 23:32:33 -06:00
using Content.Shared.Remotes.EntitySystems ;
2022-02-05 13:33:24 +00:00
2024-03-21 17:19:52 -07:00
namespace Content.Shared.Remotes
2022-02-05 13:33:24 +00:00
{
2024-03-21 17:19:52 -07:00
public sealed class DoorRemoteSystem : SharedDoorRemoteSystem
2022-02-05 13:33:24 +00:00
{
2023-01-10 03:37:26 -06:00
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2023-01-18 05:44:32 +11:00
[Dependency] private readonly AirlockSystem _airlock = default ! ;
2022-02-05 13:33:24 +00:00
[Dependency] private readonly DoorSystem _doorSystem = default ! ;
2024-03-17 08:31:09 +01:00
[Dependency] private readonly ExamineSystemShared _examine = default ! ;
2025-01-18 23:32:33 -06:00
2022-02-05 13:33:24 +00:00
public override void Initialize ( )
{
2024-03-21 17:19:52 -07:00
base . Initialize ( ) ;
2023-08-11 21:29:33 +12:00
2024-03-21 17:19:52 -07:00
SubscribeLocalEvent < DoorRemoteComponent , BeforeRangedInteractEvent > ( OnBeforeInteract ) ;
2022-02-05 13:33:24 +00:00
}
2024-03-21 17:19:52 -07:00
private void OnBeforeInteract ( Entity < DoorRemoteComponent > entity , ref BeforeRangedInteractEvent args )
2022-02-05 13:33:24 +00:00
{
2023-08-11 21:29:33 +12:00
bool isAirlock = TryComp < AirlockComponent > ( args . Target , out var airlockComp ) ;
2022-06-16 06:36:36 -07:00
if ( args . Handled
2022-02-05 13:33:24 +00:00
| | args . Target = = null
2022-06-16 06:36:36 -07:00
| | ! TryComp < DoorComponent > ( args . Target , out var doorComp ) // If it isn't a door we don't use it
2025-01-18 23:32:33 -06:00
// Only able to control doors if they are within your vision and within your max range.
// Not affected by mobs or machines anymore.
| | ! _examine . InRangeUnOccluded ( args . User ,
args . Target . Value ,
SharedInteractionSystem . MaxRaycastRange ,
null ) )
2024-03-21 17:19:52 -07:00
2023-08-11 21:29:33 +12:00
{
2022-02-05 13:33:24 +00:00
return ;
2023-08-11 21:29:33 +12:00
}
2022-02-05 13:33:24 +00:00
args . Handled = true ;
2022-05-27 10:36:12 +10:00
2022-06-16 06:36:36 -07:00
if ( ! this . IsPowered ( args . Target . Value , EntityManager ) )
2022-02-05 13:33:24 +00:00
{
2024-03-21 17:19:52 -07:00
Popup . PopupEntity ( Loc . GetString ( "door-remote-no-power" ) , args . User , args . User ) ;
2022-06-16 06:36:36 -07:00
return ;
2022-02-05 13:33:24 +00:00
}
2025-06-29 18:21:14 +02:00
var accessTarget = args . Used ;
// This covers the accesses the REMOTE has, and is not effected by the user's ID card.
if ( entity . Comp . IncludeUserAccess ) // Allows some door remotes to inherit the user's access.
{
accessTarget = args . User ;
// This covers the accesses the USER has, which always includes the remote's access since holding a remote acts like holding an ID card.
}
2023-08-11 21:29:33 +12:00
if ( TryComp < AccessReaderComponent > ( args . Target , out var accessComponent )
2025-06-29 18:21:14 +02:00
& & ! _doorSystem . HasAccess ( args . Target . Value , accessTarget , doorComp , accessComponent ) )
2022-02-05 13:33:24 +00:00
{
2025-01-18 23:32:33 -06:00
if ( isAirlock )
2025-06-29 18:21:14 +02:00
_doorSystem . Deny ( args . Target . Value , doorComp , accessTarget ) ;
2024-03-21 17:19:52 -07:00
Popup . PopupEntity ( Loc . GetString ( "door-remote-denied" ) , args . User , args . User ) ;
2022-06-16 06:36:36 -07:00
return ;
2022-02-05 13:33:24 +00:00
}
2022-02-09 03:13:35 +00:00
2024-03-21 17:19:52 -07:00
switch ( entity . Comp . Mode )
2022-02-09 03:13:35 +00:00
{
2022-06-16 06:36:36 -07:00
case OperatingMode . OpenClose :
2025-06-29 18:21:14 +02:00
if ( _doorSystem . TryToggleDoor ( args . Target . Value , doorComp , accessTarget ) )
2025-01-18 23:32:33 -06:00
_adminLogger . Add ( LogType . Action ,
LogImpact . Medium ,
$"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)}: {doorComp.State}" ) ;
2022-06-16 06:36:36 -07:00
break ;
case OperatingMode . ToggleBolts :
2023-06-01 02:23:35 +12:00
if ( TryComp < DoorBoltComponent > ( args . Target , out var boltsComp ) )
2023-01-10 03:37:26 -06:00
{
2023-06-01 02:23:35 +12:00
if ( ! boltsComp . BoltWireCut )
{
2025-06-29 18:21:14 +02:00
_doorSystem . SetBoltsDown ( ( args . Target . Value , boltsComp ) , ! boltsComp . BoltsDown , accessTarget ) ;
2025-01-18 23:32:33 -06:00
_adminLogger . Add ( LogType . Action ,
LogImpact . Medium ,
$"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to {(boltsComp.BoltsDown ? "" : " un ")}bolt it" ) ;
2023-06-01 02:23:35 +12:00
}
2023-01-10 03:37:26 -06:00
}
2025-01-18 23:32:33 -06:00
2022-06-16 06:36:36 -07:00
break ;
case OperatingMode . ToggleEmergencyAccess :
2023-08-11 21:29:33 +12:00
if ( airlockComp ! = null )
{
2024-09-27 10:22:17 +03:00
_airlock . SetEmergencyAccess ( ( args . Target . Value , airlockComp ) , ! airlockComp . EmergencyAccess ) ;
2025-01-18 23:32:33 -06:00
_adminLogger . Add ( LogType . Action ,
LogImpact . Medium ,
2023-08-11 21:29:33 +12:00
$"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to set emergency access {(airlockComp.EmergencyAccess ? " on " : " off ")}" ) ;
}
2025-01-18 23:32:33 -06:00
2022-06-16 06:36:36 -07:00
break ;
default :
throw new InvalidOperationException (
2024-03-21 17:19:52 -07:00
$"{nameof(DoorRemoteComponent)} had invalid mode {entity.Comp.Mode}" ) ;
2022-02-09 03:13:35 +00:00
}
2022-02-05 13:33:24 +00:00
}
}
}