Xenoborg door control module (#41546)

* 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
This commit is contained in:
Samuka
2025-12-15 22:24:54 -03:00
committed by GitHub
parent 971d4efca8
commit 0fb6f26edb
19 changed files with 155 additions and 13 deletions

View 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" />

View 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);
}

View 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"
});

View File

@@ -148,7 +148,8 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
missingAccess,
privilegedIdName,
targetLabel,
targetLabelColor);
targetLabelColor,
component.ShowPrivilegedId);
_userInterface.SetUiState(uid, AccessOverriderUiKey.Key, newState);
}

View 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;
}
}

View 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);

View File

@@ -70,5 +70,6 @@ public enum OperatingMode : byte
{
OpenClose,
ToggleBolts,
ToggleEmergencyAccess
ToggleEmergencyAccess,
ToggleOvercharge
}

View 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(

View 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

View 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

View File

@@ -43,6 +43,7 @@
- BorgModuleCable
- XenoborgModuleAccessBreaker
- XenoborgModuleFireExtinguisher
- type: ShowElectrocutionHUD
- type: ShowHealthBars
damageContainers:
- Inorganic

View File

@@ -13,18 +13,18 @@
- 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
@@ -37,6 +37,28 @@
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
@@ -209,7 +231,7 @@
- Xenoborg
- type: entity
parent: [ DoorRemoteDefault, BaseXenoborgContraband ]
parent: [ DoorRemoteCanEletrifyDoors, BaseXenoborgContraband ]
id: DoorRemoteXenoborg
name: xenoborg door remote
components:

View File

@@ -1043,6 +1043,18 @@
- 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

View File

@@ -1506,6 +1506,24 @@
- 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

View File

@@ -144,3 +144,32 @@
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

View File

@@ -11,6 +11,11 @@
- type: latheRecipePack
id: XenoborgUpgradeModules
recipes:
# engi xenoborg
- XenoborgModuleDoorControlRecipe
# heavy xenoborg
- XenoborgModuleHeavyLaserRecipe
# scout xenoborg
- XenoborgModuleEnergySwordRecipe
# stealth xenoborg
- XenoborgModuleSuperCloakDeviceRecipe

View File

@@ -51,16 +51,32 @@
# 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

View File

@@ -139,6 +139,9 @@
{
"name":"xenoborg-control-computer"
},
{
"name":"xenoborg-door-remote-module"
},
{
"name":"xenoborg-extinguisher-module"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B