diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 4bd03bc2f0..defc8e2649 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -301,7 +301,8 @@ namespace Content.Client.Entry "ArtifactInteractionTrigger", "Artifact", "RandomArtifactSprite", - "EnergySword" + "EnergySword", + "DoorRemote", }; } } diff --git a/Content.Server/Remotes/DoorRemoteComponent.cs b/Content.Server/Remotes/DoorRemoteComponent.cs new file mode 100644 index 0000000000..e4a78ce176 --- /dev/null +++ b/Content.Server/Remotes/DoorRemoteComponent.cs @@ -0,0 +1,21 @@ +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; + +namespace Content.Server.Remotes +{ + [RegisterComponent] + [Friend(typeof(DoorRemoteSystem))] + public class DoorRemoteComponent : Component + { + public override string Name => "DoorRemote"; + + public OperatingMode Mode = OperatingMode.OpenClose; + + public enum OperatingMode : byte + { + OpenClose, + ToggleBolts + // ToggleEmergencyAccess + } + } +} diff --git a/Content.Server/Remotes/DoorRemoteSystem.cs b/Content.Server/Remotes/DoorRemoteSystem.cs new file mode 100644 index 0000000000..f2c2b23b4f --- /dev/null +++ b/Content.Server/Remotes/DoorRemoteSystem.cs @@ -0,0 +1,93 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Localization; +using Robust.Shared.Player; +using Robust.Shared.IoC; +using Robust.Shared.Audio; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Doors.Components; +using Content.Shared.Doors.Systems; +using Content.Shared.Physics; +using Content.Shared.Access.Components; +using Content.Server.Doors.Systems; +using Content.Server.Doors.Components; + +namespace Content.Server.Remotes +{ + public sealed class DoorRemoteSystem : EntitySystem + { + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly SharedDoorSystem _sharedDoorSystem = default!; + [Dependency] private readonly DoorSystem _doorSystem = default!; + [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInHandActivation); + SubscribeLocalEvent(OnAfterInteract); + } + + public void OnInHandActivation(EntityUid user, DoorRemoteComponent component, UseInHandEvent args) + { + switch (component.Mode) + { + case DoorRemoteComponent.OperatingMode.OpenClose: + component.Mode = DoorRemoteComponent.OperatingMode.ToggleBolts; + _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-toggle-bolts"), args.User, Filter.Entities(args.User)); + break; + case DoorRemoteComponent.OperatingMode.ToggleBolts: + component.Mode = DoorRemoteComponent.OperatingMode.OpenClose; // TODO: Swítch to ToggleEmergencyAcces when EA is implemented + _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-open-close"), args.User, Filter.Entities(args.User)); // TODO: See the above comment + break; + /* + case DoorRemoteComponent.OperatingMode.ToggleEmergencyAccess: + component.Mode = DoorRemoteComponent.OperatingMode.OpenClose; + _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-open-close"), args.User, Filter.Entities(args.User)); + break; + */ + } + } + + private void OnAfterInteract(EntityUid uid, DoorRemoteComponent component, AfterInteractEvent args) + { + if (args.Handled + || args.Target == null + || !TryComp(args.Target, out var doorComponent) // If it isn't a door we don't use it + || !HasComp(args.Target) // Remotes do not work on doors without access requirements + || !TryComp(args.Target, out var airlockComponent) // Remotes only work on airlocks + || !_interactionSystem.InRangeUnobstructed(args.User, doorComponent.Owner, -1f, CollisionGroup.Opaque)) + { + return; + } + + args.Handled = true; + + if (component.Mode == DoorRemoteComponent.OperatingMode.OpenClose) + { + _sharedDoorSystem.TryToggleDoor(doorComponent.Owner, user: args.Used); + } + + if (component.Mode == DoorRemoteComponent.OperatingMode.ToggleBolts + && airlockComponent.IsPowered()) + { + if (_doorSystem.HasAccess(doorComponent.Owner, args.Used)) + { + airlockComponent.SetBoltsWithAudio(!airlockComponent.IsBolted()); + } + else + { + if (doorComponent.State != DoorState.Open) + { + _sharedDoorSystem.Deny(airlockComponent.Owner, user: args.User); + } + else if (doorComponent.DenySound != null) + { + SoundSystem.Play(Filter.Pvs(args.Target.Value), doorComponent.DenySound.GetSound(), args.Target.Value); + } + } + } + } + } +} diff --git a/Resources/Locale/en-US/door-remote/door-remote.ftl b/Resources/Locale/en-US/door-remote/door-remote.ftl new file mode 100644 index 0000000000..fa35d4d659 --- /dev/null +++ b/Resources/Locale/en-US/door-remote/door-remote.ftl @@ -0,0 +1,3 @@ +door-remote-switch-state-open-close = You switch the remote to open and close doors +door-remote-switch-state-toggle-bolts = You switch the remote to toggle bolts +door-remote-switch-state-toggle-emergency-access = You switch the remote to toggle emergency access diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index 320724e9e5..e7d2aed8f3 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -25,6 +25,7 @@ prob: 1 - id: CigPackGreen prob: 0.50 + - id: DoorRemoteCargo - type: entity id: LockerCaptainFilled @@ -63,6 +64,7 @@ - id: CigarGoldCase prob: 0.25 - id: ClothingBeltSheathFilled + - id: DoorRemoteCommand - type: entity id: LockerHeadOfPersonnelFilled @@ -94,6 +96,7 @@ - id: CigarGoldCase prob: 0.10 # Fuck the HoP they don't deserve fucking cigars. + - id: DoorRemoteService - type: entity id: LockerChiefEngineerFilled @@ -114,6 +117,7 @@ - id: ClothingHandsGlovesColorYellow - id: CigarCase prob: 0.15 + - id: DoorRemoteEngineering - type: entity id: LockerChiefMedicalOfficerFilled @@ -135,6 +139,7 @@ - id: ClothingOuterHardsuitMedical - id: Hypospray - id: HandheldCrewMonitor + - id: DoorRemoteMedical - type: entity id: LockerResearchDirectorFilled @@ -157,6 +162,7 @@ prob: 1 - id: PlushieSlime prob: 0.1 + - id: DoorRemoteResearch - type: entity id: LockerHeadOfSecurityFilled @@ -205,3 +211,4 @@ prob: 1 - id: CigarGoldCase prob: 0.50 + - id: DoorRemoteSecurity diff --git a/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml b/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml new file mode 100644 index 0000000000..1be90036ac --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/door_remote.yml @@ -0,0 +1,137 @@ +- type: entity + parent: BaseItem + id: DoorRemoteDefault + name: door remote + description: A gadget which can open and bolt doors remotely + abstract: true + components: + - type: Sprite + sprite: Objects/Devices/door_remote.rsi + netsync: false + - type: Access + - type: DoorRemote + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteCommand + name: command door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#e6e600" + - state: door_remotescreencolour + color: "#9f9f00" + - type: Access + tags: + - Captain + - HeadOfPersonnel + - Command + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteSecurity + name: security door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#cb0000" + - state: door_remotescreencolour + color: "#830000" + - type: Access + tags: + - HeadOfSecurity + - Security + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteService + name: service door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#58c800" + - state: door_remotescreencolour + color: "#3a7231" + - type: Access + tags: + - HeadOfPersonnel + - Service + - Bar + - Janitor + - Theatre + - Kitchen + - Hydroponics + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteResearch + name: research door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#a53aaa" + - state: door_remotescreencolour + color: "#652368" + - type: Access + tags: + - ResearchDirector + - Research + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteCargo + name: cargo door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#b18644" + - state: door_remotescreencolour + color: "#5b4523" + - type: Access + tags: + - Cargo + - Quartermaster + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteMedical + name: medical door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#68aed6" + - state: door_remotescreencolour + color: "#325f7a" + - type: Access + tags: + - Medical + - ChiefMedicalOfficer + +- type: entity + parent: DoorRemoteDefault + id: DoorRemoteEngineering + name: engineering door remote + components: + - type: Sprite + layers: + - state: door_remotebase + - state: door_remotelightscolour + color: "#ffa62b" + - state: door_remotescreencolour + color: "#bc5b00" + - type: Access + tags: + - ChiefEngineer + - Engineering diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase.png b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase.png new file mode 100644 index 0000000000..d9aee6992a Binary files /dev/null and b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotebase.png differ diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotelightscolour.png b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotelightscolour.png new file mode 100644 index 0000000000..15a8bcd7c6 Binary files /dev/null and b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotelightscolour.png differ diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotescreencolour.png b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotescreencolour.png new file mode 100644 index 0000000000..458b47935b Binary files /dev/null and b/Resources/Textures/Objects/Devices/door_remote.rsi/door_remotescreencolour.png differ diff --git a/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json b/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json new file mode 100644 index 0000000000..ffb1be00d3 --- /dev/null +++ b/Resources/Textures/Objects/Devices/door_remote.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Command remote copied from tgstation, rest are recolors", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "door_remotebase" + }, + { + "name": "door_remotelightscolour" + }, + { + "name": "door_remotescreencolour" + } + ] +}