]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Xenoborg door control module (#41546)
authorSamuka <47865393+Samuka-C@users.noreply.github.com>
Tue, 16 Dec 2025 01:24:54 +0000 (22:24 -0300)
committerGitHub <noreply@github.com>
Tue, 16 Dec 2025 01:24:54 +0000 (01:24 +0000)
* add door control module

* some commentary

* can't eject stuff anymore

* make xenoborg door remote eletrify doors

* clean yml

* anchors and aliases

* not show stuff about id in xenoborg access config

* engi xenoborg can see eletrified doors

19 files changed:
Content.Client/Access/UI/AccessOverriderWindow.xaml
Content.Client/Access/UI/AccessOverriderWindow.xaml.cs
Content.Client/Remotes/UI/DoorRemoteStatusControl.cs
Content.Server/Access/Systems/AccessOverriderSystem.cs
Content.Shared/Access/Components/AccessOverriderComponent.cs
Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs
Content.Shared/Remotes/Components/DoorRemoteComponent.cs
Content.Shared/Remotes/EntitySystems/SharedDoorRemoteSystem.cs
Resources/Locale/en-US/access/systems/access-overrider-system.ftl
Resources/Locale/en-US/door-remote/door-remote.ftl
Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml
Resources/Prototypes/Entities/Objects/Devices/door_remote.yml
Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml
Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml
Resources/Prototypes/Recipes/Lathes/Packs/xenoborgs.yml
Resources/Prototypes/Recipes/Lathes/xenoborgs.yml
Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json
Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-door-remote-module.png [new file with mode: 0644]

index ae482140bc00a480994a615b83fc5b68bb5e3b9a..545ebec49414f9e306ccc673ecf2d08d2d53fa2f 100644 (file)
@@ -2,7 +2,7 @@
             MinSize="650 290">
     <BoxContainer Orientation="Vertical">
         <GridContainer Columns="2">
-            <GridContainer Columns="3" HorizontalExpand="True">
+            <GridContainer Name="PrivilegedIdGrid" Columns="3" HorizontalExpand="True">
                 <Label Text="{Loc 'access-overrider-window-privileged-id'}" />
                 <Button Name="PrivilegedIdButton" Access="Public"/>
                 <Label Name="PrivilegedIdLabel" />
index a783dd368fe1cc2e5b9e8055e4438bf02dd2b2e7..d0d15d2bd53b830c63530679e63ffe4cf59eadf7 100644 (file)
@@ -53,6 +53,8 @@ namespace Content.Client.Access.UI
 
         public void UpdateState(IPrototypeManager protoManager, AccessOverriderBoundUserInterfaceState state)
         {
+            PrivilegedIdGrid.Visible = state.ShowPrivilegedIdGrid;
+
             PrivilegedIdLabel.Text = state.PrivilegedIdName;
             PrivilegedIdButton.Text = state.IsPrivilegedIdPresent
                 ? Loc.GetString("access-overrider-window-eject-button")
@@ -77,7 +79,9 @@ namespace Content.Client.Access.UI
                     missingPrivileges.Add(privilege);
                 }
 
-                MissingPrivilegesLabel.Text = Loc.GetString("access-overrider-window-missing-privileges");
+                MissingPrivilegesLabel.Text = state.ShowPrivilegedIdGrid ?
+                    Loc.GetString("access-overrider-window-missing-privileges") :
+                    Loc.GetString("access-overrider-window-missing-privileges-no-id");
                 MissingPrivilegesText.Text = string.Join(", ", missingPrivileges);
             }
 
index e96cce5b2519bc2c51d77430a3086ab18a898b07..9db604ff807e33c9d2e8fa1c5e2086aa5b279cb9 100644 (file)
@@ -35,6 +35,7 @@ public sealed class DoorRemoteStatusControl(Entity<DoorRemoteComponent> ent) : C
             OperatingMode.OpenClose => "door-remote-open-close-text",
             OperatingMode.ToggleBolts => "door-remote-toggle-bolt-text",
             OperatingMode.ToggleEmergencyAccess => "door-remote-emergency-access-text",
+            OperatingMode.ToggleOvercharge => "door-remote-toggle-eletrify-text",
             _ => "door-remote-invalid-text"
         });
 
index 4eaf3c0419956289f91c2504f5e1465d50001023..aa34dc2729b29fd1ccc9fb4d9560ba8c8d0343f4 100644 (file)
@@ -148,7 +148,8 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
             missingAccess,
             privilegedIdName,
             targetLabel,
-            targetLabelColor);
+            targetLabelColor,
+            component.ShowPrivilegedId);
 
         _userInterface.SetUiState(uid, AccessOverriderUiKey.Key, newState);
     }
index 6a1bf2c831a42fbc5611f96a7f9dada3a3767a0d..27a6f7d5997d764c1531524551b5163266abc757 100644 (file)
@@ -13,6 +13,12 @@ public sealed partial class AccessOverriderComponent : Component
 {
     public static string PrivilegedIdCardSlotId = "AccessOverrider-privilegedId";
 
+    /// <summary>
+    /// If the Access Overrider UI will show info about the privileged ID
+    /// </summary>
+    [DataField]
+    public bool ShowPrivilegedId = true;
+
     [DataField]
     public ItemSlot PrivilegedIdSlot = new();
 
@@ -48,6 +54,7 @@ public sealed partial class AccessOverriderComponent : Component
         public readonly string PrivilegedIdName;
         public readonly bool IsPrivilegedIdPresent;
         public readonly bool IsPrivilegedIdAuthorized;
+        public readonly bool ShowPrivilegedIdGrid;
         public readonly ProtoId<AccessLevelPrototype>[]? TargetAccessReaderIdAccessList;
         public readonly ProtoId<AccessLevelPrototype>[]? AllowedModifyAccessList;
         public readonly ProtoId<AccessLevelPrototype>[]? MissingPrivilegesList;
@@ -59,7 +66,8 @@ public sealed partial class AccessOverriderComponent : Component
             ProtoId<AccessLevelPrototype>[]? missingPrivilegesList,
             string privilegedIdName,
             string targetLabel,
-            Color targetLabelColor)
+            Color targetLabelColor,
+            bool showPrivilegedIdGrid)
         {
             IsPrivilegedIdPresent = isPrivilegedIdPresent;
             IsPrivilegedIdAuthorized = isPrivilegedIdAuthorized;
@@ -69,6 +77,7 @@ public sealed partial class AccessOverriderComponent : Component
             PrivilegedIdName = privilegedIdName;
             TargetLabel = targetLabel;
             TargetLabelColor = targetLabelColor;
+            ShowPrivilegedIdGrid = showPrivilegedIdGrid;
         }
     }
 
index 73caec52e88d9c15d0781f51e4a7ef9c539bd4ab..5237a9e80844d1f9fe1c8cb45e248f269cc3f104 100644 (file)
@@ -813,7 +813,7 @@ namespace Content.Shared.Containers.ItemSlots
             if (!component.Slots.TryGetValue(args.SlotId, out var slot))
                 return;
 
-            if (args.TryEject && slot.HasItem)
+            if (args.TryEject && slot.HasItem && !slot.DisableEject)
                 TryEjectToHands(uid, slot, args.Actor, true);
             else if (args.TryInsert && !slot.HasItem)
                 TryInsertFromHand(uid, slot, args.Actor);
index 7bce64262d1c77935b04dc22329843247aa405c3..ed6cd71051db7269932b2ed271bcd6ba615f698e 100644 (file)
@@ -70,5 +70,6 @@ public enum OperatingMode : byte
 {
     OpenClose,
     ToggleBolts,
-    ToggleEmergencyAccess
+    ToggleEmergencyAccess,
+    ToggleOvercharge
 }
index 67c2214ca2f1dec4c155637d702fb77b9c59fe9e..7af311cc1e4431c0a15bff77848853ed8f625c5a 100644 (file)
@@ -3,11 +3,13 @@ using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
 using Content.Shared.Doors.Components;
 using Content.Shared.Doors.Systems;
+using Content.Shared.Electrocution;
 using Content.Shared.Examine;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
 using Content.Shared.Power.EntitySystems;
 using Content.Shared.Remotes.Components;
+using Robust.Shared.Audio.Systems;
 using Robust.Shared.Serialization;
 using Robust.Shared.Timing;
 
@@ -16,7 +18,9 @@ namespace Content.Shared.Remotes.EntitySystems;
 public abstract class SharedDoorRemoteSystem : EntitySystem
 {
     [Dependency] private readonly SharedAirlockSystem _airlock = default!;
+    [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedDoorSystem _doorSystem = default!;
+    [Dependency] private readonly SharedElectrocutionSystem _electrify = default!;
     [Dependency] private readonly ExamineSystemShared _examine = default!;
     [Dependency] private readonly SharedPowerReceiverSystem _powerReceiver = default!;
     [Dependency] private readonly SharedPopupSystem _popup = default!;
@@ -113,6 +117,20 @@ public abstract class SharedDoorRemoteSystem : EntitySystem
                         $"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to set emergency access {(airlockComp.EmergencyAccess ? "on" : "off")}");
                 }
 
+                break;
+            case OperatingMode.ToggleOvercharge:
+                if (TryComp<ElectrifiedComponent>(args.Target, out var eletrifiedComp))
+                {
+                    _electrify.SetElectrified((args.Target.Value, eletrifiedComp), !eletrifiedComp.Enabled);
+                    var soundToPlay = eletrifiedComp.Enabled
+                        ? eletrifiedComp.AirlockElectrifyDisabled
+                        : eletrifiedComp.AirlockElectrifyEnabled;
+                    _audio.PlayLocal(soundToPlay, args.Target.Value, args.User);
+                    _adminLogger.Add(LogType.Action,
+                        LogImpact.Medium,
+                        $"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to {(eletrifiedComp.Enabled ? "" : "un")}electrify it");
+                }
+
                 break;
             default:
                 throw new InvalidOperationException(
index 6901d41246ef4ec8806c3bd0c5b91d39da989e57..932a3a49cfeedd4177bf781057bf8b93dfd4cf25 100644 (file)
@@ -4,6 +4,7 @@ access-overrider-window-insert-button = Insert
 access-overrider-window-target-label = Connected device:
 access-overrider-window-no-target = No connected device
 access-overrider-window-missing-privileges = Access to this device cannot be modified. The inserted ID is missing the following privileges:
+access-overrider-window-missing-privileges-no-id = Access to this device cannot be modified. Missing the following privileges:
 access-overrider-cannot-modify-access = You do not have sufficient privileges to modify this device!
 access-overrider-out-of-range = The connected device is too far away
 
index 2c4ccd08052d511bc2dd3196e58d7bdd46c24962..5ff83732eee452de091cb30d2c86cf96d00c7c3f 100644 (file)
@@ -1,4 +1,5 @@
 ## UI
+door-remote-toggle-eletrify-text = Toggle overcharge
 door-remote-open-close-text = Opens and Closes Doors
 door-remote-toggle-bolt-text = Toggles Bolts
 door-remote-emergency-access-text = Toggles Emergency Access
index 991a03be962c04c36d705d6a1decdc3928f16bfe..ae07eab6c9925bbefbcc47819e3095ddb84b228c 100644 (file)
@@ -43,6 +43,7 @@
       - BorgModuleCable
       - XenoborgModuleAccessBreaker
       - XenoborgModuleFireExtinguisher
+  - type: ShowElectrocutionHUD
   - type: ShowHealthBars
     damageContainers:
     - Inorganic
index 963c7e68a06675baa5a57d0fe509c0fb12f257a7..c5d28134b66fa5798ff75b113ad2355fd1669609 100644 (file)
   - type: DoorRemote
     options:
     - mode: OpenClose
-      tooltip: door-remote-open-close-text
-      icon:
+      tooltip: &TextOpenClose door-remote-open-close-text
+      icon: &IconOpenClose
         sprite: /Textures/Structures/Doors/Airlocks/Standard/basic.rsi
         state: assembly
     - mode: ToggleBolts
-      tooltip: door-remote-toggle-bolt-text
-      icon:
+      tooltip: &TextToggleBolt door-remote-toggle-bolt-text
+      icon: &IconToggleBolt
         sprite: /Textures/Interface/Actions/actions_ai.rsi
         state: bolt_door
     - mode: ToggleEmergencyAccess
-      tooltip: door-remote-emergency-access-text
-      icon:
+      tooltip: &TextEmergencyAccess door-remote-emergency-access-text
+      icon: &IconEmergencyAccess
         sprite: /Textures/Interface/Actions/actions_ai.rsi
         state: emergency_on
   - type: StealTarget
       enum.DoorRemoteUiKey.Key:
         type: DoorRemoteBoundUserInterface
 
+- type: entity
+  parent: DoorRemoteDefault
+  id: DoorRemoteCanEletrifyDoors
+  abstract: true
+  components:
+  - type: DoorRemote
+    options:
+    - mode: ToggleOvercharge
+      tooltip: door-remote-toggle-eletrify-text
+      icon:
+        sprite: /Textures/Interface/Actions/actions_ai.rsi
+        state: door_overcharge_on
+    - mode: OpenClose
+      tooltip: *TextOpenClose
+      icon: *IconOpenClose
+    - mode: ToggleBolts
+      tooltip: *TextToggleBolt
+      icon: *IconToggleBolt
+    - mode: ToggleEmergencyAccess
+      tooltip: *TextEmergencyAccess
+      icon: *IconEmergencyAccess
+
 - type: entity
   parent: [DoorRemoteDefault, BaseCommandContraband]
   id: DoorRemoteCommand
     - Xenoborg
 
 - type: entity
-  parent: [ DoorRemoteDefault, BaseXenoborgContraband ]
+  parent: [ DoorRemoteCanEletrifyDoors, BaseXenoborgContraband ]
   id: DoorRemoteXenoborg
   name: xenoborg door remote
   components:
index 29edda603f240705df0c5b00ad36e53564de5be9..e175b6a77fbd5048ab8bc83a73e590a3fe491ed0 100644 (file)
     - NuclearOperative
     - SyndicateAgent
 
+- type: entity
+  parent: IDCardStandard
+  id: XenoborgIDCard
+  name: xenoborg ID card
+  components:
+  - type: Sprite
+    layers:
+    - state: default
+  - type: Access
+    tags:
+    - Xenoborg
+
 - type: entity
   parent: IDCardStandard
   id: WizardIDCard
index 56294a6dbb882ff94d56b1c80284509e1d95e50a..3f99a20a8a20aa62a46daa6143e0ba181c327ae5 100644 (file)
   - type: BorgModuleIcon
     icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-extinguisher-module }
 
+- type: entity
+  parent: [ BaseXenoborgModuleEngi, BaseProviderBorgModule, BaseXenoborgContraband ]
+  id: XenoborgModuleDoorControl
+  name: door control xenoborg module
+  description: Module that allows Xenoborgs to control airlocks.
+  components:
+  - type: Sprite
+    layers:
+    - state: xenoborg_engi
+    - state: icon-xenoborg-access-breaker
+  - type: ItemBorgModule
+    hands:
+    - item: DoorRemoteXenoborg
+    - item: AccessBreaker
+    - item: AccessConfiguratorXenoborg
+  - type: BorgModuleIcon
+    icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-door-remote-module }
+
 - type: entity
   parent: [ BaseXenoborgModuleHeavy, BaseProviderBorgModule, BaseXenoborgContraband ]
   id: XenoborgModuleJammer
index 7ade603634ec20605caadb1d6435698422039198..85f7486d3f55afd8e3584b58d119a8a5544845e7 100644 (file)
     denialSound:
       path: /Audio/Machines/custom_deny.ogg
     doAfter: 0.5
+
+- type: entity
+  parent: AccessConfigurator
+  id: AccessConfiguratorXenoborg
+  name: xenoborg access configurator
+  description: A modified access configurator used by the xenoborgs.
+  components:
+  - type: Sprite
+    sprite: Objects/Tools/access_configurator.rsi
+  - type: Clothing
+    sprite: Objects/Tools/access_configurator.rsi
+  - type: AccessOverrider
+    showPrivilegedId: false
+    accessLevels:
+    - Xenoborg
+    privilegedIdSlot:
+      name: id-card-console-privileged-id
+      startingItem: XenoborgIDCard
+      ejectSound: /Audio/Machines/id_swipe.ogg
+      insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
+      ejectOnBreak: true
+      disableEject: true
+      swap: false
+      whitelist:
+        components:
+        - IdCard
+    denialSound:
+      path: /Audio/Machines/custom_deny.ogg
+    doAfter: 0.5
index 31efc63265af23fc939edfb07e68a571224f5e51..1ae6a3cf07ee8f90a205c3e688358f4b30e8a185 100644 (file)
 - type: latheRecipePack
   id: XenoborgUpgradeModules
   recipes:
+  # engi xenoborg
+  - XenoborgModuleDoorControlRecipe
+  # heavy xenoborg
   - XenoborgModuleHeavyLaserRecipe
+  # scout xenoborg
   - XenoborgModuleEnergySwordRecipe
+  # stealth xenoborg
   - XenoborgModuleSuperCloakDeviceRecipe
index 9b150a502b447c3f34c7bf979618e8399c6b1d44..0c8a822398cd7d309f3046265634f99514b863dd 100644 (file)
 
 # modules
 
+## engi xenoborg modules
+
+- type: latheRecipe
+  parent: BaseXenoborgModulesRecipe
+  id: XenoborgModuleDoorControlRecipe
+  result: XenoborgModuleDoorControl
+  materials:
+    Steel: 1500
+    Glass: 1500
+
+## heavy xenoborg modules
+
 - type: latheRecipe
   parent: BaseXenoborgModulesRecipe
   id: XenoborgModuleHeavyLaserRecipe
   result: XenoborgModuleHeavyLaser
 
+## scout xenoborg modules
+
 - type: latheRecipe
   parent: BaseXenoborgModulesRecipe
   id: XenoborgModuleEnergySwordRecipe
   result: XenoborgModuleEnergySword
 
+## stealth xenoborg modules
+
 - type: latheRecipe
   parent: BaseXenoborgModulesRecipe
   id: XenoborgModuleSuperCloakDeviceRecipe
index 6072a9a2f9dd16f1fd50619e38922aad2995eac5..c4de609965cc1503c8f4dc736ad9173104fd6473 100644 (file)
         {
             "name":"xenoborg-control-computer"
         },
+        {
+            "name":"xenoborg-door-remote-module"
+        },
         {
             "name":"xenoborg-extinguisher-module"
         },
diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-door-remote-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-door-remote-module.png
new file mode 100644 (file)
index 0000000..a5ca9cf
Binary files /dev/null and b/Resources/Textures/Interface/Actions/actions_borg.rsi/xenoborg-door-remote-module.png differ