From 5c206ede67b0f3feb413068000f08a5031cab067 Mon Sep 17 00:00:00 2001 From: RedBookcase Date: Sat, 23 Aug 2025 13:32:15 -0700 Subject: [PATCH 01/16] Added more Derelict Cyborgs. (#38159) * Added more Derelict Borgs. * minor fix & salvage borg instead of mining borg name. * I LOVE CAPITALIZATION! * Fixed Derelict Engineer Cyborg name and added unshaded crystal layer. * Ordering fixes & other cleanup. * Updated Derelict Salvage Cyborg Sprites. * New Salvage borg sprites. * Updated module comments. * Update events.yml Extended the Derelict Syndicate Assault Borg's spawn timer to 25 minutes from 15. * Fix for new borg hands * Update events.yml --------- Co-authored-by: RedBookcase --- .../ghost/roles/ghost-role-component.ftl | 17 +- .../Entities/Markers/Spawners/ghost_roles.yml | 60 + .../Mobs/Cyborgs/base_borg_chassis.yml | 14 + .../Entities/Mobs/Cyborgs/borg_chassis.yml | 165 +- .../Entities/Mobs/Player/silicon.yml | 182 ++- .../Specific/Robotics/borg_modules.yml | 88 +- .../Objects/Weapons/Guns/SMGs/smgs.yml | 41 + .../Objects/Weapons/Melee/e_sword.yml | 9 +- Resources/Prototypes/GameRules/events.yml | 135 +- .../Actions/actions_borg.rsi/meta.json | 8 +- .../syndicate-c20r-module.png | Bin 0 -> 675 bytes .../syndicate-desword-module.png | Bin 0 -> 782 bytes .../syndicate-esword-module.png | Bin 782 -> 560 bytes .../Silicon/chassis.rsi/engineer_derelict.png | Bin 0 -> 3312 bytes .../chassis.rsi/engineer_derelict_crystal.png | Bin 0 -> 1333 bytes .../Silicon/chassis.rsi/janitor_derelict.png | Bin 0 -> 4522 bytes .../chassis.rsi/janitor_moving_derelict.png | Bin 0 -> 5502 bytes .../Silicon/chassis.rsi/medical_derelict.png | Bin 0 -> 4171 bytes .../chassis.rsi/medical_moving_derelict.png | Bin 0 -> 4378 bytes .../Mobs/Silicon/chassis.rsi/meta.json | 1444 +++++++++-------- .../Silicon/chassis.rsi/miner_derelict.png | Bin 0 -> 3494 bytes .../chassis.rsi/miner_moving_derelict.png | Bin 0 -> 4363 bytes .../Silicon/chassis.rsi/synd_sec_derelict.png | Bin 0 -> 3707 bytes .../chassis.rsi/synd_sec_derelict_e.png | Bin 0 -> 824 bytes .../chassis.rsi/synd_sec_derelict_l.png | Bin 0 -> 924 bytes 25 files changed, 1467 insertions(+), 696 deletions(-) create mode 100644 Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-c20r-module.png create mode 100644 Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-desword-module.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict_crystal.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_moving_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/medical_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/medical_moving_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/miner_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/miner_moving_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_e.png create mode 100644 Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_l.png diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index ce52b88655..a578adf82b 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -244,9 +244,24 @@ ghost-role-information-syndicate-cyborg-assault-name = Syndicate Assault Cyborg ghost-role-information-syndicate-cyborg-saboteur-name = Syndicate Saboteur Cyborg ghost-role-information-syndicate-cyborg-description = The Syndicate needs reinforcements. You, a cold silicon killing machine, will help them. -ghost-role-information-derelict-cyborg-name = Derelict Cyborg +ghost-role-information-derelict-engineering-cyborg-name = Derelict Engineer Cyborg +ghost-role-information-derelict-engineering-cyborg-description = You are an engineer cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. + +ghost-role-information-derelict-cyborg-name = Derelict Generic Cyborg ghost-role-information-derelict-cyborg-description = You are a regular cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. +ghost-role-information-derelict-janitor-cyborg-name = Derelict Janitor Cyborg +ghost-role-information-derelict-janitor-cyborg-description = You are a janitor cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. + +ghost-role-information-derelict-medical-cyborg-name = Derelict Medical Cyborg +ghost-role-information-derelict-medical-cyborg-description = You are a medical cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. + +ghost-role-information-derelict-mining-cyborg-name = Derelict Salvage Cyborg +ghost-role-information-derelict-mining-cyborg-description = You are a salvage cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. + +ghost-role-information-derelict-syndicate-assault-cyborg-name = Derelict Syndicate Assault Cyborg +ghost-role-information-derelict-syndicate-assault-cyborg-description = You are an early model syndicate assault cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station. + ghost-role-information-security-name = Security ghost-role-information-security-description = You are part of a security task force, but seem to have found yourself in a strange situation... diff --git a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml index e662a8b211..5815dbba47 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml @@ -211,6 +211,18 @@ - sprite: Mobs/Aliens/paradox_clone.rsi state: preview +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: SpawnPointGhostDerelictCyborg + id: SpawnPointGhostDerelictEngineeringCyborg + components: + - type: GhostRole + name: ghost-role-information-derelict-engineering-cyborg-name + description: ghost-role-information-derelict-engineering-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: entity categories: [ HideSpawnMenu, Spawner ] parent: BaseAntagSpawner @@ -229,6 +241,54 @@ - sprite: Mobs/Silicon/chassis.rsi state: derelict_icon +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: SpawnPointGhostDerelictCyborg + id: SpawnPointGhostDerelictJanitorCyborg + components: + - type: GhostRole + name: ghost-role-information-derelict-janitor-cyborg-name + description: ghost-role-information-derelict-janitor-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: SpawnPointGhostDerelictCyborg + id: SpawnPointGhostDerelictMedicalCyborg + components: + - type: GhostRole + name: ghost-role-information-derelict-medical-cyborg-name + description: ghost-role-information-derelict-medical-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: SpawnPointGhostDerelictCyborg + id: SpawnPointGhostDerelictMiningCyborg + components: + - type: GhostRole + name: ghost-role-information-derelict-mining-cyborg-name + description: ghost-role-information-derelict-mining-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: SpawnPointGhostDerelictCyborg + id: SpawnPointGhostDerelictSyndicateAssaultCyborg + components: + - type: GhostRole + name: ghost-role-information-derelict-syndicate-assault-cyborg-name + description: ghost-role-information-derelict-syndicate-assault-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: entity categories: [ HideSpawnMenu, Spawner ] parent: BaseAntagSpawner diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 34fdbbd74b..4b170af6be 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -353,6 +353,7 @@ - Syndicate - type: ActiveRadio channels: + - Binary - Syndicate - type: ShowSyndicateIcons - type: MovementAlwaysTouching @@ -386,6 +387,19 @@ chance: 1 - type: ShowJobIcons +- type: entity + id: BaseBorgChassisSyndicateDerelict #For assault borg and maybe others in time + parent: BaseBorgChassisSyndicate + abstract: true + components: + - type: SiliconLawProvider + laws: SyndicateStatic #Non-subverted version so they can still be changed + - type: StartIonStormed + ionStormAmount: 3 + - type: IonStormTarget + chance: 1 + - type: ShowJobIcons + - type: entity parent: BaseBorgChassisNotIonStormable id: BaseXenoborgChassis diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml index 87b8d54a97..1b9fbed3ac 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml @@ -206,7 +206,7 @@ map: ["light"] visible: false - type: BorgChassis - maxModules: 5 # the sixth one broke lol + maxModules: 5 # One less module slot than the regular module to reflect this being a "broken" cyborg. moduleWhitelist: tags: - BorgModuleGeneric @@ -218,4 +218,165 @@ interactSuccessString: petting-success-derelict-cyborg interactFailureString: petting-failure-derelict-cyborg interactSuccessSound: - path: /Audio/Ambience/Objects/periodic_beep.ogg \ No newline at end of file + path: /Audio/Ambience/Objects/periodic_beep.ogg + +- type: entity + parent: BaseBorgChassisDerelict + id: EngineeringBorgChassisDerelict + name: derelict engineer cyborg + description: A man-machine hybrid that assists the engineering department. This one seems to have chunks of strange crystals pockmarking its surface. + components: + - type: Sprite + layers: + - state: engineer_derelict + - state: engineer_e_r + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded + visible: false + - state: engineer_derelict_crystal #This layer and the layer below are duplicated in order to create a more mellow unshaded layer. See https://github.com/space-wizards/space-station-14/pull/37869 for more info on the method. + shader: unshaded + - state: engineer_derelict_crystal + shader: shaded + - state: engineer_l + shader: unshaded + map: ["light"] + visible: false + - type: BorgChassis + maxModules: 5 # One less module slot than the regular module to reflect this being a "broken" cyborg. + moduleWhitelist: + tags: + - BorgModuleGeneric + - BorgModuleEngineering + hasMindState: engineer_e + noMindState: engineer_e_r + +- type: entity + parent: BaseBorgChassisDerelict + id: JanitorBorgChassisDerelict + name: derelict janitor cyborg + description: A man-machine hybrid that assists the service department. It's a bigger mess than anything it can clean up. + components: + - type: Sprite + layers: + - state: janitor_derelict + map: ["movement"] + - state: janitor_e_r + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded + visible: false + - state: janitor_l + shader: unshaded + map: ["light"] + visible: false + - type: SpriteMovement + movementLayers: + movement: + state: janitor_moving_derelict + noMovementLayers: + movement: + state: janitor_derelict + - type: BorgChassis + maxModules: 5 # One less module slot than the regular module to reflect this being a "broken" cyborg. + moduleWhitelist: + tags: + - BorgModuleGeneric + - BorgModuleJanitor + hasMindState: janitor_e + noMindState: janitor_e_r + +- type: entity + parent: BaseBorgChassisDerelict + id: MedicalBorgChassisDerelict + name: derelict medical cyborg + description: A man-machine hybrid that assists the medical department. This one's needles don't look very sanitary. + components: + - type: Sprite + layers: + - state: medical_derelict + map: ["movement"] + - state: medical_e_r + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded + visible: false + - state: medical_l + shader: unshaded + map: ["light"] + visible: false + - type: SpriteMovement + movementLayers: + movement: + state: medical_moving_derelict + noMovementLayers: + movement: + state: medical_derelict + - type: BorgChassis + maxModules: 6 # One less module slot than the regular module to reflect this being a "broken" cyborg. + moduleWhitelist: + tags: + - BorgModuleGeneric + - BorgModuleMedical + hasMindState: medical_e + noMindState: medical_e_r + +- type: entity + parent: BaseBorgChassisDerelict + id: MiningBorgChassisDerelict + name: derelict salvage cyborg + description: A man-machine hybrid that assists the cargo department. This one has seen the wrong side of a gibtonite chunk. + components: + - type: Sprite + layers: + - state: miner_derelict + map: ["movement"] + - state: miner_e_r + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded + visible: false + - state: miner_l + shader: unshaded + map: ["light"] + visible: false + - type: SpriteMovement + movementLayers: + movement: + state: miner_moving_derelict + noMovementLayers: + movement: + state: miner_derelict + - type: BorgChassis + maxModules: 6 # One less module slot than the regular module to reflect this being a "broken" cyborg. + moduleWhitelist: + tags: + - BorgModuleGeneric + - BorgModuleCargo + hasMindState: miner_e + noMindState: miner_e_r + +- type: entity + parent: BaseBorgChassisSyndicateDerelict + id: SyndicateAssaultBorgChassisDerelict + name: derelict syndicate assault cyborg + description: A lean, mean killing machine with access to a variety of deadly modules. This one is more rust-orange than blood-red. + components: + - type: Sprite + layers: + - state: synd_sec_derelict + - state: synd_sec_e + map: ["enum.BorgVisualLayers.Light"] + shader: unshaded + visible: false + - state: synd_sec_l + shader: unshaded + map: ["light"] + visible: false + - type: BorgChassis + maxModules: 3 + moduleWhitelist: # Note - the Derelict Assault Borg does not have a traversal module. This is intentional as Assault Borgs have space traversal with their c20 and free space movement, and they can navigate to the station using the pinpointer. + tags: + - BorgModuleGeneric + - BorgModuleSyndicate + - BorgModuleSyndicateAssault + hasMindState: synd_sec_derelict_e + noMindState: synd_sec_derelict + - type: Construction + node: derelictcyborg diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 303f7dc676..c2025bb663 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -383,7 +383,7 @@ borg_module: - BorgModuleOperative - BorgModuleL6C - - BorgModuleEsword + - BorgModuleDoubleEsword - type: ItemSlots slots: cell_slot: @@ -453,8 +453,44 @@ - PlayerBorgSyndicateSaboteurGhostRole - type: entity - id: PlayerBorgDerelict + parent: EngineeringBorgChassisDerelict + id: PlayerEngineeringBorgDerelict + suffix: Battery, Module + components: + - type: ContainerFill + containers: + borg_brain: + - PositronicBrain + borg_module: + - BorgModuleTool + - BorgModuleFireExtinguisher + - BorgModuleConstruction + - BorgModuleRCD + - BorgModuleCable + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHigh + - type: RandomMetadata + nameSegments: [NamesBorg] + +- type: entity + parent: PlayerEngineeringBorgDerelict + id: PlayerEngineeringBorgDerelictGhostRole + suffix: Ghost role + components: + - type: GhostRole + name: ghost-role-information-derelict-engineering-cyborg-name + description: ghost-role-information-derelict-engineering-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: GhostTakeoverAvailable + +- type: entity parent: BorgChassisDerelict + id: PlayerBorgDerelict suffix: Battery, Module components: - type: ContainerFill @@ -473,8 +509,8 @@ nameSegments: [NamesBorg] - type: entity - id: PlayerBorgDerelictGhostRole parent: PlayerBorgDerelict + id: PlayerBorgDerelictGhostRole suffix: Ghost role components: - type: GhostRole @@ -484,3 +520,143 @@ raffle: settings: default - type: GhostTakeoverAvailable + +- type: entity + parent: JanitorBorgChassisDerelict + id: PlayerJanitorBorgDerelict + suffix: Battery, Module + components: + - type: ContainerFill + containers: + borg_brain: + - PositronicBrain + borg_module: + - BorgModuleTool + - BorgModuleFireExtinguisher + - BorgModuleCleaning + - BorgModuleCustodial + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHigh + - type: RandomMetadata + nameSegments: [NamesBorg] + +- type: entity + parent: PlayerJanitorBorgDerelict + id: PlayerJanitorBorgDerelictGhostRole + suffix: Ghost role + components: + - type: GhostRole + name: ghost-role-information-derelict-janitor-cyborg-name + description: ghost-role-information-derelict-janitor-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: GhostTakeoverAvailable + +- type: entity + parent: MedicalBorgChassisDerelict + id: PlayerMedicalBorgDerelict + suffix: Battery, Module + components: + - type: ContainerFill + containers: + borg_brain: + - PositronicBrain + borg_module: + - BorgModuleTool + - BorgModuleFireExtinguisher + - BorgModuleChemical + - BorgModuleTopicals + - BorgModuleRescue + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHigh + - type: RandomMetadata + nameSegments: [NamesBorg] + +- type: entity + parent: PlayerMedicalBorgDerelict + id: PlayerMedicalBorgDerelictGhostRole + suffix: Ghost role + components: + - type: GhostRole + name: ghost-role-information-derelict-medical-cyborg-name + description: ghost-role-information-derelict-medical-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: GhostTakeoverAvailable + +- type: entity + parent: MiningBorgChassisDerelict + id: PlayerMiningBorgDerelict + suffix: Battery, Module + components: + - type: ContainerFill + containers: + borg_brain: + - PositronicBrain + borg_module: + - BorgModuleTool #No fire extinguisher, traversal is better + - BorgModuleMining + - BorgModuleTraversal + - BorgModuleAppraisal + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHigh + - type: RandomMetadata + nameSegments: [NamesBorg] + +- type: entity + parent: PlayerMiningBorgDerelict + id: PlayerMiningBorgDerelictGhostRole + suffix: Ghost role + components: + - type: GhostRole + name: ghost-role-information-derelict-mining-cyborg-name + description: ghost-role-information-derelict-mining-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: GhostTakeoverAvailable + +- type: entity + parent: SyndicateAssaultBorgChassisDerelict + id: PlayerSyndicateAssaultBorgDerelict + suffix: Battery, Module + components: + - type: ContainerFill + containers: + borg_brain: + - PositronicBrain + borg_module: + - BorgModuleOperative + - BorgModuleC20r + - BorgModuleEsword + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + startingItem: PowerCellHyper + - type: RandomMetadata + nameSegments: [NamesDeathCommando] + +- type: entity + parent: PlayerSyndicateAssaultBorgDerelict + id: PlayerBorgSyndicateDerelictGhostRole + suffix: Ghost role + components: + - type: GhostRole + name: ghost-role-information-derelict-syndicate-assault-cyborg-name + description: ghost-role-information-derelict-syndicate-assault-cyborg-description + rules: ghost-role-information-silicon-rules + raffle: + settings: default + - type: GhostTakeoverAvailable diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 02b1afdbc5..2a971d71ea 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -1132,8 +1132,8 @@ #syndicate modules - type: entity - id: BorgModuleSyndicateWeapon parent: [ BaseBorgModule, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleSyndicateWeapon name: weapon cyborg module components: - type: Sprite @@ -1168,8 +1168,8 @@ price: 2500 - type: entity - id: BorgModuleOperative parent: [ BaseBorgModuleSyndicate, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleOperative name: operative cyborg module description: A module that comes with a crowbar, an Emag, an Access Breaker and a syndicate pinpointer. components: @@ -1187,42 +1187,76 @@ icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-operative-module } - type: entity - id: BorgModuleEsword parent: [ BaseBorgModuleSyndicate, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleEsword name: energy sword cyborg module - description: A module that comes with a double energy sword. + description: A weapons module that comes with an energy sword. components: - - type: Sprite - layers: - - state: syndicate - - state: icon-syndicate - - type: ItemBorgModule - hands: - - item: CyborgEnergySwordDouble - - item: PinpointerSyndicateNuclear - - type: BorgModuleIcon - icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-esword-module } + - type: Sprite + layers: + - state: syndicate + - state: icon-syndicate + - type: ItemBorgModule + hands: + - item: CyborgEnergySword + - item: PinpointerSyndicateNuclear + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-esword-module } + +- type: entity + id: BorgModuleDoubleEsword + parent: [ BaseBorgModuleSyndicate, BaseProviderBorgModule, BaseSyndicateContraband ] + name: double energy sword cyborg module + description: A weapons module that comes with a double energy sword. + components: + - type: Sprite + layers: + - state: syndicate + - state: icon-syndicate + - type: ItemBorgModule + hands: + - item: CyborgEnergySwordDouble + - item: PinpointerSyndicateNuclear + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-desword-module } - type: entity - id: BorgModuleL6C parent: [ BaseBorgModuleSyndicateAssault, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleL6C name: L6C ROW cyborg module - description: A module that comes with a L6C. + description: A weapons module that comes with a L6C. components: - - type: Sprite - layers: - - state: syndicate - - state: icon-syndicate - - type: ItemBorgModule - hands: - - item: WeaponLightMachineGunL6C - - item: PinpointerSyndicateNuclear - - type: BorgModuleIcon - icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-l6c-module } + - type: Sprite + layers: + - state: syndicate + - state: icon-syndicate + - type: ItemBorgModule + hands: + - item: WeaponLightMachineGunL6C + - item: PinpointerSyndicateNuclear + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-l6c-module } + +- type: entity + parent: [ BaseBorgModuleSyndicateAssault, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleC20r + name: C20-r ROW cyborg module + description: A weapons module that comes with a burst-fire C-20r. + components: + - type: Sprite + layers: + - state: syndicate + - state: icon-syndicate + - type: ItemBorgModule + hands: + - item: WeaponSubMachineGunC20rROW + - item: PinpointerSyndicateNuclear + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-c20r-module } - type: entity - id: BorgModuleMartyr parent: [ BaseBorgModule, BaseProviderBorgModule, BaseSyndicateContraband ] + id: BorgModuleMartyr name: martyr cyborg module description: "A module that comes with an explosive you probably don't want to handle yourself." components: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index f069b4a918..2ecaaec89e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -123,6 +123,47 @@ - type: StaticPrice price: 5000 +- type: entity + name: C-20r ROW #I think ROW stands for Recharging Onboard Weapon so i'm following the L6C's example + id: WeaponSubMachineGunC20rROW + parent: BaseItem + description: A burst-fire C-20r submachine gun for use by cyborgs. Creates .35 caliber ammo on the fly from an internal ammo fabricator, which slowly self-charges. + components: + - type: Gun + minAngle: 2 + maxAngle: 16 + angleIncrease: 4 + angleDecay: 16 + fireRate: 8 + burstFireRate: 8 + selectedMode: Burst + availableModes: + - Burst + soundGunshot: + path: /Audio/Weapons/Guns/Gunshots/c-20r.ogg + - type: Sprite + sprite: Objects/Weapons/Guns/SMGs/c20r.rsi + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-5 + map: ["enum.GunVisualLayers.Mag"] + - type: Item + size: Huge + - type: ContainerContainer + containers: + ballistic-ammo: !type:Container + - type: ProjectileBatteryAmmoProvider + proto: CartridgePistol + fireCost: 100 + - type: Battery + maxCharge: 3000 + startingCharge: 3000 + - type: BatterySelfRecharger + autoRecharge: true + autoRechargeRate: 25 + - type: AmmoCounter + - type: entity name: Drozd parent: [BaseWeaponSubMachineGun, BaseSecurityContraband] diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index f634425006..5f431416e7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -397,10 +397,17 @@ spread: 75 # Borgs + +- type: entity + parent: EnergySword + id: CyborgEnergySword + suffix: For Borgs + description: A very loud & dangerous sword with a beam made of pure, concentrated plasma. Specially designed for syndicate cyborgs. + - type: entity - suffix: One-Handed, For Borgs parent: EnergySwordDouble id: CyborgEnergySwordDouble # why is this invalid if ID is BorgEnergySwordDouble + suffix: One-Handed, For Borgs description: Syndicate Command Interns thought that having one blade on the energy sword was not enough. Specially designed for syndicate cyborgs. components: # could add energy-draining like the L6C - type: Wieldable diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index acd3d4a2b8..c9e612c7f5 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -32,7 +32,8 @@ - id: ClosetSkeleton - id: KingRatMigration - id: RevenantSpawn - - id: DerelictCyborgSpawn + - !type:NestedSelector + tableId: DerelictBorgEventTable - type: entityTable id: ModerateAntagEventsTable @@ -45,6 +46,25 @@ - id: ZombieOutbreak - id: LoneOpsSpawn - id: WizardSpawn + - !type:NestedSelector + tableId: DerelictBorgEventTable + +- type: entityTable + id: DerelictBorgEventTable #For Derelict Borg spawns + table: !type:GroupSelector + children: + - !type:GroupSelector # Standard NT Borgs + weight: 85 + children: + - id: DerelictEngineerCyborgSpawn + - id: DerelictGenericCyborgSpawn + - id: DerelictJanitorCyborgSpawn + - id: DerelictMedicalCyborgSpawn + - id: DerelictMiningCyborgSpawn + - !type:GroupSelector # Other Borgs + weight: 15 + children: + - id: DerelictSyndicateAssaultCyborgSpawn - type: entity id: BaseStationEvent @@ -542,7 +562,7 @@ earliestStart: 35 weight: 5.5 minimumPlayers: 20 - duration: null # LoneOpsSpawn needs an infinite duration so that it inherits the NukeOpsRule things of an actually appropriate end scrreen (not always "Neutral outcome!") and... ending the game if the station is nuked. + duration: null # LoneOpsSpawn needs an infinite duration so that it inherits the NukeOpsRule things of an actually appropriate end screen (not always "Neutral outcome!") and... ending the game if the station is nuked. - type: RuleGrids - type: LoadMapRule gridPath: /Maps/Shuttles/ShuttleEvent/striker.yml @@ -673,10 +693,10 @@ - type: entity parent: BaseGameRule - id: DerelictCyborgSpawn + id: DerelictEngineerCyborgSpawn components: - type: StationEvent - weight: 5 + weight: 2.5 earliestStart: 15 reoccurrenceDelay: 20 minimumPlayers: 4 @@ -684,10 +704,115 @@ - type: SpaceSpawnRule spawnDistance: 0 - type: AntagSpawner - prototype: PlayerBorgDerelict + prototype: PlayerEngineeringBorgDerelictGhostRole + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostDerelictEngineeringCyborg + min: 1 + max: 1 + pickPlayer: false + +- type: entity + parent: BaseGameRule + id: DerelictGenericCyborgSpawn + components: + - type: StationEvent + weight: 2.5 + earliestStart: 15 + reoccurrenceDelay: 20 + minimumPlayers: 4 + duration: null + - type: SpaceSpawnRule + spawnDistance: 0 + - type: AntagSpawner + prototype: PlayerBorgDerelictGhostRole - type: AntagSelection definitions: - spawnerPrototype: SpawnPointGhostDerelictCyborg min: 1 max: 1 pickPlayer: false + +- type: entity + parent: BaseGameRule + id: DerelictJanitorCyborgSpawn + components: + - type: StationEvent + weight: 2.5 + earliestStart: 15 + reoccurrenceDelay: 20 + minimumPlayers: 4 + duration: null + - type: SpaceSpawnRule + spawnDistance: 0 + - type: AntagSpawner + prototype: PlayerJanitorBorgDerelictGhostRole + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostDerelictJanitorCyborg + min: 1 + max: 1 + pickPlayer: false + +- type: entity + parent: BaseGameRule + id: DerelictMedicalCyborgSpawn + components: + - type: StationEvent + weight: 2.5 + earliestStart: 15 + reoccurrenceDelay: 20 + minimumPlayers: 4 + duration: null + - type: SpaceSpawnRule + spawnDistance: 0 + - type: AntagSpawner + prototype: PlayerMedicalBorgDerelictGhostRole + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostDerelictMedicalCyborg + min: 1 + max: 1 + pickPlayer: false + +- type: entity + parent: BaseGameRule + id: DerelictMiningCyborgSpawn + components: + - type: StationEvent + weight: 2.5 + earliestStart: 15 + reoccurrenceDelay: 20 + minimumPlayers: 4 + duration: null + - type: SpaceSpawnRule + spawnDistance: 0 + - type: AntagSpawner + prototype: PlayerMiningBorgDerelictGhostRole + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostDerelictMiningCyborg + min: 1 + max: 1 + pickPlayer: false + +- type: entity + parent: BaseGameRule + id: DerelictSyndicateAssaultCyborgSpawn + components: + - type: StationEvent + weight: 2.5 + earliestStart: 25 + reoccurrenceDelay: 20 + minimumPlayers: 15 + duration: null + - type: SpaceSpawnRule + spawnDistance: 0 + - type: AntagSpawner + prototype: PlayerBorgSyndicateDerelictGhostRole + - type: AntagSelection + definitions: + - spawnerPrototype: SpawnPointGhostDerelictSyndicateAssaultCyborg + min: 1 + max: 1 + pickPlayer: false diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json b/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json index ac631e0294..ae485c26c5 100644 --- a/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/actions_borg.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/cdbcb1e858b11f083994a7a269ed67ef5b452ce9, Module actions by Scarky0. chem, adv-chem, and adv-mining by mubururu_, xenoborg actions by Samuka-C (github), advclown by ThatGuyUSA", + "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/cdbcb1e858b11f083994a7a269ed67ef5b452ce9, Module actions by Scarky0. chem, adv-chem, and adv-mining by mubururu_, xenoborg actions by Samuka-C (github), advclown by ThatGuyUSA. c20r and esword by RedBookcase on Github.", "size": { "x": 32, "y": 32 @@ -106,12 +106,18 @@ { "name":"syndicate-operative-module" }, + { + "name":"syndicate-desword-module" + }, { "name":"syndicate-esword-module" }, { "name":"syndicate-l6c-module" }, + { + "name":"syndicate-c20r-module" + }, { "name":"syndicate-martyr-module" }, diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-c20r-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-c20r-module.png new file mode 100644 index 0000000000000000000000000000000000000000..52c14b26516bb4737c6e265684b8958230753d08 GIT binary patch literal 675 zcmV;U0$lxxP)bA-DyS%Z-z3EliumWMd%$ooiISyge^G{wM)$8=ecIYD}nzV)u8tiRV zHgp-`F1X?sPL+%j&11JqAb?g?r}}Q(zk5REc+oC?^Ku$^rZtURA9 z2ck~>oCu{wT3ltfpaKgZSzn1&05y75KPJNN*MH5HrR@6p`3BlYGE2;#JvaaW002ov JPDHLkV1n@kA7%gm literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-desword-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-desword-module.png new file mode 100644 index 0000000000000000000000000000000000000000..201149cf18e82ab28d6a834cdd2a45ea52294a84 GIT binary patch literal 782 zcmV+p1M&QcP)j|#J@k-6=^-?Kp!6gq zmqN%7=qV>pp@;r}(4z#8{RJg~7D@s=h%Ho>7&$y$zv#!n>Y!2-U zgF5qmJJGoi;z!nei@%O}n~1s>QT!n-&b5If%N{o2 zYXFv7wCCEuwUXY~K+PU7@M3kvGykdH2vsOJ-rGSS1BpnVQn3+NFVji-+^B06f4;KH zv7^*A%Npj@W}w}VP@Ko^Mppd(P^r?BWO^zSKpv0AD4!k0A(zanG7wP{pi>Mm@PLQ0 zv_!_~DZS4b^f(?BOh_MfU=2R-MGRt*L$K-isOD<`onm~vY0-~vkKUF|GB-ELJUnDn z8;mY4n2>&QU=C~WfiGeZiyX)${iZhHMs(h~p>D5BrD}zYy}dvte8|}sF^EMDcTUwj zLKLI}*w-~akm5WPi|o83_V%YWP_3Y~ap&cl20AcSh$I850R>JrP!$**fr+gxDqU8^ zdOpL&kB^CXt{{+G98>39zEt|RKsD?mn83d7^8NztQ$`Cj(G<@OkoOpQi)VurRZ|DX znPlQyvq5=>37{rEbS0h}?D=@)(q?8r8t(M(+XXT^9f4Zzdza_D_dUq&z<^Y^H`xr) z!2!|!K9R$O!Aw*-zoshY%nY~{4)+|WzciZSC_i(U$U8S+vSQA_fJ9y}49{t=IoA-# z-M6D)mIIkk83cck?S&n zoZ1Y)-kqIkBcH|ua=CN6&36sAmlL#{PE)(tq*o^=^mVA|;og?P1nlDSN_-;cwr$h* zc6)LI$@O(QFPF)5>ZRyzZ^@?fnJ`Uyl*_S}dmFg-KPLD7*X+Oj0ro&Zmmk?jD*ylh M07*qoM6N<$f=dZ+YybcN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-esword-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/syndicate-esword-module.png index 201149cf18e82ab28d6a834cdd2a45ea52294a84..944c4ee918646393b583c35fbdf96be5921c7568 100644 GIT binary patch delta 514 zcmV+d0{#7t2CxK>IDY}+Nklu0(O>SDK<&GVI_lWvZK!4+{^5`lR&Z{=n8ZG@67rCody2; zb)YxkR>Id$81h1(>Z)Iuc!P*7;YQl5&x(lX<*4`x!a^%(5Puo02r6VKfZj-jWuXPU zo0i`xU?d0Qz-2OF0BMdV+uz0tgg9`KNFpU^OOFUqofYl?C67iVTxYXu;-|q7^Hm6% zvjQDp&zX34_Gw7FoxE=c?E9RO(>c%k z4DsQB6*)~i9WuP+zPrGA!g(S0(FJzoRuhi*5W$@R{(ITZEA7Dn5#*jSaJpRKDxc$= z?E)O2OFncuc&=9AHru_*yJnyqJ3=g-#(X+OrQODx+TXl=?pBh+9H2+?cqW5xuZR9t zFNI)F$&L<`B^fnEe0>G0tJcOw4YAr@nE(I)07*qoM6N<$ Eg5_HE*#H0l delta 738 zcmV<80v-LZ1daxfIDZ1bNkl-?2Qh>+eqq7N;+nqCxTCwXuFe{4 z4($trI`e)#&&)i#68-D8;Qp}_quakxv}ld$4!_9aN7j6czkiN-n~1s>QT!n-&b5If z%N{o2YXFv7wCCEuwUXY~K+PU7@M3kvGykdH2vsOJ-rGSS1BpnVQn3+NFVji-+^B06 zf4;KHv7^*A%Npj@W}w}VP@Ko^Mppd(P^r?BWO^zSKpv0AD4!k0A(zanG7wP{pi>Mm z@PLQ0v_!_~DSy4s8T2?F6--DUbzluX@I?$_kwdWQ_^9S<0G(odylK&oZjauUO)@t( z$viw{R2z&gE|`#ha$pW?@PRL45Q`khCH@;CVa@*7cq!M z4tGw~JVF$t1K8I!K9J%(6pQSgWg!^Mw}iFmFckXsy6=Ul#2`nNze>?4@KzV7n=0_{^q3p3Fa&kd0G7c;wP%W z>Gidd>oS3y+6=(notZRyzZ^@?fnJ`Uyl*_S}dmFg-KPLD7*X+Oj0ro&Z Ummk?jD*ylh07*qoM6N<$f_9Z^X8-^I diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..7eb8b01ad0b1496bf1bb4b5dd9315b6efa05c123 GIT binary patch literal 3312 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict_crystal.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/engineer_derelict_crystal.png new file mode 100644 index 0000000000000000000000000000000000000000..38bae65c83781bb3d7d150b4b4a41b8dd0cd8ba6 GIT binary patch literal 1333 zcmV-51IUqbT` zs99@;EsY?g5CkP6Dk8h1$SS2mAPF>(hfrc$apOa=_)u^qWSa+5(D)!2D@AJ%r4)$^ zMbPedhhv6uHuJZ;Nyt4gOeTBp`Of+7ojdoOa{(=y0nLDBKr^5j&lFy6+U4GgLM;#Ff1U(LL@t+uOh*z_@sTJKJvCwV zh|{8HN5-6jk@f!G#jth+?H_mz5J0X2_uh)A$HV84lEpEoLAqa+8L0Du$M?BzL;aQE zO$EdoftEGEwq0pNqfv~Hk9$$EWZSsD0uYdbrJmXAd1>`{TLV+Ku1T%qWk|vBB6GFoQ=Hfi*hIf<$G^cLJ3l_O>gnl0I&Cg^;=DZbw@M2!co9EQ9Bn!( z&(*-Mw11)XlZ58xW+anIwHCCuw=1$LG8-2A6$s6iR`4<$A>ojovZ>Uc&W#UR+VKy{0Ae+rD2*B5ZxdMt) zt{^l41o-ifdgD_6I<&R5VS0KRo1bMB0hCYA_#=R=C98992u6_pc0}qc6`YkMAV_w_ zzpLSUa9!d|n4O(fcPshtbeDEqkR1t-w3nBVmIhF);GFv0GBY&h^y73EK))$8+1ags z1NgAlj5e>SfeRIW>95 z{N?lFs7F@aRm1>~mO2O8KFxq;Kr^5j&Gy|G}70E#0a99E+20M(iozl?~_ymb8 z+2@BFZyR5Kbl)-6P2F}If{dUq0_=w)n6Rk%W?@)KaQHpA;I-fL?~BpqCDR6pKK)?% zBEZSji+h0$4ZzP=&5BVx9>?!}ag`8>pEggE1P!nxo0B^PgMk(cv8+bDdM%AFH=EYH ze>BLr&-d|M87c+CRMnkg!1wW5D8pzV4W+?!o)V;5BYmjD?mV%GNz%1w1~dbj0nLDB zpo$Dgm6qRVsnoJsEQb`tlyVg(?Rxl3EMl@SDrXp2IhGWC73o+3P-ImOA&_OM(aY#B zHU%;ZXph)uwb{)+*Td2+EiIUsm{58Og@U?&wL58~kBz2cu^0yW2Gw?VX!xMf*jPM5 zRun0c^6#*f8|$=Y0hTf|GlT9u->Rz9*>kbt8R0>sPb7^(;hz`&(q`Ho7T=A)W&gWt zFl61wGX#}l}5!iF8Y z5(evq9C1JRj<0}(qE3;VOeqOD*>-Yr5=~7_%1^G&C5j?o~U&cx~wf_jS=jH rw9p6f#~n?#&Gy|G}mBqmSk&P8Qc5a{100000NkvXXu0mjfSOj*g literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..34ae031b79e357742b9db86daf00bac2307c8162 GIT binary patch literal 4522 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 BW0U{@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_moving_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/janitor_moving_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6b1bc61e3578c18eacb454847dc85d28429177 GIT binary patch literal 5502 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 E4|=BMHus^a;Qb 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/medical_moving_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/medical_moving_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..4054df618449b4715e3bc16f0d2844d4097c7fcf GIT binary patch literal 4378 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 qUPY_5V!^KvoH+Z7Zsz8I99UY0I4?7snVUMh?L literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json b/Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json index 4e56b98d3e..45aa679ee2 100644 --- a/Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json +++ b/Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json @@ -1,659 +1,791 @@ { - "version": 1, - "size": { - "x": 32, - "y": 32 - }, - "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/faf6db214927874c19b8fa8585d26b5d40de1acc, derelict sprites modified by GoldenCan(GitHub), xenoborg sprites, created and modified by Samuka-C (github).", - "states": [ - { - "name": "clown", - "directions": 4 + "version": 1, + "size": { + "x": 32, + "y": 32 }, - { - "name": "clown_e", - "directions": 4 - }, - { - "name": "clown_e_r", - "directions": 4 - }, - { - "name": "clown_l", - "directions": 4 - }, - { - "name": "derelict", - "directions": 4 - }, - { - "name": "derelict_e", - "directions": 4 - }, - { - "name": "derelict_e_r", - "directions": 4 - }, - { - "name": "derelict_icon", - "directions": 1 - }, - { - "name": "derelict_l", - "directions": 4 - }, - { - "name": "engineer", - "directions": 4 - }, - { - "name": "engineer_e", - "directions": 4 - }, - { - "name": "engineer_e_r", - "directions": 4 - }, - { - "name": "engineer_l", - "directions": 4 - }, - { - "name": "janitor", - "directions": 4 - }, - { - "name": "janitor_moving", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "janitor_e", - "directions": 4 - }, - { - "name": "janitor_e_r", - "directions": 4 - }, - { - "name": "janitor_l", - "directions": 4 - }, - { - "name": "medical", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "medical_moving", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "medical_e", - "directions": 4 - }, - { - "name": "medical_e_r", - "directions": 4 - }, - { - "name": "medical_l", - "directions": 4 - }, - { - "name": "miner", - "directions": 4 - }, - { - "name": "miner_moving", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ], - [ - 0.1, - 0.1 - ] - ] - }, - { - "name": "miner_e", - "directions": 4 - }, - { - "name": "miner_e_r", - "directions": 4 - }, - { - "name": "miner_l", - "directions": 4 - }, - { - "name": "robot", - "directions": 4 - }, - { - "name": "robot_e", - "directions": 4 - }, - { - "name": "robot_e_r", - "directions": 4 - }, - { - "name": "robot_l", - "directions": 4 - }, - { - "name": "peace", - "directions": 4 - }, - { - "name": "peace_e", - "directions": 4 - }, - { - "name": "peace_e_r", - "directions": 4 - }, - { - "name": "peace_l", - "directions": 4 - }, - { - "name": "service", - "directions": 4 - }, - { - "name": "service_e", - "directions": 4 - }, - { - "name": "service_e_r", - "directions": 4 - }, - { - "name": "service_l", - "directions": 4 - }, - { - "name": "synd_sec", - "directions": 4 - }, - { - "name": "synd_sec_e", - "directions": 4 - }, - { - "name": "synd_sec_l", - "directions": 4 - }, - { - "name": "synd_medical", - "directions": 4 - }, - { - "name": "synd_medical_l", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "synd_medical_e", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "synd_engi", - "directions": 4 - }, - { - "name": "synd_engi_e", - "directions": 4 - }, - { - "name": "synd_engi_l", - "directions": 4 - }, - { - "name": "xenoborg_heavy", - "directions": 4 - }, - { - "name": "xenoborg_heavy_e", - "directions": 4 - }, - { - "name": "xenoborg_heavy_e_r", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "xenoborg_heavy_l", - "directions": 4 - }, - { - "name": "xenoborg_scout", - "directions": 4 - }, - { - "name": "xenoborg_scout_l", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "xenoborg_scout_e", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "xenoborg_scout_e_r", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "xenoborg_engi", - "directions": 4 - }, - { - "name": "xenoborg_engi_e", - "directions": 4 - }, - { - "name": "xenoborg_engi_e_r", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "xenoborg_engi_l", - "directions": 4 - }, - { - "name": "xenoborg_stealth", - "directions": 4 - }, - { - "name": "xenoborg_stealth_e", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - }, - { - "name": "xenoborg_stealth_e_r", - "directions": 4, - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ], - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "xenoborg_stealth_l", - "directions": 4, - "delays": [ - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ], - [ - 0.1, - 0.2, - 0.1 - ] - ] - } - ] + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/faf6db214927874c19b8fa8585d26b5d40de1acc, derelict generic sprites modified by GoldenCan(GitHub), xenoborg sprites, created and modified by Samuka-C (github). Derelict Engineer, Janitor, Miner, Medical, and Assault Borg sprites by _miket on Discord.", + "states": [ + { + "name": "clown", + "directions": 4 + }, + { + "name": "clown_e", + "directions": 4 + }, + { + "name": "clown_e_r", + "directions": 4 + }, + { + "name": "clown_l", + "directions": 4 + }, + { + "name": "derelict", + "directions": 4 + }, + { + "name": "derelict_e", + "directions": 4 + }, + { + "name": "derelict_e_r", + "directions": 4 + }, + { + "name": "derelict_icon", + "directions": 1 + }, + { + "name": "derelict_l", + "directions": 4 + }, + { + "name": "engineer", + "directions": 4 + }, + { + "name": "engineer_e", + "directions": 4 + }, + { + "name": "engineer_e_r", + "directions": 4 + }, + { + "name": "engineer_l", + "directions": 4 + }, + { + "name": "engineer_derelict", + "directions": 4 + }, + { + "name": "engineer_derelict_crystal", + "directions": 4 + }, + { + "name": "janitor", + "directions": 4 + }, + { + "name": "janitor_moving", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "janitor_e", + "directions": 4 + }, + { + "name": "janitor_e_r", + "directions": 4 + }, + { + "name": "janitor_l", + "directions": 4 + }, + { + "name": "janitor_derelict", + "directions": 4 + }, + { + "name": "janitor_moving_derelict", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "medical", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "medical_moving", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "medical_e", + "directions": 4 + }, + { + "name": "medical_e_r", + "directions": 4 + }, + { + "name": "medical_l", + "directions": 4 + }, + { + "name": "medical_derelict", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "medical_moving_derelict", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "miner", + "directions": 4 + }, + { + "name": "miner_moving", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + }, + { + "name": "miner_e", + "directions": 4 + }, + { + "name": "miner_e_r", + "directions": 4 + }, + { + "name": "miner_l", + "directions": 4 + }, + { + "name": "miner_derelict", + "directions": 4 + }, + { + "name": "miner_moving_derelict", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + }, + { + "name": "robot", + "directions": 4 + }, + { + "name": "robot_e", + "directions": 4 + }, + { + "name": "robot_e_r", + "directions": 4 + }, + { + "name": "robot_l", + "directions": 4 + }, + { + "name": "peace", + "directions": 4 + }, + { + "name": "peace_e", + "directions": 4 + }, + { + "name": "peace_e_r", + "directions": 4 + }, + { + "name": "peace_l", + "directions": 4 + }, + { + "name": "service", + "directions": 4 + }, + { + "name": "service_e", + "directions": 4 + }, + { + "name": "service_e_r", + "directions": 4 + }, + { + "name": "service_l", + "directions": 4 + }, + { + "name": "synd_sec", + "directions": 4 + }, + { + "name": "synd_sec_e", + "directions": 4 + }, + { + "name": "synd_sec_l", + "directions": 4 + }, + { + "name": "synd_sec_derelict", + "directions": 4 + }, + { + "name": "synd_sec_derelict_e", + "directions": 4 + }, + { + "name": "synd_sec_derelict_l", + "directions": 4 + }, + { + "name": "synd_medical", + "directions": 4 + }, + { + "name": "synd_medical_l", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "synd_medical_e", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "synd_engi", + "directions": 4 + }, + { + "name": "synd_engi_e", + "directions": 4 + }, + { + "name": "synd_engi_l", + "directions": 4 + }, + { + "name": "xenoborg_heavy", + "directions": 4 + }, + { + "name": "xenoborg_heavy_e", + "directions": 4 + }, + { + "name": "xenoborg_heavy_e_r", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "xenoborg_heavy_l", + "directions": 4 + }, + { + "name": "xenoborg_scout", + "directions": 4 + }, + { + "name": "xenoborg_scout_l", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "xenoborg_scout_e", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "xenoborg_scout_e_r", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "xenoborg_engi", + "directions": 4 + }, + { + "name": "xenoborg_engi_e", + "directions": 4 + }, + { + "name": "xenoborg_engi_e_r", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "xenoborg_engi_l", + "directions": 4 + }, + { + "name": "xenoborg_stealth", + "directions": 4 + }, + { + "name": "xenoborg_stealth_e", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + }, + { + "name": "xenoborg_stealth_e_r", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "xenoborg_stealth_l", + "directions": 4, + "delays": [ + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ], + [ + 0.1, + 0.2, + 0.1 + ] + ] + } + ] } diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/miner_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/miner_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..d9d812c761186f3e217ba7a19fc7c7ddede660fc GIT binary patch literal 3494 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 H;TH2R&3aVN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/miner_moving_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/miner_moving_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..05cd74494b9ed619710539db47e03e6a388e5c83 GIT binary patch literal 4363 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 T90L|9M-5uvOt19P&8YtXxM4K{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict.png new file mode 100644 index 0000000000000000000000000000000000000000..9b42b90f6edcbd77339c7684d220c80215e36365 GIT binary patch literal 3707 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 E3!Af#;Q#;t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_e.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_e.png new file mode 100644 index 0000000000000000000000000000000000000000..a846febc061e5d2212d831c5ed154a6d26148867 GIT binary patch literal 824 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBuf-vKbiP>*~8rm~MB1$5BeXNr6bM+Ea@{>~aDsl^esu>t; z>?;Zqle1Gx6p~WYGxKcK-|yb9u8^5xs~&FZYv5bpoSKp8QB{;0T;&&%T$P<{nWAoQ z$IE3?VFffHH?<^Dp&~aYuh^=>Rtapd6_5=Q)>pE#DN0GR3UYCSssQqAl`=|73as?? z%gf94%8m8%i_-NCEiEne4UF`SjC6r2bc-wVN)jt{^NN+B2DqdaCl_TFlw{`TDS!-2 zOv*1Uu~jN9%}lXMOH4CON=Y%*O-eLQ(KR$oNz_eDF*ejqF*Z&yH#M{{N;6DSf?8ja znTD`GuNWE(zyQ$)$>>wgQzXDnC zkO2h~Jakj@fI(Ug3_G1EGq{0KqTuP`7*Y}U_LgJTVFLk&iz~y^q6`j}Vq0O!sR1hjX<;(u5CK(5MRHSt}f${esJ#<>s_WP2$ z+ug4FuG@C%~j0kDc!feZ;O8SzB{&=ijI6?yH1-TYr3VM+cBT9lO8q_z%nA z)nfe5nRdU8Y&nzWaW3B{v|)j$K^pfD%Z*Z@4E1Kma~SQ@vsQ0Eyz@YwbTP-wvlC<( zwyS?DKe*!j1Kr=>L1_&H1eO^`ZEL+2I_;L)^^^Zu%y-_>^3ILUcq@OzE!D#G+v9rE zIZnR|k0k9dHux^KqeNU$D|g}77}gB#wSO%b7#^;BRCV+6?*; v)ZxiK#@?4z(-*n^5&&}fQX@Rme0>?TfNTyR27yb#lR=cHtDnm{r-UW|27)X3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_l.png b/Resources/Textures/Mobs/Silicon/chassis.rsi/synd_sec_derelict_l.png new file mode 100644 index 0000000000000000000000000000000000000000..b479c411a7a39f04873c99344af18197598f3573 GIT binary patch literal 924 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBufiR<}hF1enLwjaOL`j6Nk5zJhu3lnFep0GlMQ#C5H3Nf< zeMLcHa&~HoLQ-maW}dD3``!E16*5z7)x%AF4SWlnQ!_F>s)|yBtNcQetFn_VQ`GJ4 zc)4sUtbiuurj{fsROII56ON0GHI_ zN%^HEwo0X?nJHFjiD{-uDJiD9Nr}cOx`u`+iMoj?#)i5n#>Oe;riK zGN53Bhi+;fFi6XRVW%@?1~)KDT0C7GLn`9l-ZIQPWFT_vW4)1DiPIaw?DrQYF7+1Y zJ17{Ce&m{IdqQH`8(FKS8`^EFa^3E*h9?A0Ij~vb>i63P4^EoBKN%S3;Ns$PZll(w zgR4%kJ*=3m^3XxH?qc+DV~1G=j4#%&cKvZTIy{?s+1)d}=AoN_%Eaa|6x=z#uYy6M ztU~o6uR?2OeXQ=OxOZ;v?{9q+A1uWuV|*`!b9cQ(Yh}gV&)w`9haY9mV*FP;S17}q z&16=>WFd~as?Awb4{VujDK*XE=IPjqzhb7R7}oo7{?WE$c3S?9`PL*xrBCMFR@*uX zO;11ibTax#$IBgZyTS5s6l1}_7JX<&az^XtY0p literal 0 HcmV?d00001 From 958a98814aaac320a96bc78721e8cb8dcbd3e2e1 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 23 Aug 2025 20:33:25 +0000 Subject: [PATCH 02/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 83363a83bc..2e96853d46 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Tweak mob collision values in line with RMC14. - type: Tweak - id: 8367 - time: '2025-04-27T14:47:18.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/36851 - author: Fildrance changes: - message: node scanner now dislplays live artifact info (while in range) after @@ -3948,3 +3941,11 @@ id: 8879 time: '2025-08-22T22:26:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/39834 +- author: _miket, RedBookcase + changes: + - message: Added new Derelict Cyborg ghost roles, including the Derelict Engineer, + Janitor, Salvage, Medical, and Assault Cyborg! + type: Add + id: 8880 + time: '2025-08-23T20:32:15.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/38159 From 7429f56bd16cd7ec99a8ade96270fc18c62d8fbe Mon Sep 17 00:00:00 2001 From: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:02:41 -0400 Subject: [PATCH 03/16] Fix "multiple keys" issue in Textures/Objects/Specific/Medical.rsi (#39861) Update meta.json --- .../Textures/Objects/Specific/Medical/medical.rsi/meta.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json b/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json index 5c32c08d7d..6fb3857023 100644 --- a/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json @@ -1,9 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/740ff31a81313086cf16761f3677cf1e2ab46c93 and Taken from tgstation at https://github.com/tgstation/tgstation/blob/623290915c2292b56da11048deb62d758e1e3fb4/icons/obj/bloodpack.dmi, Blood pack redone by Ubaser", - "copyright": "Taken from https://github.com/tgstation/tgstation/blob/a3568da5634e756d0849480104afda402c6f1c3c/icons/obj/medical/stack_medical.dmi", - "copyright": "Tourniquet Sprite by PoorMansDreams, in-hand sprites of tourniquet, gauze, and bloodpack made by SeamLesss (github)", + "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/740ff31a81313086cf16761f3677cf1e2ab46c93 and Taken from tgstation at https://github.com/tgstation/tgstation/blob/623290915c2292b56da11048deb62d758e1e3fb4/icons/obj/bloodpack.dmi, Blood pack redone by Ubaser. Taken from https://github.com/tgstation/tgstation/blob/a3568da5634e756d0849480104afda402c6f1c3c/icons/obj/medical/stack_medical.dmi. Tourniquet Sprite by PoorMansDreams, in-hand sprites of tourniquet, gauze, and bloodpack made by SeamLesss (github).", "size": { "x": 32, "y": 32 From ed7bea8e019e947b54499b2ba0964a5a622ad2e2 Mon Sep 17 00:00:00 2001 From: FungiFellow <151778459+FungiFellow@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:15:28 -0400 Subject: [PATCH 04/16] Inflatable Module (#35100) Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Co-authored-by: PJB3005 --- .../Engineering/InflatablesDeflateTest.cs | 20 ++++ .../Interaction/InteractionTest.Constants.cs | 8 ++ .../Melee/Balloon/BalloonPopperSystem.cs | 1 + .../InflatableSafeDisassemblyComponent.cs | 14 +++ .../Systems/DisassembleOnAltVerbSystem.cs | 20 ++-- .../InflatableSafeDisassemblySystem.cs | 39 ++++++++ .../Melee/Balloon/BalloonPopperComponent.cs | 2 +- .../Locale/en-US/engineering/inflatables.ftl | 1 + .../Locale/en-US/robotics/borg_modules.ftl | 2 + .../Entities/Objects/Misc/inflatable_wall.yml | 2 + .../Specific/Robotics/borg_modules.yml | 30 ++++++ .../Objects/Tools/inflatable_wall.yml | 90 ++++++++++-------- .../Recipes/Lathes/Packs/robotics.yml | 1 + .../Recipes/Lathes/robot_modules.yml | 5 + Resources/Prototypes/borg_types.yml | 1 + Resources/Prototypes/tags.yml | 3 + .../actions_borg.rsi/inflatable-module.png | Bin 0 -> 5579 bytes .../Actions/actions_borg.rsi/meta.json | 5 +- .../borgmodule.rsi/icon-inflatable.png | Bin 0 -> 4594 bytes .../Robotics/borgmodule.rsi/meta.json | 6 +- 20 files changed, 199 insertions(+), 51 deletions(-) create mode 100644 Content.IntegrationTests/Tests/Engineering/InflatablesDeflateTest.cs create mode 100644 Content.Shared/Engineering/Components/InflatableSafeDisassemblyComponent.cs create mode 100644 Content.Shared/Engineering/Systems/InflatableSafeDisassemblySystem.cs rename {Content.Server => Content.Shared}/Weapons/Melee/Balloon/BalloonPopperComponent.cs (94%) create mode 100644 Resources/Locale/en-US/engineering/inflatables.ftl create mode 100644 Resources/Textures/Interface/Actions/actions_borg.rsi/inflatable-module.png create mode 100644 Resources/Textures/Objects/Specific/Robotics/borgmodule.rsi/icon-inflatable.png diff --git a/Content.IntegrationTests/Tests/Engineering/InflatablesDeflateTest.cs b/Content.IntegrationTests/Tests/Engineering/InflatablesDeflateTest.cs new file mode 100644 index 0000000000..a7203d9259 --- /dev/null +++ b/Content.IntegrationTests/Tests/Engineering/InflatablesDeflateTest.cs @@ -0,0 +1,20 @@ +using Content.IntegrationTests.Tests.Interaction; +using Content.Shared.Engineering.Systems; + +namespace Content.IntegrationTests.Tests.Engineering; + +[TestFixture] +[TestOf(typeof(InflatableSafeDisassemblySystem))] +public sealed class InflatablesDeflateTest : InteractionTest +{ + [Test] + public async Task Test() + { + await SpawnTarget(InflatableWall); + + await InteractUsing(Needle); + + AssertDeleted(); + await AssertEntityLookup(new EntitySpecifier(InflatableWallStack.Id, 1)); + } +} diff --git a/Content.IntegrationTests/Tests/Interaction/InteractionTest.Constants.cs b/Content.IntegrationTests/Tests/Interaction/InteractionTest.Constants.cs index 5db5d91d0d..8917ba7ead 100644 --- a/Content.IntegrationTests/Tests/Interaction/InteractionTest.Constants.cs +++ b/Content.IntegrationTests/Tests/Interaction/InteractionTest.Constants.cs @@ -1,3 +1,6 @@ +using Content.Shared.Stacks; +using Robust.Shared.Prototypes; + namespace Content.IntegrationTests.Tests.Interaction; // This partial class contains various constant prototype IDs common to interaction tests. @@ -32,4 +35,9 @@ public abstract partial class InteractionTest protected const string Manipulator1 = "MicroManipulatorStockPart"; protected const string Battery1 = "PowerCellSmall"; protected const string Battery4 = "PowerCellHyper"; + + // Inflatables & Needle used to pop them + protected static readonly EntProtoId InflatableWall = "InflatableWall"; + protected static readonly EntProtoId Needle = "WeaponMeleeNeedle"; + protected static readonly ProtoId InflatableWallStack = "InflatableWall"; } diff --git a/Content.Server/Weapons/Melee/Balloon/BalloonPopperSystem.cs b/Content.Server/Weapons/Melee/Balloon/BalloonPopperSystem.cs index a8460a8c66..d4ab81ae10 100644 --- a/Content.Server/Weapons/Melee/Balloon/BalloonPopperSystem.cs +++ b/Content.Server/Weapons/Melee/Balloon/BalloonPopperSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Popups; using Content.Shared.Tag; using Content.Shared.Weapons.Melee.Events; using Content.Shared.Throwing; +using Content.Shared.Weapons.Melee.Balloon; using Robust.Shared.Audio.Systems; namespace Content.Server.Weapons.Melee.Balloon; diff --git a/Content.Shared/Engineering/Components/InflatableSafeDisassemblyComponent.cs b/Content.Shared/Engineering/Components/InflatableSafeDisassemblyComponent.cs new file mode 100644 index 0000000000..47591b6eb9 --- /dev/null +++ b/Content.Shared/Engineering/Components/InflatableSafeDisassemblyComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.Engineering.Systems; +using Content.Shared.Weapons.Melee.Balloon; + +namespace Content.Shared.Engineering.Components; + +/// +/// Implements logic to allow inflatable objects to be safely deflated by items. +/// +/// +/// The owning entity must have to implement the logic. +/// +/// +[RegisterComponent] +public sealed partial class InflatableSafeDisassemblyComponent : Component; diff --git a/Content.Shared/Engineering/Systems/DisassembleOnAltVerbSystem.cs b/Content.Shared/Engineering/Systems/DisassembleOnAltVerbSystem.cs index 150688d3d4..0c2e5398fc 100644 --- a/Content.Shared/Engineering/Systems/DisassembleOnAltVerbSystem.cs +++ b/Content.Shared/Engineering/Systems/DisassembleOnAltVerbSystem.cs @@ -19,14 +19,12 @@ public sealed partial class DisassembleOnAltVerbSystem : EntitySystem SubscribeLocalEvent>(AddDisassembleVerb); SubscribeLocalEvent(OnDisassembleDoAfter); } - private void AddDisassembleVerb(Entity entity, ref GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess || args.Hands == null) - return; + public void StartDisassembly(Entity entity, EntityUid user) + { // Doafter setup var doAfterArgs = new DoAfterArgs(EntityManager, - args.User, + user, entity.Comp.DisassembleTime, new DisassembleDoAfterEvent(), entity, @@ -35,12 +33,22 @@ public sealed partial class DisassembleOnAltVerbSystem : EntitySystem BreakOnMove = true, }; + _doAfter.TryStartDoAfter(doAfterArgs); + } + + private void AddDisassembleVerb(Entity entity, ref GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess || args.Hands == null) + return; + + var user = args.User; + // Actual verb stuff AlternativeVerb verb = new() { Act = () => { - _doAfter.TryStartDoAfter(doAfterArgs); + StartDisassembly(entity, user); }, Text = Loc.GetString("disassemble-system-verb-disassemble"), Priority = 2 diff --git a/Content.Shared/Engineering/Systems/InflatableSafeDisassemblySystem.cs b/Content.Shared/Engineering/Systems/InflatableSafeDisassemblySystem.cs new file mode 100644 index 0000000000..7852036330 --- /dev/null +++ b/Content.Shared/Engineering/Systems/InflatableSafeDisassemblySystem.cs @@ -0,0 +1,39 @@ +using Content.Shared.Engineering.Components; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Weapons.Melee.Balloon; + +namespace Content.Shared.Engineering.Systems; + +/// +/// Implements +/// +public sealed class InflatableSafeDisassemblySystem : EntitySystem +{ + [Dependency] private readonly DisassembleOnAltVerbSystem _disassembleOnAltVerbSystem = null!; + [Dependency] private readonly SharedPopupSystem _popupSystem = null!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(InteractHandler); + } + + private void InteractHandler(Entity ent, ref InteractUsingEvent args) + { + if (args.Handled) + return; + + if (!HasComp(args.Used)) + return; + + _popupSystem.PopupPredicted( + Loc.GetString("inflatable-safe-disassembly", ("item", args.Used), ("target", ent.Owner)), + ent, + args.User); + + _disassembleOnAltVerbSystem.StartDisassembly((ent, Comp(ent)), args.User); + args.Handled = true; + } +} diff --git a/Content.Server/Weapons/Melee/Balloon/BalloonPopperComponent.cs b/Content.Shared/Weapons/Melee/Balloon/BalloonPopperComponent.cs similarity index 94% rename from Content.Server/Weapons/Melee/Balloon/BalloonPopperComponent.cs rename to Content.Shared/Weapons/Melee/Balloon/BalloonPopperComponent.cs index e7f318d61c..7e90b2b4ea 100644 --- a/Content.Server/Weapons/Melee/Balloon/BalloonPopperComponent.cs +++ b/Content.Shared/Weapons/Melee/Balloon/BalloonPopperComponent.cs @@ -2,7 +2,7 @@ using Robust.Shared.Audio; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -namespace Content.Server.Weapons.Melee.Balloon; +namespace Content.Shared.Weapons.Melee.Balloon; /// /// This is used for weapons that pop balloons on attack. diff --git a/Resources/Locale/en-US/engineering/inflatables.ftl b/Resources/Locale/en-US/engineering/inflatables.ftl new file mode 100644 index 0000000000..0c4a2d44c0 --- /dev/null +++ b/Resources/Locale/en-US/engineering/inflatables.ftl @@ -0,0 +1 @@ +inflatable-safe-disassembly = You expertly use { THE($item) } to open the valve on { THE($target) }, and start deflating { OBJECT($target) } without causing damage. diff --git a/Resources/Locale/en-US/robotics/borg_modules.ftl b/Resources/Locale/en-US/robotics/borg_modules.ftl index b6c55447e7..ba5ee602a5 100644 --- a/Resources/Locale/en-US/robotics/borg_modules.ftl +++ b/Resources/Locale/en-US/robotics/borg_modules.ftl @@ -10,3 +10,5 @@ borg-slot-documents-empty = Books and papers borg-slot-soap-empty = Soap borg-slot-instruments-empty = Instruments borg-slot-beakers-empty = Beakers +borg-slot-inflatable-door-empty = Inflatable Door +borg-slot-inflatable-wall-empty = Inflatable Wall diff --git a/Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml b/Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml index 0641084847..577ab1dddd 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/inflatable_wall.yml @@ -33,6 +33,7 @@ - type: DisassembleOnAltVerb prototypeToSpawn: InflatableWallStack1 disassembleTime: 3 + - type: InflatableSafeDisassembly - type: Airtight - type: Transform anchored: true @@ -81,5 +82,6 @@ - type: DisassembleOnAltVerb prototypeToSpawn: InflatableDoorStack1 disassembleTime: 3 + - type: InflatableSafeDisassembly - type: Occluder enabled: false diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 2a971d71ea..675d9efa70 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -489,6 +489,36 @@ - type: BorgModuleIcon icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module } +- type: entity + id: BorgModuleInflatable + parent: [ BaseBorgModule, BaseProviderBorgModule ] + name: inflatable cyborg module + components: + - type: Sprite + layers: + - state: generic + - state: icon-inflatable + - type: ItemBorgModule + hands: + - item: InflatableDoorStack + hand: + emptyRepresentative: InflatableDoorStack + emptyLabel: borg-slot-inflatable-door-empty + whitelist: + tags: + - Inflatable + - item: InflatableWallStack + hand: + emptyRepresentative: InflatableWallStack + emptyLabel: borg-slot-inflatable-wall-empty + whitelist: + tags: + - Inflatable + - item: BoxInflatable + - item: WeaponMeleeNeedle + - type: BorgModuleIcon + icon: { sprite: Interface/Actions/actions_borg.rsi, state: inflatable-module } + # cargo modules - type: entity id: BorgModuleAppraisal diff --git a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml index f5e05b4e28..4f55d5c164 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/inflatable_wall.yml @@ -5,21 +5,24 @@ description: A folded membrane which rapidly expands into a large cubical shape on activation. suffix: Full components: - - type: Stack - stackType: InflatableWall - count: 10 - - type: Sprite - sprite: Objects/Misc/inflatable_wall.rsi - state: item_wall - - type: Item - sprite: Objects/Misc/inflatable_wall.rsi - size: Small - - type: SpawnAfterInteract - prototype: InflatableWall - doAfter: 1 - removeOnInteract: true - - type: Clickable - - type: PhysicalComposition + - type: Stack + stackType: InflatableWall + count: 10 + - type: Sprite + sprite: Objects/Misc/inflatable_wall.rsi + state: item_wall + - type: Item + sprite: Objects/Misc/inflatable_wall.rsi + size: Small + - type: SpawnAfterInteract + prototype: InflatableWall + doAfter: 1 + removeOnInteract: true + - type: Clickable + - type: PhysicalComposition + - type: Tag + tags: + - Inflatable # TODO: Add stack sprites + visuals. - type: entity @@ -29,21 +32,24 @@ description: A folded membrane which rapidly expands into a large cubical shape on activation. suffix: Full components: - - type: Stack - stackType: InflatableDoor - count: 4 - - type: Sprite - sprite: Objects/Misc/inflatable_door.rsi - state: item_door - - type: Item - sprite: Objects/Misc/inflatable_door.rsi - size: Small - - type: SpawnAfterInteract - prototype: InflatableDoor - doAfter: 1 - removeOnInteract: true - - type: Clickable - - type: PhysicalComposition + - type: Stack + stackType: InflatableDoor + count: 4 + - type: Sprite + sprite: Objects/Misc/inflatable_door.rsi + state: item_door + - type: Item + sprite: Objects/Misc/inflatable_door.rsi + size: Small + - type: SpawnAfterInteract + prototype: InflatableDoor + doAfter: 1 + removeOnInteract: true + - type: Clickable + - type: PhysicalComposition + - type: Tag + tags: + - Inflatable # TODO: Add stack sprites + visuals. - type: entity @@ -51,27 +57,27 @@ id: InflatableWallStack5 suffix: 5 components: - - type: Sprite - state: item_wall - - type: Stack - count: 5 + - type: Sprite + state: item_wall + - type: Stack + count: 5 - type: entity parent: InflatableWallStack id: InflatableWallStack1 suffix: 1 components: - - type: Sprite - state: item_wall - - type: Stack - count: 1 + - type: Sprite + state: item_wall + - type: Stack + count: 1 - type: entity parent: InflatableDoorStack id: InflatableDoorStack1 suffix: 1 components: - - type: Sprite - state: item_door - - type: Stack - count: 1 + - type: Sprite + state: item_door + - type: Stack + count: 1 diff --git a/Resources/Prototypes/Recipes/Lathes/Packs/robotics.yml b/Resources/Prototypes/Recipes/Lathes/Packs/robotics.yml index f22cde9c52..2db59977be 100644 --- a/Resources/Prototypes/Recipes/Lathes/Packs/robotics.yml +++ b/Resources/Prototypes/Recipes/Lathes/Packs/robotics.yml @@ -14,6 +14,7 @@ - BorgModuleTool - BorgModuleCable - BorgModuleFireExtinguisher + - BorgModuleInflatable - type: latheRecipePack id: BorgLimbsStatic diff --git a/Resources/Prototypes/Recipes/Lathes/robot_modules.yml b/Resources/Prototypes/Recipes/Lathes/robot_modules.yml index 9210529a1d..9465d7b87a 100644 --- a/Resources/Prototypes/Recipes/Lathes/robot_modules.yml +++ b/Resources/Prototypes/Recipes/Lathes/robot_modules.yml @@ -37,6 +37,11 @@ id: BorgModuleFireExtinguisher result: BorgModuleFireExtinguisher +- type: latheRecipe + parent: BaseBorgModuleRecipe + id: BorgModuleInflatable + result: BorgModuleInflatable + # Cargo Modules - type: latheRecipe diff --git a/Resources/Prototypes/borg_types.yml b/Resources/Prototypes/borg_types.yml index 1c49713e26..1d88af8455 100644 --- a/Resources/Prototypes/borg_types.yml +++ b/Resources/Prototypes/borg_types.yml @@ -14,6 +14,7 @@ defaultModules: - BorgModuleTool + - BorgModuleInflatable - BorgModuleArtifact - BorgModuleAnomaly radioChannels: diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 95b261466f..a9b927cdcf 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -801,6 +801,9 @@ - type: Tag id: Ingot +- type: Tag + id: Inflatable + - type: Tag id: InstantDoAfters diff --git a/Resources/Textures/Interface/Actions/actions_borg.rsi/inflatable-module.png b/Resources/Textures/Interface/Actions/actions_borg.rsi/inflatable-module.png new file mode 100644 index 0000000000000000000000000000000000000000..15e1c86629fb981cbcf5dc39ddfed19bf2efcf6a GIT binary patch literal 5579 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 Date: Sat, 23 Aug 2025 22:16:36 +0000 Subject: [PATCH 05/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2e96853d46..2d81e15d90 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Fildrance - changes: - - message: node scanner now dislplays live artifact info (while in range) after - linking to artifact - type: Tweak - id: 8368 - time: '2025-04-27T15:11:13.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/36635 - author: ArtisticRoomba changes: - message: A new Mapping changelog has been added. You can find it in a different @@ -3949,3 +3941,10 @@ id: 8880 time: '2025-08-23T20:32:15.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/38159 +- author: FungiFellow + changes: + - message: Added the Inflatable Module for borgs. + type: Add + id: 8881 + time: '2025-08-23T22:15:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/35100 From 4c537b7dfa452a7945183ac2b06db6d218107aa1 Mon Sep 17 00:00:00 2001 From: M4rchy-S <89603088+M4rchy-S@users.noreply.github.com> Date: Sun, 24 Aug 2025 01:48:39 +0300 Subject: [PATCH 06/16] Fix electricity for Reagent Grinder at Marathon (#39801) --- Resources/Maps/marathon.yml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Resources/Maps/marathon.yml b/Resources/Maps/marathon.yml index 0b29fe144d..4679e76938 100644 --- a/Resources/Maps/marathon.yml +++ b/Resources/Maps/marathon.yml @@ -1,11 +1,11 @@ meta: format: 7 category: Map - engineVersion: 264.0.0 + engineVersion: 266.0.0 forkId: "" forkVersion: "" - time: 07/22/2025 16:14:30 - entityCount: 23140 + time: 08/21/2025 15:09:09 + entityCount: 23143 maps: - 5350 grids: @@ -22616,6 +22616,21 @@ entities: - type: Transform pos: -25.5,-49.5 parent: 30 + - uid: 10406 + components: + - type: Transform + pos: -50.5,64.5 + parent: 30 + - uid: 10407 + components: + - type: Transform + pos: -50.5,65.5 + parent: 30 + - uid: 10408 + components: + - type: Transform + pos: -50.5,66.5 + parent: 30 - uid: 10444 components: - type: Transform From 8d3bbe2b7868d2e052f0e8621f6210add7e970c3 Mon Sep 17 00:00:00 2001 From: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:49:44 -0400 Subject: [PATCH 07/16] Killed a resolve in ClientAdminManager (#39863) took a resolve out back and shot it --- .../Administration/Managers/ClientAdminManager.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Content.Client/Administration/Managers/ClientAdminManager.cs b/Content.Client/Administration/Managers/ClientAdminManager.cs index 0f740c8104..3f072691de 100644 --- a/Content.Client/Administration/Managers/ClientAdminManager.cs +++ b/Content.Client/Administration/Managers/ClientAdminManager.cs @@ -15,6 +15,7 @@ namespace Content.Client.Administration.Managers [Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IClientNetManager _netMgr = default!; [Dependency] private readonly IClientConGroupController _conGroup = default!; + [Dependency] private readonly IClientConsoleHost _host = default!; [Dependency] private readonly IResourceManager _res = default!; [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IUserInterfaceManager _userInterface = default!; @@ -86,12 +87,12 @@ namespace Content.Client.Administration.Managers private void UpdateMessageRx(MsgUpdateAdminStatus message) { _availableCommands.Clear(); - var host = IoCManager.Resolve(); // Anything marked as Any we'll just add even if the server doesn't know about it. - foreach (var (command, instance) in host.AvailableCommands) + foreach (var (command, instance) in _host.AvailableCommands) { - if (Attribute.GetCustomAttribute(instance.GetType(), typeof(AnyCommandAttribute)) == null) continue; + if (Attribute.GetCustomAttribute(instance.GetType(), typeof(AnyCommandAttribute)) == null) + continue; _availableCommands.Add(command); } From 69bbf3b599f8dee12e3d09f4a3da27e353854a91 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 23 Aug 2025 22:49:47 +0000 Subject: [PATCH 08/16] Automatic changelog update --- Resources/Changelog/Maps.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Resources/Changelog/Maps.yml b/Resources/Changelog/Maps.yml index 0ec3640252..ba943e2221 100644 --- a/Resources/Changelog/Maps.yml +++ b/Resources/Changelog/Maps.yml @@ -551,4 +551,11 @@ id: 67 time: '2025-08-18T18:22:15.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/39091 +- author: M4rchy-S + changes: + - message: On Marathon, fixed the reagent grinder in perma not having power. + type: Fix + id: 68 + time: '2025-08-23T22:48:39.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/39801 Order: 1 From ab681dbcbbc040cb245024c80acf0386e6734146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=81da?= Date: Sat, 23 Aug 2025 18:10:55 -0500 Subject: [PATCH 09/16] GameRuleOnTrigger (#39845) * Gaming * commit --------- Co-authored-by: iaada --- .../Trigger/Systems/GameRuleTriggerSystem.cs | 44 +++++++++++++++++++ .../Effects/AddGameRuleOnTriggerComponent.cs | 26 +++++++++++ 2 files changed, 70 insertions(+) create mode 100644 Content.Server/Trigger/Systems/GameRuleTriggerSystem.cs create mode 100644 Content.Shared/Trigger/Components/Effects/AddGameRuleOnTriggerComponent.cs diff --git a/Content.Server/Trigger/Systems/GameRuleTriggerSystem.cs b/Content.Server/Trigger/Systems/GameRuleTriggerSystem.cs new file mode 100644 index 0000000000..245b9c8408 --- /dev/null +++ b/Content.Server/Trigger/Systems/GameRuleTriggerSystem.cs @@ -0,0 +1,44 @@ +using Content.Server.Administration.Logs; +using Content.Server.GameTicking; +using Content.Shared.Database; +using Content.Shared.Trigger; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Server.Trigger.Systems; + +/// +/// Trigger system for game rules. +/// +public sealed class GameRuleTriggerSystem : EntitySystem +{ + [Dependency] private readonly GameTicker _ticker = default!; + [Dependency] private readonly IAdminLogManager _adminLogger = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(AddRuleOnTrigger); + } + + private void AddRuleOnTrigger(Entity ent, ref TriggerEvent args) + { + if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key)) + return; + + var rule = _ticker.AddGameRule(ent.Comp.GameRule); + + _adminLogger.Add(LogType.EventStarted, + $"{ToPrettyString(args.User):entity} added a game rule [{ent.Comp.GameRule}]" + + $" via a trigger on {ToPrettyString(ent.Owner):entity}."); + + if (ent.Comp.StartRule && _ticker.RunLevel == GameRunLevel.InRound) + { + _ticker.StartGameRule(rule); + _adminLogger.Add(LogType.EventStarted, $"{ToPrettyString(args.User):entity} started game rule [{ent.Comp.GameRule}]."); + } + + args.Handled = true; + } +} diff --git a/Content.Shared/Trigger/Components/Effects/AddGameRuleOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/AddGameRuleOnTriggerComponent.cs new file mode 100644 index 0000000000..474272694c --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/AddGameRuleOnTriggerComponent.cs @@ -0,0 +1,26 @@ +using Content.Shared.GameTicking.Components; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Adds and starts a new game rule on a trigger. +/// The user is always logged alongside the game rule and this entity. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class AddGameRuleOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// The game rule that will be added. Entity requires . + /// + [DataField(required: true), AutoNetworkedField] + public EntProtoId GameRule; + + /// + /// Whether to also start the game rule when adding it. + /// You almost always want this to be true. + /// + [DataField, AutoNetworkedField] + public bool StartRule = true; +} From e8c40f54ce0ce314c55e13f869c86bc7ec8d040e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 24 Aug 2025 02:37:20 +0200 Subject: [PATCH 10/16] Update Credits (#39864) Co-authored-by: PJBot --- Resources/Credits/GitHub.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 7526e5ac03..7c6bca9005 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0leshe, 0tito, 0x6273, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 3nderall, 4310v343k, 4dplanner, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, Ahion, aiden, Aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alex, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, Alpha-Two, AlphaQwerty, Altoids1, amatwiedle, amylizzle, ancientpower, Andre19926, AndrewEyeke, AndreyCamper, Anzarot121, ApolloVector, Appiah, ar4ill, Arcane-Waffle, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, Awlod, azzyisnothere, AzzyIsNotHere, B-Kirill, B3CKDOOR, baa14453, BackeTako, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, BriBrooo, Bright0, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, Centronias, Chaboricks, chairbender, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, crazybrain23, Crazydave91920, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dan, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, DawBla, Daxxi3, dch-GH, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, digitalic, Dimastra, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, ewokswagger, exincore, exp111, f0x-n3rd, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Funce, FungiFellow, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, gituhabu, GlassEclipse, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, Hoshizora, Hreno, Hrosts, htmlsystem, hubismal, Hugal31, Huxellberger, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, jacksonzck, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, JerryImMouse, jerryimmouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, johnku1, Jophire, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, KieueCaprie, Killerqu00, Kimpes, KingFroozy, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit0vras, KittenColony, Kittygyat, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, kosticia, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, Krosus777, Krunklehorn, Kupie, kxvvv, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, lettern, LetterN, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, LightVillet, liltenhead, linkbro1, LinkUyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luizwritescode, Lukasz825700516, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lzimann, lzk228, M1tht1c, M3739, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, MagnusCrowe, maland1, malchanceux, MaloTV, manelnavola, ManelNavola, Mangohydra, marboww, Markek1, marlyn, matt, Matz05, max, MaxNox7, maylokana, MehimoNemo, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, muburu, MureixloI, murolem, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, not-gavnaed, notafet, notquitehadouken, NotSoDana, noudoit, noverd, Nox38, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnyxTheBrave, Orange-Winds, OrangeMoronage9622, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, PGrayCS, pgraycs, Pgriha, Phantom-Lily, pheenty, philingham, Phill101, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, Pissachu, pissdemon, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, PROG-MohamedDwidar, Prole0, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, rosieposieeee, Roudenn, router, ruddygreat, rumaks, RumiTiger, Ruzihm, S1rFl0, S1ss3l, Saakra, Sadie-silly, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, shibechef, Siginanto, SignalWalker, siigiil, silicon14wastaken, Simyon264, sirdragooon, Sirionaut, Sk1tch, SkaldetSkaeg, Skarletto, Skrauz, Skybailey-dev, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, snebl, snicket, sniperchance, Snowni, snowsignal, SolidusSnek, solstar2, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, spacelizard, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, supergdpwyl, superjj18, Supernorn, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telyonok, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheFlyingSentry, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheShuEd, thetolbean, thevinter, TheWaffleJesus, thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, treytipton, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, unusualcrow, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, viceemargo, VigersRay, violet754, Visne, vitusveit, vlad, vlados1408, VMSolidus, vmzd, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, yuriykiss, YuriyKiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex +0leshe, 0tito, 0x6273, 12rabbits, 1337dakota, 13spacemen, 154942, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 3nderall, 4310v343k, 4dplanner, 612git, 778b, 96flo, aaron, abadaba695, Ablankmann, abregado, Absolute-Potato, Absotively, achookh, Acruid, ActiveMammmoth, actually-reb, ada-please, adamsong, Adeinitas, adm2play, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aearo-Deepwater, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, afrokada, AftrLite, AgentSmithRadio, Agoichi, Ahion, aiden, Aidenkrz, Aisu9, ajcm, AJCM-git, AjexRose, Alekshhh, alex, alexalexmax, alexkar598, AlexMorgan3817, alexum418, alexumandxgabriel08x, Alice4267, Alithsko, Alkheemist, alliephante, ALMv1, Alpaccalypse, Alpha-Two, AlphaQwerty, Altoids1, amatwiedle, amylizzle, ancientpower, Andre19926, AndrewEyeke, AndreyCamper, Anzarot121, ApolloVector, Appiah, ar4ill, Arcane-Waffle, archee1, ArchPigeon, ArchRBX, areitpog, Arendian, areyouconfused, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, Artxmisery, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, august-sun, AutoOtter, AverageNotDoingAnythingEnjoyer, avghdev, Awlod, azzyisnothere, AzzyIsNotHere, B-Kirill, B3CKDOOR, baa14453, BackeTako, BadaBoomie, Bakke, BananaFlambe, Baptr0b0t, BarryNorfolk, BasedUser, beck-thompson, beesterman, bellwetherlogic, ben, benbryant0, benev0, benjamin-burges, BGare, bhespiritu, bibbly, BigfootBravo, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, blitzthesquishy, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, Bokser815, bolantej, Booblesnoot42, Boolean-Buckeye, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, BriBrooo, Bright0, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, BWTCK, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, Camdot, capnsockless, CaptainMaru, captainsqrbeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, catdotjs, catlord, Catofquestionableethics, CatTheSystem, Centronias, Chaboricks, chairbender, Chaoticaa, Charlese2, charlie, chartman, ChaseFlorom, chavonadelal, Cheackraze, CheddaCheez, cheesePizza2, CheesePlated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, ciaran, citrea, civilCornball, claustro305, Clement-O, clyf, Clyybber, CMDR-Piboy314, cnv41, coco, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, Compilatron144, CookieMasterT, coolboy911, CoolioDudio, coolmankid12345, Coolsurf6, cooperwallace, corentt, CormosLemming, CrafterKolyan, crazybrain23, Crazydave91920, creadth, CrigCrag, CroilBird, Crotalus, CrudeWax, cryals, CrzyPotato, cubixthree, cutemoongod, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, DamianX, dan, dangerrevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, DawBla, Daxxi3, dch-GH, de0rix, Deahaka, dean, DEATHB4DEFEAT, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, DeepwaterCreations, Deerstop, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, devinschubert14, dexlerxd, dffdff2423, DieselMohawk, digitalic, Dimastra, DinnerCalzone, DinoWattz, Disp-Dev, DisposableCrewmember42, dissidentbullet, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, DR-DOCTOR-EVIL-EVIL, Dragonjspider, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, DuckManZach, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, dylanstrategie, dylanwhittingham, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, Emisse, emmafornash, EmoGarbage404, Endecc, EnrichedCaramel, Entvari, eoineoineoin, ephememory, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, ewokswagger, exincore, exp111, f0x-n3rd, FacePluslll, Fahasor, FairlySadPanda, farrellka-dev, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, firenamefn, Firewars763, FirinMaLazors, Fishfish458, fl-oz, Flareguy, flashgnash, FlipBrooke, FluffiestFloof, FluffMe, FluidRock, flymo5678, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, foxhorn, freeman2651, freeze2222, frobnic8, Froffy025, Fromoriss, froozigiusz, FrostMando, FrostRibbon, Funce, FungiFellow, FunTust, Futuristic-OK, GalacticChimp, gamer3107, Gamewar360, gansulalan, GaussiArson, Gaxeer, gbasood, gcoremans, Geekyhobo, genderGeometries, GeneralGaws, Genkail, Gentleman-Bird, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, gituhabu, GlassEclipse, GnarpGnarp, GNF54, godisdeadLOL, goet, GoldenCan, Goldminermac, Golinth, golubgik, GoodWheatley, Gorox221, gradientvera, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GrownSamoyedDog, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, he1acdvv, Hebi, Helix-ctrl, helm4142, Henry, HerCoyote23, HighTechPuddle, Hitlinemoss, hiucko, hivehum, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, Hoshizora, Hreno, Hrosts, htmlsystem, hubismal, Hugal31, Huxellberger, Hyenh, hyperb1, hyperDelegate, hyphenationc, i-justuser-i, iaada, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imatsoup, IMCB, impubbi, imrenq, imweax, indeano, Injazz, Insineer, insoPL, IntegerTempest, Interrobang01, Intoxicating-Innocence, IProduceWidgets, itsmethom, Itzbenz, iztokbajcar, Jackal298, Jackrost, jacksonzck, Jacktastic09, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jarmer123, Jaskanbe, JasperJRoth, jbox144, JCGWE30, JerryImMouse, jerryimmouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, jkwookee, jmcb, JohnGinnane, johnku1, Jophire, joshepvodka, JpegOfAFrog, jproads, JrInventor05, Jrpl, jukereise, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, JustinWinningham, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, kaiserbirch, KaiShibaa, kalane15, kalanosh, KamTheSythe, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, KieueCaprie, Killerqu00, Kimpes, KingFroozy, kira-er, kiri-yoshikage, Kirillcas, Kirus59, Kistras, Kit0vras, KittenColony, Kittygyat, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, kontakt, kosticia, koteq, kotobdev, Kowlin, KrasnoshchekovPavel, Krosus777, Krunklehorn, Kupie, kxvvv, kyupolaris, kzhanik, LaCumbiaDelCoronavirus, lajolico, Lamrr, lanedon, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leander-0, leonardo-dabepis, leonidussaks, leonsfriedrich, LeoSantich, lettern, LetterN, Level10Cybermancer, LEVELcat, lever1209, LevitatingTree, Lgibb18, lgruthes, LightVillet, liltenhead, linkbro1, LinkUyx, Litraxx, little-meow-meow, LittleBuilderJane, LittleNorthStar, LittleNyanCat, lizelive, ljm862, lmsnoise, localcc, lokachop, lolman360, Lomcastar, LordCarve, LordEclipse, lucas, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luizwritescode, Lukasz825700516, luminight, lunarcomets, Lusatia, Luxeator, lvvova1, Lyndomen, lyroth001, lzimann, lzk228, M1tht1c, M3739, M4rchy-S, M87S, mac6na6na, MACMAN2003, Macoron, magicalus, magmodius, MagnusCrowe, maland1, malchanceux, MaloTV, manelnavola, ManelNavola, Mangohydra, marboww, Markek1, MarkerWicker, marlyn, matt, Matz05, max, MaxNox7, maylokana, MehimoNemo, MeltedPixel, memeproof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, mifia, MilenVolf, MilonPL, Minemoder5000, Minty642, minus1over12, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterImp, MisterMecky, Mith-randalf, Mixelz, mjarduk, MjrLandWhale, mkanke-real, MLGTASTICa, mnva0, moderatelyaware, modern-nm, mokiros, momo, Moneyl, monotheonist, Moomoobeef, moony, Morb0, MossyGreySlope, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, muburu, MureixloI, murolem, musicmanvr, MWKane, Myakot, Myctai, N3X15, nabegator, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikitosych, nikthechampiongr, Nimfar11, ninruB, Nirnael, NIXC, nkokic, NkoKirkto, nmajask, noctyrnal, noelkathegod, noirogen, nok-ko, NonchalantNoob, NoobyLegion, Nopey, not-gavnaed, notafet, notquitehadouken, NotSoDana, noudoit, noverd, Nox38, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, Nyxilath, och-och, OctoRocket, OldDanceJacket, OliverOtter, onesch, OneZerooo0, OnyxTheBrave, Orange-Winds, OrangeMoronage9622, Orsoniks, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paige404, paigemaeforrest, pali6, Palladinium, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, pavlockblaine03, peccneck, Peptide90, peptron1, perryprog, PeterFuto, PetMudstone, pewter-wiz, pgraycs, PGrayCS, Pgriha, Phantom-Lily, pheenty, philingham, Phill101, Phooooooooooooooooooooooooooooooosphate, phunnyguy, PicklOH, PilgrimViis, Pill-U, pinkbat5, Piras314, Pireax, Pissachu, pissdemon, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, pok27, poklj, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, PotRoastPiggy, Princess-Cheeseballs, ProfanedBane, PROG-MohamedDwidar, Prole0, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykana, psykzz, PuceTint, pumkin69, PuroSlavKing, PursuitInAshes, Putnam3145, py01, Pyrovi, qrtDaniil, qrwas, Quantum-cross, quatre, QueerNB, QuietlyWhisper, qwerltaz, Radezolid, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, RedBookcase, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, ReeZer2, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, rhsvenson, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, rlebell33, RobbyTheFish, robinthedragon, Rockdtben, Rohesie, rok-povsic, rokudara-sen, rolfero, RomanNovo, rosieposieeee, Roudenn, router, ruddygreat, rumaks, RumiTiger, Ruzihm, S1rFl0, S1ss3l, Saakra, Sadie-silly, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, Samuka-C, SaphireLattice, SapphicOverload, sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, ScholarNZL, schrodinger71, scrato, Scribbles0, scrivoy, scruq445, scuffedjays, ScumbagDog, SeamLesss, Segonist, semensponge, sephtasm, ser1-1y, Serkket, sewerpig, SG6732, sh18rw, Shaddap1, ShadeAware, ShadowCommander, shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SharkSnake98, shibechef, Siginanto, SignalWalker, siigiil, silicon14wastaken, Simyon264, sirdragooon, Sirionaut, Sk1tch, SkaldetSkaeg, Skarletto, Skrauz, Skybailey-dev, Skyedra, SlamBamActionman, slarticodefast, Slava0135, sleepyyapril, slimmslamm, Slyfox333, Smugman, snebl, snicket, sniperchance, Snowni, snowsignal, SolidSyn, SolidusSnek, solstar2, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, soupkilove, southbridge-fur, sowelipililimute, Soydium, spacelizard, SpaceLizardSky, SpaceManiac, SpaceRox1244, SpaceyLady, Spangs04, spanky-spanky, Sparlight, spartak, SpartanKadence, spderman3333, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, sporkyz, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, starbuckss14, Stealthbomber16, stellar-novas, stewie523, stomf, Stop-Signs, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, supergdpwyl, superjj18, Supernorn, SweptWasTaken, SyaoranFox, Sybil, SYNCHRONIC, Szunti, t, Tainakov, takemysoult, taonewt, tap, TaralGit, Taran, taurie, Tayrtahn, tday93, teamaki, TeenSarlacc, TekuNut, telyonok, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, Tezzaide, TGODiamond, TGRCdev, tgrkzus, ThatGuyUSA, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, TheBlueYowie, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheFlyingSentry, TheIntoxicatedCat, thekilk, themias, theomund, TheProNoob678, TherapyGoth, ThereDrD0, TheShuEd, thetolbean, thevinter, TheWaffleJesus, thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, TiniestShark, Titian3, tk-a369, tkdrg, tmtmtl30, ToastEnjoyer, Toby222, TokenStyle, Tollhouse, Toly65, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, tornado-technology, TornadoTechnology, tosatur, TotallyLemon, ToxicSonicFan04, Tr1bute, treytipton, trixxedbit, TrixxedHeart, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, tyashley, Tyler-IN, TytosB, Tyzemol, UbaserB, ubis1, UBlueberry, uhbg, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, unusualcrow, Uriende, UristMcDorf, user424242420, Utmanarn, Vaaankas, valentfingerov, valquaint, Varen, Vasilis, VasilisThePikachu, veliebm, Velken, VelonacepsCalyxEggs, veprolet, VerinSenpai, veritable-calamity, Veritius, Vermidia, vero5123, verslebas, vexerot, viceemargo, VigersRay, violet754, Visne, vitusveit, vlad, vlados1408, VMSolidus, vmzd, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, Vortebo, vulppine, wafehling, walksanatora, Warentan, WarMechanic, Watermelon914, weaversam8, wertanchik, whateverusername0, whatston3, widgetbeck, Will-Oliver-Br, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, Wolfkey-SomeoneElseTookMyUsername, wrexbe, wtcwr68, xeri7, xkreksx, xprospero, xRiriq, xsainteer, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, YoungThugSS14, Yousifb26, youtissoum, yunii, yuriykiss, YuriyKiss, zach-hill, Zadeon, Zalycon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, ZeWaka, zHonys, zionnBE, ZNixian, Zokkie, ZoldorfTheWizard, zonespace27, Zylofan, Zymem, zzylex From a8e0001f348d2f4a81ecd9679b5c91452368edab Mon Sep 17 00:00:00 2001 From: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com> Date: Sat, 23 Aug 2025 21:29:55 -0400 Subject: [PATCH 11/16] Cleanup of resolves and usings. (#39865) * commit * commit --- Content.Client/Audio/AmbientSoundSystem.cs | 14 ++++++-------- .../Audio/ContentAudioSystem.AmbientMusic.cs | 6 ++---- Content.Client/NPC/PathfindingSystem.cs | 9 ++++----- .../Radiation/Overlays/RadiationDebugOverlay.cs | 5 +++-- .../Systems/ShuttleSystem.EmergencyConsole.cs | 8 ++++---- Content.Client/Weapons/Ranged/Systems/GunSystem.cs | 6 +++--- .../Weapons/Ranged/Systems/SharedGunSystem.cs | 3 --- 7 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Content.Client/Audio/AmbientSoundSystem.cs b/Content.Client/Audio/AmbientSoundSystem.cs index e6ea94c3a6..9929751b22 100644 --- a/Content.Client/Audio/AmbientSoundSystem.cs +++ b/Content.Client/Audio/AmbientSoundSystem.cs @@ -3,17 +3,13 @@ using Content.Shared.CCVar; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Audio; -using Robust.Shared.Log; using Robust.Shared.Configuration; -using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; using System.Linq; using System.Numerics; -using Robust.Client.GameObjects; -using Robust.Shared.Audio.Effects; using Robust.Shared.Audio.Systems; using Robust.Shared.Player; @@ -31,6 +27,7 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem [Dependency] private readonly SharedTransformSystem _xformSystem = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IOverlayManager _overlayManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -65,18 +62,19 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem get => _overlayEnabled; set { - if (_overlayEnabled == value) return; + if (_overlayEnabled == value) + return; + _overlayEnabled = value; - var overlayManager = IoCManager.Resolve(); if (_overlayEnabled) { _overlay = new AmbientSoundOverlay(EntityManager, this, EntityManager.System()); - overlayManager.AddOverlay(_overlay); + _overlayManager.AddOverlay(_overlay); } else { - overlayManager.RemoveOverlay(_overlay!); + _overlayManager.RemoveOverlay(_overlay!); _overlay = null; } } diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index bf7ab26cba..d82f6b07fb 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -3,11 +3,8 @@ using Content.Client.Gameplay; using Content.Shared.Audio; using Content.Shared.CCVar; using Content.Shared.GameTicking; -using Content.Shared.Random; using Content.Shared.Random.Rules; -using Robust.Client.GameObjects; using Robust.Client.Player; -using Robust.Client.ResourceManagement; using Robust.Client.State; using Robust.Shared.Audio; using Robust.Shared.Audio.Components; @@ -25,6 +22,7 @@ public sealed partial class ContentAudioSystem { [Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -61,7 +59,7 @@ public sealed partial class ContentAudioSystem private void InitializeAmbientMusic() { Subs.CVar(_configManager, CCVars.AmbientMusicVolume, AmbienceCVarChanged, true); - _sawmill = IoCManager.Resolve().GetSawmill("audio.ambience"); + _sawmill = _logManager.GetSawmill("audio.ambience"); // Reset audio _nextAudio = TimeSpan.MaxValue; diff --git a/Content.Client/NPC/PathfindingSystem.cs b/Content.Client/NPC/PathfindingSystem.cs index 0c72a8f99f..dc8fd98433 100644 --- a/Content.Client/NPC/PathfindingSystem.cs +++ b/Content.Client/NPC/PathfindingSystem.cs @@ -20,6 +20,7 @@ namespace Content.Client.NPC [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IInputManager _inputManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IOverlayManager _overlayManager = default!; [Dependency] private readonly IResourceCache _cache = default!; [Dependency] private readonly NPCSteeringSystem _steering = default!; [Dependency] private readonly MapSystem _mapSystem = default!; @@ -30,17 +31,15 @@ namespace Content.Client.NPC get => _modes; set { - var overlayManager = IoCManager.Resolve(); - if (value == PathfindingDebugMode.None) { Breadcrumbs.Clear(); Polys.Clear(); - overlayManager.RemoveOverlay(); + _overlayManager.RemoveOverlay(); } - else if (!overlayManager.HasOverlay()) + else if (!_overlayManager.HasOverlay()) { - overlayManager.AddOverlay(new PathfindingOverlay(EntityManager, _eyeManager, _inputManager, _mapManager, _cache, this, _mapSystem, _transformSystem)); + _overlayManager.AddOverlay(new PathfindingOverlay(EntityManager, _eyeManager, _inputManager, _mapManager, _cache, this, _mapSystem, _transformSystem)); } if ((value & PathfindingDebugMode.Steering) != 0x0) diff --git a/Content.Client/Radiation/Overlays/RadiationDebugOverlay.cs b/Content.Client/Radiation/Overlays/RadiationDebugOverlay.cs index 784c39a6ce..1f060e532d 100644 --- a/Content.Client/Radiation/Overlays/RadiationDebugOverlay.cs +++ b/Content.Client/Radiation/Overlays/RadiationDebugOverlay.cs @@ -11,6 +11,8 @@ namespace Content.Client.Radiation.Overlays; public sealed class RadiationDebugOverlay : Overlay { [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IResourceCache _cache = default!; + private readonly SharedMapSystem _mapSystem; private readonly RadiationSystem _radiation; @@ -24,8 +26,7 @@ public sealed class RadiationDebugOverlay : Overlay _radiation = _entityManager.System(); _mapSystem = _entityManager.System(); - var cache = IoCManager.Resolve(); - _font = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Regular.ttf"), 8); + _font = new VectorFont(_cache.GetResource("/Fonts/NotoSans/NotoSans-Regular.ttf"), 8); } protected override void Draw(in OverlayDrawArgs args) diff --git a/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs b/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs index 56b54c176a..f6e6594af5 100644 --- a/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs +++ b/Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs @@ -16,20 +16,20 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem get => _enableShuttlePosition; set { - if (_enableShuttlePosition == value) return; + if (_enableShuttlePosition == value) + return; _enableShuttlePosition = value; - var overlayManager = IoCManager.Resolve(); if (_enableShuttlePosition) { _overlay = new EmergencyShuttleOverlay(EntityManager.TransformQuery, XformSystem); - overlayManager.AddOverlay(_overlay); + _overlays.AddOverlay(_overlay); RaiseNetworkEvent(new EmergencyShuttleRequestPositionMessage()); } else { - overlayManager.RemoveOverlay(_overlay!); + _overlays.RemoveOverlay(_overlay!); _overlay = null; } } diff --git a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs index 6abebda6ee..c27e81b5c7 100644 --- a/Content.Client/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Client/Weapons/Ranged/Systems/GunSystem.cs @@ -30,6 +30,7 @@ public sealed partial class GunSystem : SharedGunSystem { [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IOverlayManager _overlayManager = default!; [Dependency] private readonly IPlayerManager _player = default!; [Dependency] private readonly IStateManager _state = default!; [Dependency] private readonly AnimationPlayerSystem _animPlayer = default!; @@ -50,11 +51,10 @@ public sealed partial class GunSystem : SharedGunSystem return; _spreadOverlay = value; - var overlayManager = IoCManager.Resolve(); if (_spreadOverlay) { - overlayManager.AddOverlay(new GunSpreadOverlay( + _overlayManager.AddOverlay(new GunSpreadOverlay( EntityManager, _eyeManager, Timing, @@ -65,7 +65,7 @@ public sealed partial class GunSystem : SharedGunSystem } else { - overlayManager.RemoveOverlay(); + _overlayManager.RemoveOverlay(); } } } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 31f86d0236..32da51f8bb 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -8,7 +8,6 @@ using Content.Shared.CombatMode; using Content.Shared.Containers.ItemSlots; using Content.Shared.Damage; using Content.Shared.Examine; -using Content.Shared.Gravity; using Content.Shared.Hands; using Content.Shared.Hands.EntitySystems; using Content.Shared.Popups; @@ -27,7 +26,6 @@ using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Network; -using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; @@ -57,7 +55,6 @@ public abstract partial class SharedGunSystem : EntitySystem [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] private readonly SharedCombatModeSystem _combatMode = default!; [Dependency] protected readonly SharedContainerSystem Containers = default!; - [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] protected readonly SharedPointLightSystem Lights = default!; [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; [Dependency] protected readonly SharedPhysicsSystem Physics = default!; From 91a4cee6e1b8b9810ad59eab8e9a944b24ad22a2 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Sun, 24 Aug 2025 06:34:56 -0700 Subject: [PATCH 12/16] [Bugfix] Lizard smite fix (#39842) Fix Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- Content.Server/Polymorph/Systems/PolymorphSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Polymorph/Systems/PolymorphSystem.cs b/Content.Server/Polymorph/Systems/PolymorphSystem.cs index aabc0366cd..ee7fdf2b22 100644 --- a/Content.Server/Polymorph/Systems/PolymorphSystem.cs +++ b/Content.Server/Polymorph/Systems/PolymorphSystem.cs @@ -259,7 +259,7 @@ public sealed partial class PolymorphSystem : EntitySystem if (configuration.TransferHumanoidAppearance) { - _humanoid.CloneAppearance(uid, child); + _humanoid.CloneAppearance(child, uid); } if (_mindSystem.TryGetMind(uid, out var mindId, out var mind)) From 30aa61c29c9bc5654b719fdae5e0fa1ca9a69cbd Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sun, 24 Aug 2025 15:50:19 +0200 Subject: [PATCH 13/16] Changeling cleanup and bugfix (#39843) * fixes and cleanup * key --- .../Systems/ChangelingIdentitySystem.cs | 30 ++++++++ .../ChangelingTransformBoundUserInterface.cs | 12 ++-- .../ChangelingTransformMenu.xaml | 0 .../ChangelingTransformMenu.xaml.cs | 16 +++-- .../Systems/ChangelingIdentitySystem.cs | 5 ++ .../Components/ChangelingIdentityComponent.cs | 2 +- .../Systems/ChangelingDevourSystem.cs | 2 +- .../Systems/ChangelingTransformSystem.UI.cs | 14 +--- .../Systems/ChangelingTransformSystem.cs | 19 ++--- ...m.cs => SharedChangelingIdentitySystem.cs} | 72 +++++++++---------- 10 files changed, 91 insertions(+), 81 deletions(-) create mode 100644 Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs rename Content.Client/Changeling/{Transform => UI}/ChangelingTransformBoundUserInterface.cs (72%) rename Content.Client/Changeling/{Transform => UI}/ChangelingTransformMenu.xaml (100%) rename Content.Client/Changeling/{Transform => UI}/ChangelingTransformMenu.xaml.cs (80%) create mode 100644 Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs rename Content.Shared/Changeling/Systems/{ChangelingIdentitySystem.cs => SharedChangelingIdentitySystem.cs} (68%) diff --git a/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs new file mode 100644 index 0000000000..348cfee0f8 --- /dev/null +++ b/Content.Client/Changeling/Systems/ChangelingIdentitySystem.cs @@ -0,0 +1,30 @@ +using Content.Shared.Changeling.Components; +using Content.Shared.Changeling.Systems; +using Robust.Client.GameObjects; + +namespace Content.Client.Changeling.Systems; + +public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem +{ + [Dependency] private readonly UserInterfaceSystem _ui = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAfterAutoHandleState); + } + + private void OnAfterAutoHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + UpdateUi(ent); + } + + public void UpdateUi(EntityUid uid) + { + if (_ui.TryGetOpenUi(uid, ChangelingTransformUiKey.Key, out var bui)) + { + bui.Update(); + } + } +} diff --git a/Content.Client/Changeling/Transform/ChangelingTransformBoundUserInterface.cs b/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs similarity index 72% rename from Content.Client/Changeling/Transform/ChangelingTransformBoundUserInterface.cs rename to Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs index 9401231303..8220e18708 100644 --- a/Content.Client/Changeling/Transform/ChangelingTransformBoundUserInterface.cs +++ b/Content.Client/Changeling/UI/ChangelingTransformBoundUserInterface.cs @@ -2,7 +2,7 @@ using JetBrains.Annotations; using Robust.Client.UserInterface; -namespace Content.Client.Changeling.Transform; +namespace Content.Client.Changeling.UI; [UsedImplicitly] public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) @@ -16,16 +16,16 @@ public sealed partial class ChangelingTransformBoundUserInterface(EntityUid owne _window = this.CreateWindow(); _window.OnIdentitySelect += SendIdentitySelect; + + _window.Update(Owner); } - protected override void UpdateState(BoundUserInterfaceState state) + public override void Update() { - base.UpdateState(state); - - if (state is not ChangelingTransformBoundUserInterfaceState current) + if (_window == null) return; - _window?.UpdateState(current); + _window.Update(Owner); } public void SendIdentitySelect(NetEntity identityId) diff --git a/Content.Client/Changeling/Transform/ChangelingTransformMenu.xaml b/Content.Client/Changeling/UI/ChangelingTransformMenu.xaml similarity index 100% rename from Content.Client/Changeling/Transform/ChangelingTransformMenu.xaml rename to Content.Client/Changeling/UI/ChangelingTransformMenu.xaml diff --git a/Content.Client/Changeling/Transform/ChangelingTransformMenu.xaml.cs b/Content.Client/Changeling/UI/ChangelingTransformMenu.xaml.cs similarity index 80% rename from Content.Client/Changeling/Transform/ChangelingTransformMenu.xaml.cs rename to Content.Client/Changeling/UI/ChangelingTransformMenu.xaml.cs index fa2deaf431..ebd4e90440 100644 --- a/Content.Client/Changeling/Transform/ChangelingTransformMenu.xaml.cs +++ b/Content.Client/Changeling/UI/ChangelingTransformMenu.xaml.cs @@ -1,11 +1,11 @@ using System.Numerics; using Content.Client.UserInterface.Controls; -using Content.Shared.Changeling.Systems; +using Content.Shared.Changeling.Components; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; -namespace Content.Client.Changeling.Transform; +namespace Content.Client.Changeling.UI; [GenerateTypedNameReferences] public sealed partial class ChangelingTransformMenu : RadialMenu @@ -19,13 +19,15 @@ public sealed partial class ChangelingTransformMenu : RadialMenu IoCManager.InjectDependencies(this); } - public void UpdateState(ChangelingTransformBoundUserInterfaceState state) + public void Update(EntityUid uid) { Main.DisposeAllChildren(); - foreach (var identity in state.Identites) - { - var identityUid = _entity.GetEntity(identity); + if (!_entity.TryGetComponent(uid, out var identityComp)) + return; + + foreach (var identityUid in identityComp.ConsumedIdentities) + { if (!_entity.TryGetComponent(identityUid, out var metadata)) continue; @@ -48,7 +50,7 @@ public sealed partial class ChangelingTransformMenu : RadialMenu entView.SetEntity(identityUid); button.OnButtonUp += _ => { - OnIdentitySelect?.Invoke(identity); + OnIdentitySelect?.Invoke(_entity.GetNetEntity(identityUid)); Close(); }; button.AddChild(entView); diff --git a/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs new file mode 100644 index 0000000000..8cb3dec3d6 --- /dev/null +++ b/Content.Server/Changeling/Systems/ChangelingIdentitySystem.cs @@ -0,0 +1,5 @@ +using Content.Shared.Changeling.Systems; + +namespace Content.Server.Changeling.Systems; + +public sealed class ChangelingIdentitySystem : SharedChangelingIdentitySystem; diff --git a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs index 2779164e4e..8e74f83537 100644 --- a/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs +++ b/Content.Shared/Changeling/Components/ChangelingIdentityComponent.cs @@ -8,7 +8,7 @@ namespace Content.Shared.Changeling.Components; /// The storage component for Changelings, it handles the link between a changeling and its consumed identities /// that exist on a paused map. /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(raiseAfterAutoHandleState: true)] public sealed partial class ChangelingIdentityComponent : Component { /// diff --git a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs index a064858d43..500ee06b22 100644 --- a/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingDevourSystem.cs @@ -32,7 +32,7 @@ public sealed class ChangelingDevourSystem : EntitySystem [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly MobStateSystem _mobState = default!; - [Dependency] private readonly ChangelingIdentitySystem _changelingIdentitySystem = default!; + [Dependency] private readonly SharedChangelingIdentitySystem _changelingIdentitySystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; diff --git a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.UI.cs b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.UI.cs index 98926631dc..e555147352 100644 --- a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.UI.cs +++ b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.UI.cs @@ -14,20 +14,8 @@ public sealed class ChangelingTransformIdentitySelectMessage(NetEntity targetIde public readonly NetEntity TargetIdentity = targetIdentity; } -// TODO: Replace with component states. -// We are already networking the ChangelingIdentityComponent, which contains all this information, -// so we can just read it from them from the component and update the UI in an AfterAuotHandleState subscription. [Serializable, NetSerializable] -public sealed class ChangelingTransformBoundUserInterfaceState(List identities) : BoundUserInterfaceState -{ - /// - /// The uids of the cloned identities. - /// - public readonly List Identites = identities; -} - -[Serializable, NetSerializable] -public enum TransformUI : byte +public enum ChangelingTransformUiKey : byte { Key, } diff --git a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs index 31f22b9294..cf8d9d7cb6 100644 --- a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs +++ b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs @@ -44,7 +44,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem _actionsSystem.AddAction(ent, ref ent.Comp.ChangelingTransformActionEntity, ent.Comp.ChangelingTransformAction); var userInterfaceComp = EnsureComp(ent); - _uiSystem.SetUi((ent, userInterfaceComp), TransformUI.Key, new InterfaceData(ChangelingBuiXmlGeneratedName)); + _uiSystem.SetUi((ent, userInterfaceComp), ChangelingTransformUiKey.Key, new InterfaceData(ChangelingBuiXmlGeneratedName)); } private void OnShutdown(Entity ent, ref ComponentShutdown args) @@ -64,18 +64,9 @@ public sealed partial class ChangelingTransformSystem : EntitySystem if (!TryComp(ent, out var userIdentity)) return; - if (!_uiSystem.IsUiOpen((ent, userInterfaceComp), TransformUI.Key, args.Performer)) + if (!_uiSystem.IsUiOpen((ent, userInterfaceComp), ChangelingTransformUiKey.Key, args.Performer)) { - _uiSystem.OpenUi((ent, userInterfaceComp), TransformUI.Key, args.Performer); - - var identityData = new List(); - - foreach (var consumedIdentity in userIdentity.ConsumedIdentities) - { - identityData.Add(GetNetEntity(consumedIdentity)); - } - - _uiSystem.SetUiState((ent, userInterfaceComp), TransformUI.Key, new ChangelingTransformBoundUserInterfaceState(identityData)); + _uiSystem.OpenUi((ent, userInterfaceComp), ChangelingTransformUiKey.Key, args.Performer); } //TODO: Can add a Else here with TransformInto and CloseUI to make a quick switch, // issue right now is that Radials cover the Action buttons so clicking the action closes the UI (due to clicking off a radial causing it to close, even with UI) // but pressing the number does. @@ -108,7 +99,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem else _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(ent.Owner):player} begun an attempt to transform into \"{Name(targetIdentity)}\""); - var result = _doAfterSystem.TryStartDoAfter(new DoAfterArgs( + _doAfterSystem.TryStartDoAfter(new DoAfterArgs( EntityManager, ent, ent.Comp.TransformWindup, @@ -127,7 +118,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem private void OnTransformSelected(Entity ent, ref ChangelingTransformIdentitySelectMessage args) { - _uiSystem.CloseUi(ent.Owner, TransformUI.Key, ent); + _uiSystem.CloseUi(ent.Owner, ChangelingTransformUiKey.Key, ent); if (!TryGetEntity(args.TargetIdentity, out var targetIdentity)) return; diff --git a/Content.Shared/Changeling/Systems/ChangelingIdentitySystem.cs b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs similarity index 68% rename from Content.Shared/Changeling/Systems/ChangelingIdentitySystem.cs rename to Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs index 8467cc5702..e7e46d79a1 100644 --- a/Content.Shared/Changeling/Systems/ChangelingIdentitySystem.cs +++ b/Content.Shared/Changeling/Systems/SharedChangelingIdentitySystem.cs @@ -2,7 +2,6 @@ using Content.Shared.Changeling.Components; using Content.Shared.Cloning; using Content.Shared.Humanoid; -using Content.Shared.Mind.Components; using Content.Shared.NameModifier.EntitySystems; using Robust.Shared.GameStates; using Robust.Shared.Map; @@ -12,7 +11,7 @@ using Robust.Shared.Prototypes; namespace Content.Shared.Changeling.Systems; -public sealed class ChangelingIdentitySystem : EntitySystem +public abstract class SharedChangelingIdentitySystem : EntitySystem { [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; @@ -32,22 +31,19 @@ public sealed class ChangelingIdentitySystem : EntitySystem SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnMindAdded); - SubscribeLocalEvent(OnMindRemoved); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnStoredRemove); } - private void OnMindAdded(Entity ent, ref MindAddedMessage args) + private void OnPlayerAttached(Entity ent, ref PlayerAttachedEvent args) { - if (!TryComp(args.Container.Owner, out var actor)) - return; - - HandOverPvsOverride(actor.PlayerSession, ent.Comp); + HandOverPvsOverride(ent, args.Player); } - private void OnMindRemoved(Entity ent, ref MindRemovedMessage args) + private void OnPlayerDetached(Entity ent, ref PlayerDetachedEvent args) { - CleanupPvsOverride(ent, args.Container.Owner); + CleanupPvsOverride(ent, args.Player); } private void OnMapInit(Entity ent, ref MapInitEvent args) @@ -59,7 +55,8 @@ public sealed class ChangelingIdentitySystem : EntitySystem private void OnShutdown(Entity ent, ref ComponentShutdown args) { - CleanupPvsOverride(ent, ent.Owner); + if (TryComp(ent, out var actor)) + CleanupPvsOverride(ent, actor.PlayerSession); CleanupChangelingNullspaceIdentities(ent); } @@ -107,66 +104,63 @@ public sealed class ChangelingIdentitySystem : EntitySystem // Movercontrollers and mob collisions are currently being calculated even for paused entities. // Spawning all of them in the same spot causes severe performance problems. // Cryopods and Polymorph have the same problem. - var mob = Spawn(speciesPrototype.Prototype, new MapCoordinates(new Vector2(2 * _numberOfStoredIdentities++, 0), PausedMapId!.Value)); + var clone = Spawn(speciesPrototype.Prototype, new MapCoordinates(new Vector2(2 * _numberOfStoredIdentities++, 0), PausedMapId!.Value)); - var storedIdentity = EnsureComp(mob); + var storedIdentity = EnsureComp(clone); storedIdentity.OriginalEntity = target; // TODO: network this once we have WeakEntityReference or the autonetworking source gen is fixed if (TryComp(target, out var actor)) storedIdentity.OriginalSession = actor.PlayerSession; - _humanoidSystem.CloneAppearance(target, mob); - _cloningSystem.CloneComponents(target, mob, settings); + _humanoidSystem.CloneAppearance(target, clone); + _cloningSystem.CloneComponents(target, clone, settings); var targetName = _nameMod.GetBaseName(target); - _metaSystem.SetEntityName(mob, targetName); - ent.Comp.ConsumedIdentities.Add(mob); + _metaSystem.SetEntityName(clone, targetName); + ent.Comp.ConsumedIdentities.Add(clone); Dirty(ent); - HandlePvsOverride(ent, mob); + HandlePvsOverride(ent, clone); - return mob; + return clone; } /// - /// Simple helper to add a PVS override to a Nullspace Identity + /// Simple helper to add a PVS override to a nullspace identity. /// - /// - /// - private void HandlePvsOverride(EntityUid uid, EntityUid target) + /// The actor that should get the override. + /// The identity stored in nullspace. + private void HandlePvsOverride(EntityUid uid, EntityUid identity) { if (!TryComp(uid, out var actor)) return; - _pvsOverrideSystem.AddSessionOverride(target, actor.PlayerSession); + _pvsOverrideSystem.AddSessionOverride(identity, actor.PlayerSession); } /// - /// Cleanup all Pvs Overrides for the owner of the ChangelingIdentity + /// Cleanup all PVS overrides for the owner of the ChangelingIdentity /// - /// the Changeling itself - /// Who specifically to cleanup from, usually just the same owner, but in the case of a mindswap we want to clean up the victim - private void CleanupPvsOverride(Entity ent, EntityUid entityUid) + /// The changeling storing the identities. + /// + private void CleanupPvsOverride(Entity ent, ICommonSession session) { - if (!TryComp(entityUid, out var actor)) - return; - foreach (var identity in ent.Comp.ConsumedIdentities) { - _pvsOverrideSystem.RemoveSessionOverride(identity, actor.PlayerSession); + _pvsOverrideSystem.RemoveSessionOverride(identity, session); } } /// - /// Inform another Session of the entities stored for Transformation + /// Inform another session of the entities stored for transformation. /// - /// The Session you wish to inform - /// The Target storage of identities - public void HandOverPvsOverride(ICommonSession session, ChangelingIdentityComponent comp) + /// The changeling storing the identities. + /// The session you wish to inform. + public void HandOverPvsOverride(Entity ent, ICommonSession session) { - foreach (var entity in comp.ConsumedIdentities) + foreach (var identity in ent.Comp.ConsumedIdentities) { - _pvsOverrideSystem.AddSessionOverride(entity, session); + _pvsOverrideSystem.AddSessionOverride(identity, session); } } From b5529ecf2b5db7052f2e5978df1136b812eac008 Mon Sep 17 00:00:00 2001 From: Whatstone <166147148+whatston3@users.noreply.github.com> Date: Sun, 24 Aug 2025 11:02:47 -0400 Subject: [PATCH 14/16] Batchable lathe jobs, editable lathe job order (#38624) * batchable lathe jobs, editable order * requested changes * LatheComponent comment, menu strings --- .../Lathe/UI/LatheBoundUserInterface.cs | 4 + Content.Client/Lathe/UI/LatheMenu.xaml | 13 ++ Content.Client/Lathe/UI/LatheMenu.xaml.cs | 36 +++- .../Lathe/UI/QueuedRecipeControl.xaml | 35 ++++ .../Lathe/UI/QueuedRecipeControl.xaml.cs | 36 ++++ Content.Server/Lathe/LatheSystem.cs | 164 +++++++++++++++--- Content.Shared/Lathe/LatheComponent.cs | 23 ++- Content.Shared/Lathe/LatheMessages.cs | 31 +++- .../Lathe/PrototypeIdLinkedListSerializer.cs | 81 +++++++++ Content.Shared/Lathe/SharedLatheSystem.cs | 3 + .../Locale/en-US/lathe/ui/lathe-menu.ftl | 6 + 11 files changed, 397 insertions(+), 35 deletions(-) create mode 100644 Content.Client/Lathe/UI/QueuedRecipeControl.xaml create mode 100644 Content.Client/Lathe/UI/QueuedRecipeControl.xaml.cs create mode 100644 Content.Shared/Lathe/PrototypeIdLinkedListSerializer.cs diff --git a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs index 4ddde885fa..75b1704b0d 100644 --- a/Content.Client/Lathe/UI/LatheBoundUserInterface.cs +++ b/Content.Client/Lathe/UI/LatheBoundUserInterface.cs @@ -30,6 +30,10 @@ namespace Content.Client.Lathe.UI { SendMessage(new LatheQueueRecipeMessage(recipe, amount)); }; + _menu.QueueDeleteAction += index => SendMessage(new LatheDeleteRequestMessage(index)); + _menu.QueueMoveUpAction += index => SendMessage(new LatheMoveRequestMessage(index, -1)); + _menu.QueueMoveDownAction += index => SendMessage(new LatheMoveRequestMessage(index, 1)); + _menu.DeleteFabricatingAction += () => SendMessage(new LatheAbortFabricationMessage()); } protected override void UpdateState(BoundUserInterfaceState state) diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml b/Content.Client/Lathe/UI/LatheMenu.xaml index 28b79254c0..a5c8f6a85c 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml +++ b/Content.Client/Lathe/UI/LatheMenu.xaml @@ -1,6 +1,7 @@ + diff --git a/Content.Client/Lathe/UI/LatheMenu.xaml.cs b/Content.Client/Lathe/UI/LatheMenu.xaml.cs index 66d875b0f2..ce190464d2 100644 --- a/Content.Client/Lathe/UI/LatheMenu.xaml.cs +++ b/Content.Client/Lathe/UI/LatheMenu.xaml.cs @@ -26,6 +26,10 @@ public sealed partial class LatheMenu : DefaultWindow public event Action? OnServerListButtonPressed; public event Action? RecipeQueueAction; + public event Action? QueueDeleteAction; + public event Action? QueueMoveUpAction; + public event Action? QueueMoveDownAction; + public event Action? DeleteFabricatingAction; public List> Recipes = new(); @@ -50,12 +54,21 @@ public sealed partial class LatheMenu : DefaultWindow }; AmountLineEdit.OnTextChanged += _ => { + if (int.TryParse(AmountLineEdit.Text, out var amount)) + { + if (amount > LatheSystem.MaxItemsPerRequest) + AmountLineEdit.Text = LatheSystem.MaxItemsPerRequest.ToString(); + else if (amount < 0) + AmountLineEdit.Text = "0"; + } + PopulateRecipes(); }; FilterOption.OnItemSelected += OnItemSelected; ServerListButton.OnPressed += a => OnServerListButtonPressed?.Invoke(a); + DeleteFabricating.OnPressed += _ => DeleteFabricatingAction?.Invoke(); } public void SetEntity(EntityUid uid) @@ -223,22 +236,27 @@ public sealed partial class LatheMenu : DefaultWindow /// Populates the build queue list with all queued items /// /// - public void PopulateQueueList(IReadOnlyCollection> queue) + public void PopulateQueueList(IReadOnlyCollection queue) { QueueList.DisposeAllChildren(); var idx = 1; - foreach (var recipeProto in queue) + foreach (var batch in queue) { - var recipe = _prototypeManager.Index(recipeProto); - var queuedRecipeBox = new BoxContainer(); - queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal; + var recipe = _prototypeManager.Index(batch.Recipe); - queuedRecipeBox.AddChild(GetRecipeDisplayControl(recipe)); + var itemName = _lathe.GetRecipeName(batch.Recipe); + string displayText; + if (batch.ItemsRequested > 1) + displayText = Loc.GetString("lathe-menu-item-batch", ("index", idx), ("name", itemName), ("printed", batch.ItemsPrinted), ("total", batch.ItemsRequested)); + else + displayText = Loc.GetString("lathe-menu-item-single", ("index", idx), ("name", itemName)); + + var queuedRecipeBox = new QueuedRecipeControl(displayText, idx - 1, GetRecipeDisplayControl(recipe)); + queuedRecipeBox.OnDeletePressed += s => QueueDeleteAction?.Invoke(s); + queuedRecipeBox.OnMoveUpPressed += s => QueueMoveUpAction?.Invoke(s); + queuedRecipeBox.OnMoveDownPressed += s => QueueMoveDownAction?.Invoke(s); - var queuedRecipeLabel = new Label(); - queuedRecipeLabel.Text = $"{idx}. {_lathe.GetRecipeName(recipe)}"; - queuedRecipeBox.AddChild(queuedRecipeLabel); QueueList.AddChild(queuedRecipeBox); idx++; } diff --git a/Content.Client/Lathe/UI/QueuedRecipeControl.xaml b/Content.Client/Lathe/UI/QueuedRecipeControl.xaml new file mode 100644 index 0000000000..b1d4b496a1 --- /dev/null +++ b/Content.Client/Lathe/UI/QueuedRecipeControl.xaml @@ -0,0 +1,35 @@ + + + + + diff --git a/Content.Client/Lathe/UI/QueuedRecipeControl.xaml.cs b/Content.Client/Lathe/UI/QueuedRecipeControl.xaml.cs new file mode 100644 index 0000000000..c4ba9803b0 --- /dev/null +++ b/Content.Client/Lathe/UI/QueuedRecipeControl.xaml.cs @@ -0,0 +1,36 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.Lathe.UI; + +[GenerateTypedNameReferences] +public sealed partial class QueuedRecipeControl : Control +{ + public Action? OnDeletePressed; + public Action? OnMoveUpPressed; + public Action? OnMoveDownPressed; + + public QueuedRecipeControl(string displayText, int index, Control displayControl) + { + RobustXamlLoader.Load(this); + + RecipeName.Text = displayText; + RecipeDisplayContainer.AddChild(displayControl); + + MoveUp.OnPressed += (_) => + { + OnMoveUpPressed?.Invoke(index); + }; + + MoveDown.OnPressed += (_) => + { + OnMoveDownPressed?.Invoke(index); + }; + + Delete.OnPressed += (_) => + { + OnDeletePressed?.Invoke(index); + }; + } +} diff --git a/Content.Server/Lathe/LatheSystem.cs b/Content.Server/Lathe/LatheSystem.cs index 6ecd5bdf62..02abb07791 100644 --- a/Content.Server/Lathe/LatheSystem.cs +++ b/Content.Server/Lathe/LatheSystem.cs @@ -74,6 +74,9 @@ namespace Content.Server.Lathe SubscribeLocalEvent(OnLatheQueueRecipeMessage); SubscribeLocalEvent(OnLatheSyncRequestMessage); + SubscribeLocalEvent(OnLatheDeleteRequestMessage); + SubscribeLocalEvent(OnLatheMoveRequestMessage); + SubscribeLocalEvent(OnLatheAbortFabricationMessage); SubscribeLocalEvent((u, c, _) => UpdateUserInterfaceState(u, c)); SubscribeLocalEvent(OnMaterialAmountChanged); @@ -167,23 +170,32 @@ namespace Content.Server.Lathe return ev.Recipes.ToList(); } - public bool TryAddToQueue(EntityUid uid, LatheRecipePrototype recipe, LatheComponent? component = null) + public bool TryAddToQueue(EntityUid uid, LatheRecipePrototype recipe, int quantity, LatheComponent? component = null) { if (!Resolve(uid, ref component)) return false; - if (!CanProduce(uid, recipe, 1, component)) + if (quantity <= 0) + return false; + quantity = int.Min(quantity, MaxItemsPerRequest); + + if (!CanProduce(uid, recipe, quantity, component)) return false; foreach (var (mat, amount) in recipe.Materials) { var adjustedAmount = recipe.ApplyMaterialDiscount - ? (int) (-amount * component.MaterialUseMultiplier) + ? (int)(-amount * component.MaterialUseMultiplier) : -amount; + adjustedAmount *= quantity; _materialStorage.TryChangeMaterialAmount(uid, mat, adjustedAmount); } - component.Queue.Enqueue(recipe); + + if (component.Queue.Last is { } node && node.ValueRef.Recipe == recipe.ID) + node.ValueRef.ItemsRequested += quantity; + else + component.Queue.AddLast(new LatheRecipeBatch(recipe.ID, 0, quantity)); return true; } @@ -195,8 +207,11 @@ namespace Content.Server.Lathe if (component.CurrentRecipe != null || component.Queue.Count <= 0 || !this.IsPowered(uid, EntityManager)) return false; - var recipeProto = component.Queue.Dequeue(); - var recipe = _proto.Index(recipeProto); + var batch = component.Queue.First(); + batch.ItemsPrinted++; + if (batch.ItemsPrinted >= batch.ItemsRequested || batch.ItemsPrinted < 0) // Rollover sanity check + component.Queue.RemoveFirst(); + var recipe = _proto.Index(batch.Recipe); var time = _reagentSpeed.ApplySpeed(uid, recipe.CompleteTime) * component.TimeMultiplier; @@ -271,8 +286,8 @@ namespace Content.Server.Lathe return; var producing = component.CurrentRecipe; - if (producing == null && component.Queue.TryPeek(out var next)) - producing = next; + if (producing == null && component.Queue.First is { } node) + producing = node.Value.Recipe; var state = new LatheUpdateState(GetAvailableRecipes(uid, component), component.Queue.ToArray(), producing); _uiSys.SetUiState(uid, LatheUiKey.Key, state); @@ -349,12 +364,10 @@ namespace Content.Server.Lathe { if (!args.Powered) { - RemComp(uid); - UpdateRunningAppearance(uid, false); + AbortProduction(uid); } - else if (component.CurrentRecipe != null) + else { - EnsureComp(uid); TryStartProducing(uid, component); } } @@ -416,25 +429,46 @@ namespace Content.Server.Lathe return GetAvailableRecipes(uid, component).Contains(recipe.ID); } + public void AbortProduction(EntityUid uid, LatheComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + if (component.CurrentRecipe != null) + { + if (component.Queue.Count > 0) + { + // Batch abandoned while printing last item, need to create a one-item batch + var batch = component.Queue.First(); + if (batch.Recipe != component.CurrentRecipe) + { + var newBatch = new LatheRecipeBatch(component.CurrentRecipe.Value, 0, 1); + component.Queue.AddFirst(newBatch); + } + else if (batch.ItemsPrinted > 0) + { + batch.ItemsPrinted--; + } + } + + component.CurrentRecipe = null; + } + RemCompDeferred(uid); + UpdateUserInterfaceState(uid, component); + UpdateRunningAppearance(uid, false); + } + #region UI Messages private void OnLatheQueueRecipeMessage(EntityUid uid, LatheComponent component, LatheQueueRecipeMessage args) { if (_proto.TryIndex(args.ID, out LatheRecipePrototype? recipe)) { - var count = 0; - for (var i = 0; i < args.Quantity; i++) - { - if (TryAddToQueue(uid, recipe, component)) - count++; - else - break; - } - if (count > 0) + if (TryAddToQueue(uid, recipe, args.Quantity, component)) { _adminLogger.Add(LogType.Action, LogImpact.Low, - $"{ToPrettyString(args.Actor):player} queued {count} {GetRecipeName(recipe)} at {ToPrettyString(uid):lathe}"); + $"{ToPrettyString(args.Actor):player} queued {args.Quantity} {GetRecipeName(recipe)} at {ToPrettyString(uid):lathe}"); } } TryStartProducing(uid, component); @@ -445,6 +479,92 @@ namespace Content.Server.Lathe { UpdateUserInterfaceState(uid, component); } + + /// + /// Removes a batch from the batch queue by index. + /// If the index given does not exist or is outside of the bounds of the lathe's batch queue, nothing happens. + /// + /// The lathe whose queue is being altered. + /// + /// + public void OnLatheDeleteRequestMessage(EntityUid uid, LatheComponent component, ref LatheDeleteRequestMessage args) + { + if (args.Index < 0 || args.Index >= component.Queue.Count) + return; + + var node = component.Queue.First; + for (int i = 0; i < args.Index; i++) + node = node?.Next; + + if (node == null) // Shouldn't happen with checks above. + return; + + var batch = node.Value; + _adminLogger.Add(LogType.Action, + LogImpact.Low, + $"{ToPrettyString(args.Actor):player} deleted a lathe job for ({batch.ItemsPrinted}/{batch.ItemsRequested}) {GetRecipeName(batch.Recipe)} at {ToPrettyString(uid):lathe}"); + + component.Queue.Remove(node); + UpdateUserInterfaceState(uid, component); + } + + public void OnLatheMoveRequestMessage(EntityUid uid, LatheComponent component, ref LatheMoveRequestMessage args) + { + if (args.Change == 0 || args.Index < 0 || args.Index >= component.Queue.Count) + return; + + // New index must be within the bounds of the batch. + var newIndex = args.Index + args.Change; + if (newIndex < 0 || newIndex >= component.Queue.Count) + return; + + var node = component.Queue.First; + for (int i = 0; i < args.Index; i++) + node = node?.Next; + + if (node == null) // Something went wrong. + return; + + if (args.Change > 0) + { + var newRelativeNode = node.Next; + for (int i = 1; i < args.Change; i++) // 1-indexed: starting from Next + newRelativeNode = newRelativeNode?.Next; + + if (newRelativeNode == null) // Something went wrong. + return; + + component.Queue.Remove(node); + component.Queue.AddAfter(newRelativeNode, node); + } + else + { + var newRelativeNode = node.Previous; + for (int i = 1; i < -args.Change; i++) // 1-indexed: starting from Previous + newRelativeNode = newRelativeNode?.Previous; + + if (newRelativeNode == null) // Something went wrong. + return; + + component.Queue.Remove(node); + component.Queue.AddBefore(newRelativeNode, node); + } + + UpdateUserInterfaceState(uid, component); + } + + public void OnLatheAbortFabricationMessage(EntityUid uid, LatheComponent component, ref LatheAbortFabricationMessage args) + { + if (component.CurrentRecipe == null) + return; + + _adminLogger.Add(LogType.Action, + LogImpact.Low, + $"{ToPrettyString(args.Actor):player} aborted printing {GetRecipeName(component.CurrentRecipe.Value)} at {ToPrettyString(uid):lathe}"); + + component.CurrentRecipe = null; + FinishProducing(uid, component); + } #endregion } } diff --git a/Content.Shared/Lathe/LatheComponent.cs b/Content.Shared/Lathe/LatheComponent.cs index 8b701ff64e..7bd7764514 100644 --- a/Content.Shared/Lathe/LatheComponent.cs +++ b/Content.Shared/Lathe/LatheComponent.cs @@ -26,10 +26,14 @@ namespace Content.Shared.Lathe // Otherwise the material arbitrage test and/or LatheSystem.GetAllBaseRecipes needs to be updated /// - /// The lathe's construction queue + /// The lathe's construction queue. /// + /// + /// This is a LinkedList to allow for constant time insertion/deletion (vs a List), and more efficient + /// moves (vs a Queue). + /// [DataField] - public Queue> Queue = new(); + public LinkedList Queue = new(); /// /// The sound that plays when the lathe is producing an item, if any @@ -97,6 +101,21 @@ namespace Content.Shared.Lathe } } + [Serializable] + public sealed partial class LatheRecipeBatch + { + public ProtoId Recipe; + public int ItemsPrinted; + public int ItemsRequested; + + public LatheRecipeBatch(ProtoId recipe, int itemsPrinted, int itemsRequested) + { + Recipe = recipe; + ItemsPrinted = itemsPrinted; + ItemsRequested = itemsRequested; + } + } + /// /// Event raised on a lathe when it starts producing a recipe. /// diff --git a/Content.Shared/Lathe/LatheMessages.cs b/Content.Shared/Lathe/LatheMessages.cs index 1c1c6440f1..fe72eed367 100644 --- a/Content.Shared/Lathe/LatheMessages.cs +++ b/Content.Shared/Lathe/LatheMessages.cs @@ -10,11 +10,11 @@ public sealed class LatheUpdateState : BoundUserInterfaceState { public List> Recipes; - public ProtoId[] Queue; + public LatheRecipeBatch[] Queue; public ProtoId? CurrentlyProducing; - public LatheUpdateState(List> recipes, ProtoId[] queue, ProtoId? currentlyProducing = null) + public LatheUpdateState(List> recipes, LatheRecipeBatch[] queue, ProtoId? currentlyProducing = null) { Recipes = recipes; Queue = queue; @@ -46,6 +46,33 @@ public sealed class LatheQueueRecipeMessage : BoundUserInterfaceMessage } } +/// +/// Sent to the server to remove a batch from the queue. +/// +[Serializable, NetSerializable] +public sealed class LatheDeleteRequestMessage(int index) : BoundUserInterfaceMessage +{ + public int Index = index; +} + +/// +/// Sent to the server to move the position of a batch in the queue. +/// +[Serializable, NetSerializable] +public sealed class LatheMoveRequestMessage(int index, int change) : BoundUserInterfaceMessage +{ + public int Index = index; + public int Change = change; +} + +/// +/// Sent to the server to stop producing the current item. +/// +[Serializable, NetSerializable] +public sealed class LatheAbortFabricationMessage() : BoundUserInterfaceMessage +{ +} + [NetSerializable, Serializable] public enum LatheUiKey { diff --git a/Content.Shared/Lathe/PrototypeIdLinkedListSerializer.cs b/Content.Shared/Lathe/PrototypeIdLinkedListSerializer.cs new file mode 100644 index 0000000000..1c616ff105 --- /dev/null +++ b/Content.Shared/Lathe/PrototypeIdLinkedListSerializer.cs @@ -0,0 +1,81 @@ +using Robust.Shared.Serialization; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Markdown; +using Robust.Shared.Serialization.Markdown.Sequence; +using Robust.Shared.Serialization.Markdown.Validation; +using Robust.Shared.Serialization.TypeSerializers.Interfaces; + +namespace Content.Shared.Lathe; + +/// +/// Handles reading, writing, and validation for linked lists of prototypes. +/// +/// The type of prototype this linked list represents +/// +/// This is in the Content.Shared.Lathe namespace as there are no other LinkedList ProtoId instances. +/// +[TypeSerializer] +public sealed class LinkedListSerializer : ITypeSerializer, SequenceDataNode>, ITypeCopier> where T : class +{ + public ValidationNode Validate(ISerializationManager serializationManager, SequenceDataNode node, + IDependencyCollection dependencies, ISerializationContext? context = null) + { + var list = new List(); + + foreach (var elem in node.Sequence) + { + list.Add(serializationManager.ValidateNode(elem, context)); + } + + return new ValidatedSequenceNode(list); + } + + public DataNode Write(ISerializationManager serializationManager, LinkedList value, + IDependencyCollection dependencies, + bool alwaysWrite = false, + ISerializationContext? context = null) + { + var sequence = new SequenceDataNode(); + + foreach (var elem in value) + { + sequence.Add(serializationManager.WriteValue(elem, alwaysWrite, context)); + } + + return sequence; + } + + LinkedList ITypeReader, SequenceDataNode>.Read(ISerializationManager serializationManager, + SequenceDataNode node, + IDependencyCollection dependencies, + SerializationHookContext hookCtx, + ISerializationContext? context, ISerializationManager.InstantiationDelegate>? instanceProvider) + { + var list = instanceProvider != null ? instanceProvider() : new LinkedList(); + + foreach (var dataNode in node.Sequence) + { + list.AddLast(serializationManager.Read(dataNode, hookCtx, context)); + } + + return list; + } + + public void CopyTo( + ISerializationManager serializationManager, + LinkedList source, + ref LinkedList target, + IDependencyCollection dependencies, + SerializationHookContext hookCtx, + ISerializationContext? context = null) + { + target.Clear(); + using var enumerator = source.GetEnumerator(); + + while (enumerator.MoveNext()) + { + var current = enumerator.Current; + target.AddLast(current); + } + } +} diff --git a/Content.Shared/Lathe/SharedLatheSystem.cs b/Content.Shared/Lathe/SharedLatheSystem.cs index 524d83fd84..5942f4bf6c 100644 --- a/Content.Shared/Lathe/SharedLatheSystem.cs +++ b/Content.Shared/Lathe/SharedLatheSystem.cs @@ -22,6 +22,7 @@ public abstract class SharedLatheSystem : EntitySystem [Dependency] private readonly EmagSystem _emag = default!; public readonly Dictionary> InverseRecipes = new(); + public const int MaxItemsPerRequest = 10_000; public override void Initialize() { @@ -86,6 +87,8 @@ public abstract class SharedLatheSystem : EntitySystem return false; if (!HasRecipe(uid, recipe, component)) return false; + if (amount <= 0) + return false; foreach (var (material, needed) in recipe.Materials) { diff --git a/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl b/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl index 076a70447c..c04c095162 100644 --- a/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl +++ b/Resources/Locale/en-US/lathe/ui/lathe-menu.ftl @@ -29,3 +29,9 @@ lathe-menu-silo-linked-message = Silo Linked lathe-menu-fabricating-message = Fabricating... lathe-menu-materials-title = Materials lathe-menu-queue-title = Build Queue +lathe-menu-delete-fabricating-tooltip = Cancel printing the current item. +lathe-menu-delete-item-tooltip = Cancel printing this batch. +lathe-menu-move-up-tooltip = Move this batch ahead in the queue. +lathe-menu-move-down-tooltip = Move this batch back in the queue. +lathe-menu-item-single = {$index}. {$name} +lathe-menu-item-batch = {$index}. {$name} ({$printed}/{$total}) From b168f7be5a849863f6ce81048ca68fbd3eecefa9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 24 Aug 2025 15:03:54 +0000 Subject: [PATCH 15/16] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2d81e15d90..fc3f0e933b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: ArtisticRoomba - changes: - - message: A new Mapping changelog has been added. You can find it in a different - "Mapping" tab under the changelog menu. - type: Add - id: 8369 - time: '2025-04-27T20:15:17.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/34848 - author: ScarKy0 changes: - message: Deliveries can now spawn as fragile-type! Deliver them intact to earn @@ -3948,3 +3940,11 @@ id: 8881 time: '2025-08-23T22:15:28.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/35100 +- author: whatston3 + changes: + - message: Lathes now batch items into jobs, which can be moved around in priority + or deleted. + type: Add + id: 8882 + time: '2025-08-24T15:02:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/38624 From 6c154fb79e467fff1191a4bb01c045e86cf7703f Mon Sep 17 00:00:00 2001 From: M4rchy-S <89603088+M4rchy-S@users.noreply.github.com> Date: Sun, 24 Aug 2025 23:46:23 +0300 Subject: [PATCH 16/16] Moving FlammableComponent to Shared (#39870) --- .../Administration/Systems/AdminVerbSystem.Smites.cs | 5 +---- Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs | 2 +- Content.Server/EntityEffects/EntityEffectSystem.cs | 2 +- Content.Server/Explosion/EntitySystems/ExplosionSystem.cs | 1 + Content.Server/NPC/Systems/NPCUtilitySystem.cs | 4 +--- .../Xenoarchaeology/Artifact/XAE/XAEIgniteSystem.cs | 2 +- .../Atmos/Components/FlammableComponent.cs | 5 +++-- 7 files changed, 9 insertions(+), 12 deletions(-) rename {Content.Server => Content.Shared}/Atmos/Components/FlammableComponent.cs (95%) diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index cd89b11e10..90e5e46d65 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -1,10 +1,8 @@ using System.Threading; using Content.Server.Administration.Components; -using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Components; using Content.Server.Body.Systems; -using Content.Server.Clothing.Systems; using Content.Server.Electrocution; using Content.Server.Explosion.EntitySystems; using Content.Server.GhostKick; @@ -19,6 +17,7 @@ using Content.Server.Tabletop; using Content.Server.Tabletop.Components; using Content.Shared.Administration; using Content.Shared.Administration.Components; +using Content.Shared.Atmos.Components; using Content.Shared.Body.Components; using Content.Shared.Body.Part; using Content.Shared.Clumsy; @@ -40,7 +39,6 @@ using Content.Shared.Nutrition.Components; using Content.Shared.Popups; using Content.Shared.Slippery; using Content.Shared.Storage.Components; -using Content.Shared.Stunnable; using Content.Shared.Tabletop.Components; using Content.Shared.Tools.Systems; using Content.Shared.Verbs; @@ -50,7 +48,6 @@ using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Player; using Robust.Shared.Random; -using Robust.Shared.Timing; using Robust.Shared.Utility; using Timer = Robust.Shared.Timing.Timer; diff --git a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs index d38bda562b..5ceb9888f4 100644 --- a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs @@ -1,7 +1,7 @@ -using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Shared.Anomaly.Components; using Content.Shared.Anomaly.Effects.Components; +using Content.Shared.Atmos.Components; using Robust.Shared.Map; namespace Content.Server.Anomaly.Effects; diff --git a/Content.Server/EntityEffects/EntityEffectSystem.cs b/Content.Server/EntityEffects/EntityEffectSystem.cs index b0b8ab5045..f423a43261 100644 --- a/Content.Server/EntityEffects/EntityEffectSystem.cs +++ b/Content.Server/EntityEffects/EntityEffectSystem.cs @@ -1,6 +1,5 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Components; using Content.Server.Body.Systems; @@ -22,6 +21,7 @@ using Content.Server.Temperature.Systems; using Content.Server.Traits.Assorted; using Content.Server.Zombies; using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; using Content.Shared.Body.Components; using Content.Shared.Coordinates.Helpers; using Content.Shared.EntityEffects.EffectConditions; diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index c50b1e53fa..fc31a77041 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NPC.Pathfinding; +using Content.Shared.Atmos.Components; using Content.Shared.Camera; using Content.Shared.CCVar; using Content.Shared.Damage; diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs index 5f077a06bb..813626a1c4 100644 --- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs +++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs @@ -1,4 +1,3 @@ -using Content.Server.Atmos.Components; using Content.Server.Fluids.EntitySystems; using Content.Server.Hands.Systems; using Content.Server.NPC.Queries; @@ -6,13 +5,11 @@ using Content.Server.NPC.Queries.Considerations; using Content.Server.NPC.Queries.Curves; using Content.Server.NPC.Queries.Queries; using Content.Server.Nutrition.Components; -using Content.Server.Nutrition.EntitySystems; using Content.Server.Temperature.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Damage; using Content.Shared.Examine; using Content.Shared.Fluids.Components; -using Content.Shared.Hands.Components; using Content.Shared.Inventory; using Content.Shared.Mobs; using Content.Shared.Mobs.Systems; @@ -31,6 +28,7 @@ using Microsoft.Extensions.ObjectPool; using Robust.Server.Containers; using Robust.Shared.Prototypes; using Robust.Shared.Utility; +using Content.Shared.Atmos.Components; using System.Linq; namespace Content.Server.NPC.Systems; diff --git a/Content.Server/Xenoarchaeology/Artifact/XAE/XAEIgniteSystem.cs b/Content.Server/Xenoarchaeology/Artifact/XAE/XAEIgniteSystem.cs index 14270fb866..7e8fff73ad 100644 --- a/Content.Server/Xenoarchaeology/Artifact/XAE/XAEIgniteSystem.cs +++ b/Content.Server/Xenoarchaeology/Artifact/XAE/XAEIgniteSystem.cs @@ -1,6 +1,6 @@ -using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Server.Xenoarchaeology.Artifact.XAE.Components; +using Content.Shared.Atmos.Components; using Content.Shared.Xenoarchaeology.Artifact; using Content.Shared.Xenoarchaeology.Artifact.XAE; using Robust.Shared.Random; diff --git a/Content.Server/Atmos/Components/FlammableComponent.cs b/Content.Shared/Atmos/Components/FlammableComponent.cs similarity index 95% rename from Content.Server/Atmos/Components/FlammableComponent.cs rename to Content.Shared/Atmos/Components/FlammableComponent.cs index 9ae99a1513..acfb9e2540 100644 --- a/Content.Server/Atmos/Components/FlammableComponent.cs +++ b/Content.Shared/Atmos/Components/FlammableComponent.cs @@ -1,11 +1,12 @@ using Content.Shared.Alert; using Content.Shared.Damage; +using Robust.Shared.GameStates; using Robust.Shared.Physics.Collision.Shapes; using Robust.Shared.Prototypes; -namespace Content.Server.Atmos.Components +namespace Content.Shared.Atmos.Components { - [RegisterComponent] + [RegisterComponent, NetworkedComponent] public sealed partial class FlammableComponent : Component { [DataField]