diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 492c685e29..b31db597b1 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -101,6 +101,7 @@ namespace Content.Client.Entry "SoundOnTrigger", "TriggerOnCollide", "DeleteOnTrigger", + "EmptyOnMachineDeconstruct", "ExplodeOnTrigger", "Utensil", "UnarmedCombat", diff --git a/Content.Server/Chemistry/Components/ChemMasterComponent.cs b/Content.Server/Chemistry/Components/ChemMasterComponent.cs index eebcf35f70..2d10d8f5bf 100644 --- a/Content.Server/Chemistry/Components/ChemMasterComponent.cs +++ b/Content.Server/Chemistry/Components/ChemMasterComponent.cs @@ -73,6 +73,7 @@ namespace Content.Server.Chemistry.Components UserInterface.OnReceiveMessage += OnUiReceiveMessage; } + // Name relied upon by construction graph machine.yml to ensure beaker doesn't get deleted BeakerContainer = ContainerHelpers.EnsureContainer(Owner, $"{Name}-reagentContainerContainer"); @@ -434,6 +435,11 @@ namespace Content.Server.Chemistry.Components { Owner.PopupMessage(args.User, Loc.GetString("chem-master-component-cannot-put-entity-message", ("entity", activeHandEntity))); + // TBD: This is very definitely hax so that Construction & Wires get a chance to handle things. + // When this is ECS'd, drop this in favour of proper prioritization. + // Since this is a catch-all handler, that means do this last! + // Also note ReagentDispenserComponent did something similar before I got here. + return false; } return true; diff --git a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs index 481f825d36..40f31be9f3 100644 --- a/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs +++ b/Content.Server/Chemistry/Components/ReagentDispenserComponent.cs @@ -83,6 +83,7 @@ namespace Content.Server.Chemistry.Components UserInterface.OnReceiveMessage += OnUiReceiveMessage; } + // Name relied upon by construction graph machine.yml to ensure beaker doesn't get deleted BeakerContainer = ContainerHelpers.EnsureContainer(Owner, $"{Name}-reagentContainerContainer"); diff --git a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs index 5b67810993..c04d0fd6ae 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemMasterSystem.cs @@ -1,7 +1,9 @@ using Content.Shared.Verbs; using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Components.SolutionManager; +using Content.Server.Construction.Components; using JetBrains.Annotations; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Content.Shared.ActionBlocker; diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index 27182c1c64..6d445fdec1 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -1,7 +1,9 @@ using Content.Shared.Verbs; using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Components.SolutionManager; +using Content.Server.Construction.Components; using JetBrains.Annotations; +using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Content.Shared.ActionBlocker; @@ -57,12 +59,6 @@ namespace Content.Server.Chemistry.EntitySystems !_actionBlockerSystem.CanDrop(args.User)) return; - if (!args.Using.HasComponent() || - !_solutionContainerSystem.TryGetSolution(args.Using.Uid, "beaker", out _)) - { - return; - } - Verb verb = new(); verb.Act = () => { diff --git a/Content.Server/Containers/EmptyOnMachineDeconstructComponent.cs b/Content.Server/Containers/EmptyOnMachineDeconstructComponent.cs new file mode 100644 index 0000000000..df36160665 --- /dev/null +++ b/Content.Server/Containers/EmptyOnMachineDeconstructComponent.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Containers +{ + /// + /// Empties a list of containers when the machine is deconstructed via MachineDeconstructedEvent. + /// + [RegisterComponent] + public class EmptyOnMachineDeconstructComponent : Component + { + public override string Name => "EmptyOnMachineDeconstruct"; + + [ViewVariables] + [DataField("containers")] + public HashSet Containers { get; set; } = new(); + } +} diff --git a/Content.Server/Containers/EmptyOnMachineDeconstructSystem.cs b/Content.Server/Containers/EmptyOnMachineDeconstructSystem.cs new file mode 100644 index 0000000000..19e358fc4d --- /dev/null +++ b/Content.Server/Containers/EmptyOnMachineDeconstructSystem.cs @@ -0,0 +1,37 @@ +using Content.Shared.Verbs; +using Content.Server.Construction.Components; +using JetBrains.Annotations; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Server.Containers +{ + /// + /// Implements functionality of EmptyOnMachineDeconstructComponent. + /// + [UsedImplicitly] + public class EmptyOnMachineDeconstructSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDeconstruct); + } + + private void OnDeconstruct(EntityUid uid, EmptyOnMachineDeconstructComponent component, MachineDeconstructedEvent ev) + { + if (!EntityManager.TryGetComponent(uid, out var mComp)) + return; + var baseCoords = component.Owner.Transform.Coordinates; + foreach (var v in component.Containers) + { + if (mComp.TryGetContainer(v, out var container)) + { + container.EmptyContainer(true, baseCoords); + } + } + } + } +} diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index 20d5242a46..824364b783 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -97,6 +97,23 @@ - Dropper - Syringe +- type: technology + name: "medical machinery" + id: MedicalMachinery + description: More machine power for more healing efficiency. + icon: + sprite: Structures/Machines/cloning.rsi + state: pod_0 + requiredPoints: 15000 + requiredTechnologies: + - BiologicalTechnology + - ChemistryTechnology + unlockedRecipes: + - CloningPodMachineCircuitboard + - MedicalScannerMachineCircuitboard + - ChemMasterMachineCircuitboard + - ChemDispenserMachineCircuitboard + # Security Technology Tree - type: technology @@ -228,7 +245,7 @@ description: Try not to fry yourself. icon: sprite: Structures/Power/apc.rsi - state: apcewires + state: apc0 requiredPoints: 10000 requiredTechnologies: - BasicResearch @@ -241,8 +258,6 @@ - FirelockElectronics - DoorElectronics - APCElectronics - - CloningPodMachineCircuitboard - - MedicalScannerMachineCircuitboard - HydroponicsTrayMachineCircuitboard - SolarControlComputerCircuitboard diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index 86a0dc0916..8905db795b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -58,6 +58,37 @@ Glass: 1 Cable: 1 +- type: entity + id: ChemMasterMachineCircuitboard + parent: BaseMachineCircuitboard + name: Chem Master (Machine Board) + components: + - type: MachineBoard + prototype: chem_master + requirements: + Manipulator: 1 + materialRequirements: + Glass: 1 + tagRequirements: + GlassBeaker: + Amount: 2 + DefaultPrototype: Beaker + ExamineName: Glass Beaker + +- type: entity + id: ChemDispenserMachineCircuitboard + parent: BaseMachineCircuitboard + name: Chem Dispenser (Machine Board) + components: + - type: MachineBoard + prototype: chem_dispenser + requirements: + Capacitor: 1 + Manipulator: 1 + MatterBin: 2 + materialRequirements: + Glass: 1 + - type: entity id: HydroponicsTrayMachineCircuitboard parent: BaseMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index d1f61978fb..a2822c9e9f 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -11,3 +11,26 @@ pack: ChemDispenserStandardInventory - type: ApcPowerReceiver - type: ExtensionCableReceiver + - type: Construction + graph: machine + node: machine + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] + - type: Machine + board: ChemDispenserMachineCircuitboard + - type: MaterialStorage + - type: Wires + BoardName: "chem_dispenser" + LayoutId: chem_dispenser + - type: EmptyOnMachineDeconstruct + containers: + - ReagentDispenser-reagentContainerContainer + diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index 0546cca23a..d6ec34b1c9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -1,6 +1,6 @@ - type: entity id: chem_master - parent: BaseStructure + parent: BaseMachinePowered name: ChemMaster 4000 description: An industrial grade chemical manipulator with pill and bottle production included. placement: @@ -16,10 +16,6 @@ sprite: Structures/Machines/mixer.rsi state: mixer_loaded - type: ChemMaster - - type: ApcPowerReceiver - - type: ExtensionCableReceiver - - type: InteractionOutline - - type: Anchorable - type: Physics bodyType: Static fixtures: @@ -32,73 +28,31 @@ layer: - Opaque - MobImpassable - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Metallic - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 50 behaviors: - - !type:SpawnEntitiesBehavior - spawn: - chem_master_broken: - min: 1 - max: 1 + - !type:ChangeConstructionNodeBehavior + node: machineFrame - !type:DoActsBehavior acts: [ "Destruction" ] - type: UserInterface interfaces: - key: enum.ChemMasterUiKey.Key type: ChemMasterBoundUserInterface + # Machine / Construction stuff + - type: Wires + BoardName: "chem_master" + LayoutId: chem_master + - type: Machine + board: ChemMasterMachineCircuitboard + - type: MaterialStorage + - type: Construction + graph: machine + node: machine + - type: EmptyOnMachineDeconstruct + containers: + - ChemMaster-reagentContainerContainer -- type: entity - id: chem_master_broken - parent: BaseStructureDynamic - name: ChemMaster 4000 - description: "An industrial grade chemical manipulator with pill and bottle production included. It's broken." - abstract: true - suffix: Broken - components: - - type: Sprite - sprite: Structures/Machines/mixer.rsi - layers: - - state: mixer_empty - - state: mixer_screen_broken - shader: unshaded - - type: Icon - sprite: Structures/Machines/mixer.rsi - state: mixer_broken - - type: InteractionOutline - - type: Physics - bodyType: Dynamic - fixtures: - - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.4,0.25,0.4" - mass: 25 - mask: - - SmallImpassable - layer: - - Opaque - - MobImpassable - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 25 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: UserInterface - interfaces: - - key: enum.ChemMasterUiKey.Key - type: ChemMasterBoundUserInterface diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 76782d1648..1a8eec0241 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -174,6 +174,8 @@ - APCElectronics - CloningPodMachineCircuitboard - MedicalScannerMachineCircuitboard + - ChemMasterMachineCircuitboard + - ChemDispenserMachineCircuitboard - HydroponicsTrayMachineCircuitboard - SolarControlComputerCircuitboard - Bucket diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml b/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml index 93a7535235..0c59465441 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/machine.yml @@ -91,3 +91,4 @@ steps: - tool: Prying doAfter: 0.25 + diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index 9a1c12f36c..57d23c34cf 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -43,6 +43,24 @@ Steel: 100 Glass: 100 +- type: latheRecipe + id: ChemMasterMachineCircuitboard + icon: Objects/Misc/module.rsi/id_mod.png + result: ChemMasterMachineCircuitboard + completetime: 1000 + materials: + Steel: 100 + Glass: 100 + +- type: latheRecipe + id: ChemDispenserMachineCircuitboard + icon: Objects/Misc/module.rsi/id_mod.png + result: ChemDispenserMachineCircuitboard + completetime: 1000 + materials: + Steel: 100 + Glass: 100 + - type: latheRecipe id: SolarControlComputerCircuitboard icon: Objects/Misc/module.rsi/id_mod.png