diff --git a/Content.Server/Atmos/Piping/Unary/Components/GasCondenserComponent.cs b/Content.Server/Atmos/Piping/Unary/Components/GasCondenserComponent.cs new file mode 100644 index 0000000000..1db0b524bb --- /dev/null +++ b/Content.Server/Atmos/Piping/Unary/Components/GasCondenserComponent.cs @@ -0,0 +1,33 @@ +using Content.Server.Atmos.Piping.Unary.EntitySystems; + +namespace Content.Server.Atmos.Piping.Unary.Components; + +/// +/// Used for an entity that converts moles of gas into units of reagent. +/// +[RegisterComponent] +[Access(typeof(GasCondenserSystem))] +public sealed partial class GasCondenserComponent : Component +{ + /// + /// The ID for the pipe node. + /// + [DataField] + public string Inlet = "pipe"; + + /// + /// The ID for the solution. + /// + [DataField] + public string SolutionId = "tank"; + + /// + /// For a condenser, how many U of reagents are given per each mole of gas. + /// + /// + /// Derived from a standard of 500u per canister: + /// 400u / 1871.71051 moles per canister + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float MolesToReagentMultiplier = 0.2137f; +} diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCondenserSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCondenserSystem.cs new file mode 100644 index 0000000000..1b790b5cf0 --- /dev/null +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCondenserSystem.cs @@ -0,0 +1,73 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Server.Atmos.Piping.Components; +using Content.Server.Atmos.Piping.Unary.Components; +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; +using Content.Shared.Atmos; +using JetBrains.Annotations; +using Content.Server.Power.EntitySystems; +using Content.Shared.Chemistry.EntitySystems; + +namespace Content.Server.Atmos.Piping.Unary.EntitySystems; + +[UsedImplicitly] +public sealed class GasCondenserSystem : EntitySystem +{ + [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; + [Dependency] private readonly PowerReceiverSystem _power = default!; + [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; + [Dependency] private readonly SolutionContainerSystem _solution = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnCondenserUpdated); + } + + private void OnCondenserUpdated(EntityUid uid, GasCondenserComponent component, AtmosDeviceUpdateEvent args) + { + if (!(_power.IsPowered(uid) && TryComp(uid, out var receiver)) + || !TryComp(uid, out var nodeContainer) + || !_nodeContainer.TryGetNode(nodeContainer, component.Inlet, out PipeNode? inlet) + || !_solution.TryGetSolution(uid, component.SolutionId, out var solution)) + { + return; + } + + if (solution.AvailableVolume == 0 || inlet.Air.TotalMoles == 0) + return; + + var molesToConvert = NumberOfMolesToConvert(receiver, inlet.Air, args.dt); + var removed = inlet.Air.Remove(molesToConvert); + for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) + { + var moles = removed.Moles[i]; + if (moles <= 0) + continue; + + if (_atmosphereSystem.GetGas(i).Reagent is not {} gasReagent) + continue; + + var moleToReagentMultiplier = component.MolesToReagentMultiplier; + var amount = moles * moleToReagentMultiplier; + + if (_solution.TryAddReagent(uid, solution, gasReagent, amount, out var remaining)) + continue; + + // if we have leftover reagent, then convert it back to moles and put it back in the mixture. + inlet.Air.AdjustMoles(i, remaining.Float() / moleToReagentMultiplier); + } + } + + public float NumberOfMolesToConvert(ApcPowerReceiverComponent comp, GasMixture mix, float dt) + { + var hc = _atmosphereSystem.GetHeatCapacity(mix); + var alpha = 0.8f; // tuned to give us 1-ish u/second of reagent conversion + // ignores the energy needed to cool down the solution to the condensation point, but that probably adds too much difficulty and so let's not simulate that + var energy = comp.Load * dt; + return energy / (alpha * hc); + } +} diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionContainerSystem.cs index bb90351483..04ad17869f 100644 --- a/Content.Shared/Chemistry/EntitySystems/SolutionContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SolutionContainerSystem.cs @@ -374,6 +374,22 @@ public sealed partial class SolutionContainerSystem : EntitySystem return acceptedQuantity == reagentQuantity.Quantity; } + /// + /// Adds reagent of an Id to the container. + /// + /// + /// Container to which we are adding reagent + /// The Id of the reagent to add. + /// The amount of reagent to add. + /// If all the reagent could be added. + [PublicAPI] + public bool TryAddReagent(EntityUid targetUid, Solution targetSolution, string prototype, FixedPoint2 quantity, + float? temperature = null, ReagentData? data = null) + { + var reagent = new ReagentQuantity(prototype, quantity, data); + return TryAddReagent(targetUid, targetSolution, reagent, out _, temperature); + } + /// /// Adds reagent of an Id to the container. /// diff --git a/Resources/Locale/en-US/wires/wire-names.ftl b/Resources/Locale/en-US/wires/wire-names.ftl index aae87f9c53..4a94dc9ac6 100644 --- a/Resources/Locale/en-US/wires/wire-names.ftl +++ b/Resources/Locale/en-US/wires/wire-names.ftl @@ -3,6 +3,7 @@ wires-board-name-default = Wires wires-board-name-booze = BoozeDispenser wires-board-name-soda = SodaDispenser wires-board-name-thermomachine = Thermomachine +wires-board-name-condenser = Condenser wires-board-name-pa = Mk2 Particle Accelerator wires-board-name-highsec = HighSec Control wires-board-name-vessel = Vessel diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml index af4f8cba78..7af85a09f0 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml @@ -338,6 +338,21 @@ deconstructionTarget: null node: heater +- type: entity + id: CondenserMachineCircuitBoard + parent: BaseMachineCircuitboard + name: condenser machine board + description: A machine printed circuit board for a condenser. + components: + - type: Sprite + state: engineering + - type: MachineBoard + prototype: BaseGasCondenser + requirements: + MatterBin: 1 + materialRequirements: + Glass: 1 + - type: entity id: PortableScrubberMachineCircuitBoard parent: BaseMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 5972a6c976..730ecdf72d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -306,6 +306,8 @@ producingSound: /Audio/Machines/circuitprinter.ogg idleState: icon runningState: building + staticRecipes: + - CondenserMachineCircuitBoard dynamicRecipes: - ThermomachineFreezerMachineCircuitBoard - PortableScrubberMachineCircuitBoard diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index 0fdad5d967..05135da0ce 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -351,3 +351,89 @@ enabled: true - type: ApcPowerReceiver powerDisabled: false + +- type: entity + parent: [ BaseMachinePowered, ConstructibleMachine ] + id: BaseGasCondenser + name: condenser + description: Condenses gases into liquids. Now we just need some plumbing. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Structures/Piping/Atmospherics/condenser.rsi + snapCardinals: true + granularLayersRendering: true + layers: + - state: off + map: [ "enum.PowerDeviceVisualLayers.Powered" ] + - state: panel + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - state: pipe + map: [ "enum.PipeVisualLayers.Pipe" ] + renderingStrategy: Default + - state: fill-1 + map: ["enum.SolutionContainerLayers.Fill"] + visible: false + - state: trans + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + enum.PowerDeviceVisualLayers.Powered: + True: { state: on } + False: { state: off } + - type: SolutionContainerVisuals + maxFillLevels: 7 + fillBaseName: fill- + - type: Appearance + - type: PipeColorVisuals + - type: Rotatable + - type: GasCondenser + - type: AtmosPipeColor + - type: AtmosDevice + - type: ApcPowerReceiver + powerLoad: 10000 + - type: Machine + board: CondenserMachineCircuitBoard + - type: WiresPanel + - type: Wires + boardName: wires-board-name-condenser + layoutId: Condenser + - type: WiresVisuals + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpillBehavior + solution: tank + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/metalbreak.ogg + - type: NodeContainer + nodes: + pipe: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + - type: Transform + noRot: false + - type: SolutionContainerManager + solutions: + tank: + maxVol: 400 + canMix: true + - type: DrainableSolution + solution: tank + - type: ExaminableSolution + solution: tank + - type: PowerSwitch diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index 8477e6c9be..9ab48db864 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -104,6 +104,14 @@ Glass: 900 Gold: 50 +- type: latheRecipe + id: CondenserMachineCircuitBoard + result: CondenserMachineCircuitBoard + completetime: 4 + materials: + Steel: 100 + Glass: 900 + - type: latheRecipe id: PortableScrubberMachineCircuitBoard result: PortableScrubberMachineCircuitBoard diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-1.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-1.png new file mode 100644 index 0000000000..a030b2d524 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-1.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-2.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-2.png new file mode 100644 index 0000000000..9007c74cb3 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-2.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-3.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-3.png new file mode 100644 index 0000000000..364bd10840 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-3.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-4.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-4.png new file mode 100644 index 0000000000..efbfaf5c04 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-4.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-5.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-5.png new file mode 100644 index 0000000000..f87544fa82 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-5.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-6.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-6.png new file mode 100644 index 0000000000..1fabf81878 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-6.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-7.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-7.png new file mode 100644 index 0000000000..55e26a4d5a Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/fill-7.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json new file mode 100644 index 0000000000..591c223e5c --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json @@ -0,0 +1,60 @@ +{ + "version":1, + "size": + { + "x":32, + "y":32 + }, + "copyright":"Created by EmoGarbage404 (github) for Space Station 14.", + "license":"CC0-1.0", + "states": + [ + { + "name":"off" + }, + { + "name":"on", + "delays": + [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ] + ] + }, + { + "name":"panel" + }, + { + "name":"trans" + }, + { + "name":"pipe", + "directions":4 + }, + { + "name":"fill-1" + }, + { + "name":"fill-2" + }, + { + "name":"fill-3" + }, + { + "name":"fill-4" + }, + { + "name":"fill-5" + }, + { + "name":"fill-6" + }, + { + "name":"fill-7" + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/off.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/off.png new file mode 100644 index 0000000000..523adff6c3 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/off.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/on.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/on.png new file mode 100644 index 0000000000..268750001a Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/on.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/panel.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/panel.png new file mode 100644 index 0000000000..05c2f179fa Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/panel.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png new file mode 100644 index 0000000000..c9fbbec300 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/trans.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/trans.png new file mode 100644 index 0000000000..06e34a2e36 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/trans.png differ