initial commit - cross reference with 5th port - obviously has compile errors
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
/obj/machinery/atmospherics/components/binary
|
||||
icon = 'icons/obj/atmospherics/components/binary_devices.dmi'
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH
|
||||
use_power = 1
|
||||
device_type = BINARY
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/SetInitDirections()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
if(SOUTH)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
if(EAST)
|
||||
initialize_directions = EAST|WEST
|
||||
if(WEST)
|
||||
initialize_directions = EAST|WEST
|
||||
/*
|
||||
Iconnery
|
||||
*/
|
||||
/obj/machinery/atmospherics/components/binary/hide(intact)
|
||||
update_icon()
|
||||
|
||||
..(intact)
|
||||
/*
|
||||
Housekeeping and pipe network stuff
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/atmosinit()
|
||||
var/node2_connect = dir
|
||||
var/node1_connect = turn(dir, 180)
|
||||
|
||||
var/list/node_connects = list(node1_connect, node2_connect)
|
||||
..(node_connects)
|
||||
@@ -0,0 +1,70 @@
|
||||
//node2, air2, network2 correspond to input
|
||||
//node1, air1, network1 correspond to output
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/circulator
|
||||
name = "circulator/heat exchanger"
|
||||
desc = "A gas circulator pump and heat exchanger."
|
||||
icon_state = "circ1-off"
|
||||
|
||||
var/side = CIRC_LEFT
|
||||
var/status = 0
|
||||
|
||||
var/last_pressure_delta = 0
|
||||
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
var/global/const/CIRC_LEFT = 1
|
||||
var/global/const/CIRC_RIGHT = 2
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/circulator/proc/return_transfer_air()
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
|
||||
var/output_starting_pressure = air1.return_pressure()
|
||||
var/input_starting_pressure = air2.return_pressure()
|
||||
|
||||
if(output_starting_pressure >= input_starting_pressure-10)
|
||||
//Need at least 10 KPa difference to overcome friction in the mechanism
|
||||
last_pressure_delta = 0
|
||||
return null
|
||||
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
if(air2.temperature>0)
|
||||
var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2
|
||||
|
||||
var/transfer_moles = pressure_delta*air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
last_pressure_delta = pressure_delta
|
||||
|
||||
//world << "pressure_delta = [pressure_delta]; transfer_moles = [transfer_moles];"
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air2.remove(transfer_moles)
|
||||
|
||||
update_parents()
|
||||
|
||||
return removed
|
||||
|
||||
else
|
||||
last_pressure_delta = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/circulator/process_atmos()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/circulator/update_icon()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
icon_state = "circ[side]-p"
|
||||
else if(last_pressure_delta > 0)
|
||||
if(last_pressure_delta > ONE_ATMOSPHERE)
|
||||
icon_state = "circ[side]-run"
|
||||
else
|
||||
icon_state = "circ[side]-slow"
|
||||
else
|
||||
icon_state = "circ[side]-off"
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
Acts like a normal vent, but has an input AND output.
|
||||
*/
|
||||
#define EXT_BOUND 1
|
||||
#define INPUT_MIN 2
|
||||
#define OUTPUT_MAX 4
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump
|
||||
icon = 'icons/obj/atmospherics/components/unary_devices.dmi' //We reuse the normal vent icons!
|
||||
icon_state = "dpvent_map"
|
||||
|
||||
//node2 is output port
|
||||
//node1 is input port
|
||||
|
||||
name = "dual-port air vent"
|
||||
desc = "Has a valve and pump attached to it. There are two ports."
|
||||
|
||||
level = 1
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/on = 0
|
||||
var/pump_direction = 1 //0 = siphoning, 1 = releasing
|
||||
|
||||
var/external_pressure_bound = ONE_ATMOSPHERE
|
||||
var/input_pressure_min = 0
|
||||
var/output_pressure_max = 0
|
||||
|
||||
var/pressure_checks = EXT_BOUND
|
||||
//EXT_BOUND: Do not pass external_pressure_bound
|
||||
//INPUT_MIN: Do not pass input_pressure_min
|
||||
//OUTPUT_MAX: Do not pass output_pressure_max
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src, frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume
|
||||
name = "large dual-port air vent"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
air1.volume = 1000
|
||||
air2.volume = 1000
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "dpvent_cap"))
|
||||
|
||||
if(!on || stat & (NOPOWER|BROKEN))
|
||||
icon_state = "vent_off"
|
||||
return
|
||||
|
||||
if(pump_direction)
|
||||
icon_state = "vent_out"
|
||||
else
|
||||
icon_state = "vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/process_atmos()
|
||||
..()
|
||||
|
||||
if(!on)
|
||||
return 0
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction) //input -> external
|
||||
var/pressure_delta = 10000
|
||||
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
|
||||
if(pressure_checks&INPUT_MIN)
|
||||
pressure_delta = min(pressure_delta, (air1.return_pressure() - input_pressure_min))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(air1.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
|
||||
var/datum/pipeline/parent1 = PARENT1
|
||||
parent1.update = 1
|
||||
|
||||
else //external -> output
|
||||
var/pressure_delta = 10000
|
||||
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&INPUT_MIN)
|
||||
pressure_delta = min(pressure_delta, (output_pressure_max - air2.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
|
||||
air2.merge(removed)
|
||||
air_update_turf()
|
||||
|
||||
var/datum/pipeline/parent2 = PARENT2
|
||||
parent2.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "ADVP",
|
||||
"power" = on,
|
||||
"direction" = pump_direction?("release"):("siphon"),
|
||||
"checks" = pressure_checks,
|
||||
"input" = input_pressure_min,
|
||||
"output" = output_pressure_max,
|
||||
"external" = external_pressure_bound,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/atmosinit()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/dp_vent_pump/receive_signal(datum/signal/signal)
|
||||
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("set_direction" in signal.data)
|
||||
pump_direction = text2num(signal.data["set_direction"])
|
||||
|
||||
if("checks" in signal.data)
|
||||
pressure_checks = text2num(signal.data["checks"])
|
||||
|
||||
if("purge" in signal.data)
|
||||
pressure_checks &= ~1
|
||||
pump_direction = 0
|
||||
|
||||
if("stabalize" in signal.data)
|
||||
pressure_checks |= 1
|
||||
pump_direction = 1
|
||||
|
||||
if("set_input_pressure" in signal.data)
|
||||
input_pressure_min = Clamp(text2num(signal.data["set_input_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
output_pressure_max = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
//if(signal.data["tag"])
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
|
||||
#undef EXT_BOUND
|
||||
#undef INPUT_MIN
|
||||
#undef OUTPUT_MAX
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
|
||||
Passive gate is similar to the regular pump except:
|
||||
* It doesn't require power
|
||||
* Can not transfer low pressure to higher pressure (so it's more like a valve where you can control the flow)
|
||||
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate
|
||||
icon_state = "passgate_map"
|
||||
|
||||
name = "passive gate"
|
||||
desc = "A one-way air valve that does not require power."
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/update_icon_nopipes()
|
||||
if(!on)
|
||||
icon_state = "passgate_off"
|
||||
cut_overlays()
|
||||
return
|
||||
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "passgate_on"))
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
var/input_starting_pressure = air1.return_pressure()
|
||||
|
||||
if(output_starting_pressure >= min(target_pressure,input_starting_pressure-10))
|
||||
//No need to pump gas if target is already reached or input pressure is too low
|
||||
//Need at least 10 KPa difference to overcome friction in the mechanism
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
if((air1.total_moles() > 0) && (air1.temperature>0))
|
||||
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure)/2)
|
||||
//Can not have a pressure delta that would cause output_pressure > input_pressure
|
||||
|
||||
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
air2.merge(removed)
|
||||
|
||||
update_parents()
|
||||
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AGP",
|
||||
"power" = on,
|
||||
"target_output" = target_pressure,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) || !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/atmosinit()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
var/old_on = on //for logging
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status()
|
||||
return
|
||||
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/passive_gate/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if(on)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
|
||||
|
||||
node1, air1, network1 correspond to input
|
||||
node2, air2, network2 correspond to output
|
||||
|
||||
Thus, the two variables affect pump operation are set in New():
|
||||
air1.volume
|
||||
This is the volume of gas available to the pump that may be transfered to the output
|
||||
air2.volume
|
||||
Higher quantities of this cause more air to be perfected later
|
||||
but overall network volume is also increased as this increases...
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump
|
||||
icon_state = "pump_map"
|
||||
name = "gas pump"
|
||||
desc = "A pump that moves gas by pressure."
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/on
|
||||
on = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
if(radio_connection)
|
||||
radio_connection = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/update_icon_nopipes()
|
||||
if(stat & NOPOWER)
|
||||
icon_state = "pump_off"
|
||||
return
|
||||
|
||||
icon_state = "pump_[on?"on":"off"]"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/process_atmos()
|
||||
// ..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
|
||||
if((target_pressure - output_starting_pressure) < 0.01)
|
||||
//No need to pump gas if target is already reached!
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
if((air1.total_moles() > 0) && (air1.temperature>0))
|
||||
var/pressure_delta = target_pressure - output_starting_pressure
|
||||
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
air2.merge(removed)
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
//Radio remote control
|
||||
/obj/machinery/atmospherics/components/binary/pump/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AGP",
|
||||
"power" = on,
|
||||
"target_output" = target_pressure,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 335, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/atmosinit()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
var/old_on = on //for logging
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("set_output_pressure" in signal.data)
|
||||
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status()
|
||||
return
|
||||
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/pump/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if(!(stat & NOPOWER) && on)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
It's like a regular ol' straight pipe, but you can turn it on and off.
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve
|
||||
icon_state = "mvalve_map"
|
||||
name = "manual valve"
|
||||
desc = "A pipe valve"
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
|
||||
var/open = 0
|
||||
var/valve_type = "m" //lets us have a nice, clean, OOP update_icon_nopipes()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/open
|
||||
open = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/update_icon_nopipes(animation = 0)
|
||||
normalize_dir()
|
||||
if(animation)
|
||||
flick("[valve_type]valve_[open][!open]",src)
|
||||
icon_state = "[valve_type]valve_[open?"on":"off"]"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/proc/open()
|
||||
open = 1
|
||||
update_icon_nopipes()
|
||||
update_parents()
|
||||
var/datum/pipeline/parent1 = PARENT1
|
||||
parent1.reconcile_air()
|
||||
investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/proc/close()
|
||||
open = 0
|
||||
update_icon_nopipes()
|
||||
investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/proc/normalize_dir()
|
||||
if(dir==SOUTH)
|
||||
setDir(NORTH)
|
||||
else if(dir==WEST)
|
||||
setDir(EAST)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/attack_ai(mob/user)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/attack_hand(mob/user)
|
||||
add_fingerprint(usr)
|
||||
update_icon_nopipes(1)
|
||||
sleep(10)
|
||||
if(open)
|
||||
close()
|
||||
return
|
||||
open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/digital // can be controlled by AI
|
||||
name = "digital valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon_state = "dvalve_map"
|
||||
valve_type = "d"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/digital/attack_ai(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/valve/digital/update_icon_nopipes(animation)
|
||||
if(stat & NOPOWER)
|
||||
normalize_dir()
|
||||
icon_state = "dvalve_nopower"
|
||||
return
|
||||
..()
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
Every cycle, the pump uses the air in air_in to try and make air_out the perfect pressure.
|
||||
|
||||
node1, air1, network1 correspond to input
|
||||
node2, air2, network2 correspond to output
|
||||
|
||||
Thus, the two variables affect pump operation are set in New():
|
||||
air1.volume
|
||||
This is the volume of gas available to the pump that may be transfered to the output
|
||||
air2.volume
|
||||
Higher quantities of this cause more air to be perfected later
|
||||
but overall network volume is also increased as this increases...
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump
|
||||
icon_state = "volpump_map"
|
||||
name = "volumetric gas pump"
|
||||
desc = "A pump that moves gas by volume."
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/transfer_rate = MAX_TRANSFER_RATE
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/on
|
||||
on = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/update_icon_nopipes()
|
||||
if(stat & NOPOWER)
|
||||
icon_state = "volpump_off"
|
||||
return
|
||||
|
||||
icon_state = "volpump_[on?"on":"off"]"
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/process_atmos()
|
||||
// ..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
|
||||
// Pump mechanism just won't do anything if the pressure is too high/too low
|
||||
|
||||
var/input_starting_pressure = air1.return_pressure()
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
|
||||
if((input_starting_pressure < 0.01) || (output_starting_pressure > 9000))
|
||||
return 1
|
||||
|
||||
var/transfer_ratio = min(1, transfer_rate/air1.volume)
|
||||
|
||||
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
|
||||
|
||||
air2.merge(removed)
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "APV",
|
||||
"power" = on,
|
||||
"transfer_rate" = transfer_rate,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_pump", name, 310, 115, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["rate"] = round(transfer_rate)
|
||||
data["max_rate"] = round(MAX_TRANSFER_RATE)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/atmosinit()
|
||||
..()
|
||||
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("rate")
|
||||
var/rate = params["rate"]
|
||||
if(rate == "max")
|
||||
rate = MAX_TRANSFER_RATE
|
||||
. = TRUE
|
||||
else if(rate == "input")
|
||||
rate = input("New transfer rate (0-[MAX_TRANSFER_RATE] L/s):", name, transfer_rate) as num|null
|
||||
if(!isnull(rate) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(rate) != null)
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
var/old_on = on //for logging
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("set_transfer_rate" in signal.data)
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
|
||||
|
||||
if(on != old_on)
|
||||
investigate_log("was turned [on ? "on" : "off"] by a remote signal", "atmos")
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/binary/volume_pump/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if(!(stat & NOPOWER) && on)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
So much of atmospherics.dm was used solely by components, so separating this makes things all a lot cleaner.
|
||||
On top of that, now people can add component-speciic procs/vars if they want!
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components
|
||||
var/welded = 0 //Used on pumps and scrubbers
|
||||
var/showpipe = 0
|
||||
|
||||
var/list/datum/pipeline/parents = list()
|
||||
var/list/datum/gas_mixture/airs = list()
|
||||
|
||||
/obj/machinery/atmospherics/components/New()
|
||||
parents.len = device_type
|
||||
airs.len = device_type
|
||||
..()
|
||||
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
var/datum/gas_mixture/A = new
|
||||
A.volume = 200
|
||||
AIR_I = A
|
||||
/*
|
||||
Iconnery
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/icon_addintact(var/obj/machinery/atmospherics/node)
|
||||
var/image/img = getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_intact", get_dir(src,node), node.pipe_color)
|
||||
underlays += img
|
||||
|
||||
return img.dir
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/icon_addbroken(var/connected = 0)
|
||||
var/unconnected = (~connected) & initialize_directions
|
||||
for(var/direction in cardinal)
|
||||
if(unconnected & direction)
|
||||
underlays += getpipeimage('icons/obj/atmospherics/components/binary_devices.dmi', "pipe_exposed", direction)
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/update_icon_nopipes()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/update_icon()
|
||||
update_icon_nopipes()
|
||||
|
||||
underlays.Cut()
|
||||
|
||||
var/turf/T = loc
|
||||
if(level == 2 || !T.intact)
|
||||
showpipe = 1
|
||||
else
|
||||
showpipe = 0
|
||||
|
||||
if(!showpipe)
|
||||
return //no need to update the pipes if they aren't showing
|
||||
|
||||
var/connected = 0
|
||||
|
||||
for(DEVICE_TYPE_LOOP) //adds intact pieces
|
||||
if(NODE_I)
|
||||
connected |= icon_addintact(NODE_I)
|
||||
|
||||
icon_addbroken(connected) //adds broken pieces
|
||||
|
||||
|
||||
/*
|
||||
Pipenet stuff; housekeeping
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/nullifyNode(I)
|
||||
..()
|
||||
if(NODE_I)
|
||||
nullifyPipenet(PARENT_I)
|
||||
qdel(AIR_I)
|
||||
AIR_I = null
|
||||
|
||||
/obj/machinery/atmospherics/components/construction()
|
||||
..()
|
||||
update_parents()
|
||||
|
||||
/obj/machinery/atmospherics/components/build_network()
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
if(!PARENT_I)
|
||||
PARENT_I = new /datum/pipeline()
|
||||
var/datum/pipeline/P = PARENT_I
|
||||
P.build_pipeline(src)
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
|
||||
var/I = parents.Find(reference)
|
||||
reference.other_airs -= AIR_I
|
||||
reference.other_atmosmch -= src
|
||||
PARENT_I = null
|
||||
|
||||
/obj/machinery/atmospherics/components/returnPipenetAir(datum/pipeline/reference)
|
||||
var/I = parents.Find(reference)
|
||||
return AIR_I
|
||||
|
||||
/obj/machinery/atmospherics/components/pipeline_expansion(datum/pipeline/reference)
|
||||
if(reference)
|
||||
var/I = parents.Find(reference)
|
||||
return list(NODE_I)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/setPipenet(datum/pipeline/reference, obj/machinery/atmospherics/A)
|
||||
var/I = nodes.Find(A)
|
||||
PARENT_I = reference
|
||||
|
||||
/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = NODE1) //returns PARENT1 if called without argument
|
||||
var/I = nodes.Find(A)
|
||||
return PARENT_I
|
||||
|
||||
/obj/machinery/atmospherics/components/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
|
||||
var/I = parents.Find(Old)
|
||||
PARENT_I = New
|
||||
|
||||
/obj/machinery/atmospherics/components/unsafe_pressure_release(var/mob/user, var/pressures)
|
||||
..()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
//Remove the gas from airs and assume it
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/lost = null
|
||||
var/times_lost = 0
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
var/datum/gas_mixture/air = AIR_I
|
||||
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION)
|
||||
times_lost++
|
||||
var/shared_loss = lost/times_lost
|
||||
|
||||
var/datum/gas_mixture/to_release
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
var/datum/gas_mixture/air = AIR_I
|
||||
if(!to_release)
|
||||
to_release = air.remove(shared_loss)
|
||||
continue
|
||||
to_release.merge(air.remove(shared_loss))
|
||||
T.assume_air(to_release)
|
||||
air_update_turf(1)
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/safe_input(var/title, var/text, var/default_set)
|
||||
var/new_value = input(usr,text,title,default_set) as num
|
||||
if(usr.canUseTopic(src))
|
||||
return new_value
|
||||
return default_set
|
||||
|
||||
/*
|
||||
Helpers
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/proc/update_parents()
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
var/datum/pipeline/parent = PARENT_I
|
||||
if(!parent)
|
||||
throw EXCEPTION("Component is missing a pipenet! Rebuilding...")
|
||||
build_network()
|
||||
parent.update = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/returnPipenets()
|
||||
. = list()
|
||||
for(DEVICE_TYPE_LOOP)
|
||||
. += returnPipenet(NODE_I)
|
||||
|
||||
/*
|
||||
UI Stuff
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/ui_status(mob/user)
|
||||
if(allowed(user))
|
||||
return ..()
|
||||
user << "<span class='danger'>Access denied.</span>"
|
||||
return UI_CLOSE
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/obj/machinery/atmospherics/components/trinary/filter
|
||||
name = "gas filter"
|
||||
icon_state = "filter_off"
|
||||
density = 0
|
||||
can_unwrench = 1
|
||||
var/on = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
var/filter_type = ""
|
||||
var/frequency = 0
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/flipped
|
||||
icon_state = "filter_off_f"
|
||||
flipped = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/update_icon()
|
||||
cut_overlays()
|
||||
for(var/direction in cardinal)
|
||||
if(direction & initialize_directions)
|
||||
var/obj/machinery/atmospherics/node = findConnecting(direction)
|
||||
if(node)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color))
|
||||
continue
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction))
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes()
|
||||
|
||||
if(!(stat & NOPOWER) && on && NODE1 && NODE2 && NODE3)
|
||||
icon_state = "filter_on[flipped?"_f":""]"
|
||||
return
|
||||
|
||||
icon_state = "filter_off[flipped?"_f":""]"
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
on = 0
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
if(!(NODE1 && NODE2 && NODE3))
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
var/datum/gas_mixture/air3 = AIR3
|
||||
|
||||
var/output_starting_pressure = air3.return_pressure()
|
||||
|
||||
if(output_starting_pressure >= target_pressure)
|
||||
//No need to mix if target is already full!
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/pressure_delta = target_pressure - output_starting_pressure
|
||||
var/transfer_moles
|
||||
|
||||
if(air1.temperature > 0)
|
||||
transfer_moles = pressure_delta*air3.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Actually transfer the gas
|
||||
|
||||
if(transfer_moles > 0)
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
|
||||
if(!removed)
|
||||
return
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
if(filter_type && removed.gases[filter_type])
|
||||
filtered_out.assert_gas(filter_type)
|
||||
filtered_out.gases[filter_type][MOLES] = removed.gases[filter_type][MOLES]
|
||||
removed.gases[filter_type][MOLES] = 0
|
||||
removed.garbage_collect()
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
air2.merge(filtered_out)
|
||||
air3.merge(removed)
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/atmosinit()
|
||||
set_frequency(frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_filter", name, 475, 140, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
data["filter_type"] = filter_type
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/filter/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if("filter")
|
||||
filter_type = ""
|
||||
var/filter_name = "nothing"
|
||||
var/gas = params["mode"]
|
||||
if(gas in meta_gas_info)
|
||||
filter_type = gas
|
||||
filter_name = meta_gas_info[gas][META_GAS_NAME]
|
||||
investigate_log("was set to filter [filter_name] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
update_icon()
|
||||
@@ -0,0 +1,170 @@
|
||||
/obj/machinery/atmospherics/components/trinary/mixer
|
||||
icon_state = "mixer_off"
|
||||
density = 0
|
||||
|
||||
name = "gas mixer"
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
var/node1_concentration = 0.5
|
||||
var/node2_concentration = 0.5
|
||||
|
||||
//node 3 is the outlet, nodes 1 & 2 are intakes
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/flipped
|
||||
icon_state = "mixer_off_f"
|
||||
flipped = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/update_icon()
|
||||
cut_overlays()
|
||||
for(var/direction in cardinal)
|
||||
if(direction & initialize_directions)
|
||||
var/obj/machinery/atmospherics/node = findConnecting(direction)
|
||||
if(node)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction, node.pipe_color))
|
||||
continue
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/trinary_devices.dmi', "cap", direction))
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes()
|
||||
if(!(stat & NOPOWER) && on && NODE1 && NODE2 && NODE3)
|
||||
icon_state = "mixer_on[flipped?"_f":""]"
|
||||
return
|
||||
|
||||
icon_state = "mixer_off[flipped?"_f":""]"
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(stat & NOPOWER)
|
||||
on = 0
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air3 = AIR3
|
||||
air3.volume = 300
|
||||
AIR3 = air3
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
if(!(NODE1 && NODE2 && NODE3))
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
var/datum/gas_mixture/air2 = AIR2
|
||||
var/datum/gas_mixture/air3 = AIR3
|
||||
|
||||
var/output_starting_pressure = air3.return_pressure()
|
||||
|
||||
if(output_starting_pressure >= target_pressure)
|
||||
//No need to mix if target is already full!
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/pressure_delta = target_pressure - output_starting_pressure
|
||||
var/transfer_moles1 = 0
|
||||
var/transfer_moles2 = 0
|
||||
|
||||
if(air1.temperature > 0)
|
||||
transfer_moles1 = (node1_concentration * pressure_delta) * air3.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
if(air2.temperature > 0)
|
||||
transfer_moles2 = (node2_concentration * pressure_delta) * air3.volume / (air2.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/air1_moles = air1.total_moles()
|
||||
var/air2_moles = air2.total_moles()
|
||||
|
||||
if((air1_moles < transfer_moles1) || (air2_moles < transfer_moles2))
|
||||
var/ratio = 0
|
||||
if((transfer_moles1 > 0 ) && (transfer_moles2 > 0))
|
||||
ratio = min(air1_moles / transfer_moles1, air2_moles / transfer_moles2)
|
||||
if((transfer_moles2 == 0 ) && ( transfer_moles1 > 0))
|
||||
ratio = air1_moles / transfer_moles1
|
||||
if((transfer_moles1 == 0 ) && ( transfer_moles2 > 0))
|
||||
ratio = air2_moles / transfer_moles2
|
||||
|
||||
transfer_moles1 *= ratio
|
||||
transfer_moles2 *= ratio
|
||||
|
||||
//Actually transfer the gas
|
||||
|
||||
if(transfer_moles1 > 0)
|
||||
var/datum/gas_mixture/removed1 = air1.remove(transfer_moles1)
|
||||
air3.merge(removed1)
|
||||
|
||||
if(transfer_moles2 > 0)
|
||||
var/datum/gas_mixture/removed2 = air2.remove(transfer_moles2)
|
||||
air3.merge(removed2)
|
||||
|
||||
if(transfer_moles1)
|
||||
var/datum/pipeline/parent1 = PARENT1
|
||||
parent1.update = TRUE
|
||||
|
||||
if(transfer_moles2)
|
||||
var/datum/pipeline/parent2 = PARENT2
|
||||
parent2.update = TRUE
|
||||
|
||||
var/datum/pipeline/parent3 = PARENT3
|
||||
parent3.update = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_mixer", name, 370, 165, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_data()
|
||||
var/data = list()
|
||||
data["on"] = on
|
||||
data["set_pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
data["node1_concentration"] = round(node1_concentration*100)
|
||||
data["node2_concentration"] = round(node2_concentration*100)
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/mixer/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("pressure")
|
||||
var/pressure = params["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if("node1")
|
||||
var/value = text2num(params["concentration"])
|
||||
node1_concentration = max(0, min(1, node1_concentration + value))
|
||||
node2_concentration = max(0, min(1, node2_concentration - value))
|
||||
investigate_log("was set to [node1_concentration] % on node 1 by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("node2")
|
||||
var/value = text2num(params["concentration"])
|
||||
node2_concentration = max(0, min(1, node2_concentration + value))
|
||||
node1_concentration = max(0, min(1, node1_concentration - value))
|
||||
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
update_icon()
|
||||
@@ -0,0 +1,47 @@
|
||||
/obj/machinery/atmospherics/components/trinary
|
||||
icon = 'icons/obj/atmospherics/components/trinary_devices.dmi'
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH|WEST
|
||||
use_power = 1
|
||||
device_type = TRINARY
|
||||
|
||||
var/flipped = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/SetInitDirections()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = EAST|NORTH|SOUTH
|
||||
if(SOUTH)
|
||||
initialize_directions = SOUTH|WEST|NORTH
|
||||
if(EAST)
|
||||
initialize_directions = EAST|WEST|SOUTH
|
||||
if(WEST)
|
||||
initialize_directions = WEST|NORTH|EAST
|
||||
|
||||
/*
|
||||
Housekeeping and pipe network stuff
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/trinary/atmosinit()
|
||||
|
||||
//Mixer:
|
||||
//1 and 2 is input
|
||||
//Node 3 is output
|
||||
//If we flip the mixer, 1 and 3 shall exchange positions
|
||||
|
||||
//Filter:
|
||||
//Node 1 is input
|
||||
//Node 2 is filtered output
|
||||
//Node 3 is rest output
|
||||
//If we flip the filter, 1 and 3 shall exchange positions
|
||||
|
||||
var/node1_connect = turn(dir, -180)
|
||||
var/node2_connect = turn(dir, -90)
|
||||
var/node3_connect = dir
|
||||
|
||||
if(flipped)
|
||||
node1_connect = turn(node1_connect, 180)
|
||||
node3_connect = turn(node3_connect, 180)
|
||||
|
||||
var/list/node_connects = list(node1_connect, node2_connect, node3_connect)
|
||||
..(node_connects)
|
||||
@@ -0,0 +1,271 @@
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell
|
||||
name = "cryo cell"
|
||||
icon = 'icons/obj/cryogenics.dmi'
|
||||
icon_state = "cell-off"
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
var/on = FALSE
|
||||
state_open = FALSE
|
||||
var/autoeject = FALSE
|
||||
var/volume = 100
|
||||
|
||||
var/efficiency = 1
|
||||
var/sleep_factor = 750
|
||||
var/paralyze_factor = 1000
|
||||
var/heat_capacity = 20000
|
||||
var/conduction_coefficient = 0.30
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
var/reagent_transfer = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/New()
|
||||
..()
|
||||
initialize_directions = dir
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/cryo_tube(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/cryo_tube
|
||||
name = "circuit board (Cryotube)"
|
||||
build_path = /obj/machinery/atmospherics/components/unary/cryo_cell
|
||||
origin_tech = "programming=4;biotech=3;engineering=4;plasmatech=3"
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1,
|
||||
/obj/item/stack/sheet/glass = 2)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/construction()
|
||||
..(dir, dir)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/RefreshParts()
|
||||
var/C
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
C += M.rating
|
||||
|
||||
efficiency = initial(efficiency) * C
|
||||
sleep_factor = initial(sleep_factor) * C
|
||||
paralyze_factor = initial(paralyze_factor) * C
|
||||
heat_capacity = initial(heat_capacity) / C
|
||||
conduction_coefficient = initial(conduction_coefficient) * C
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/Destroy()
|
||||
beaker = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/update_icon()
|
||||
if(panel_open)
|
||||
icon_state = "cell-o"
|
||||
else if(state_open)
|
||||
icon_state = "cell-open"
|
||||
else if(on && is_operational())
|
||||
if(occupant)
|
||||
icon_state = "cell-occupied"
|
||||
else
|
||||
icon_state = "cell-on"
|
||||
else
|
||||
icon_state = "cell-off"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/process()
|
||||
..()
|
||||
if(!on)
|
||||
return
|
||||
if(!is_operational())
|
||||
on = FALSE
|
||||
update_icon()
|
||||
return
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
if(occupant)
|
||||
if(occupant.health >= 100) // Don't bother with fully healed people.
|
||||
on = FALSE
|
||||
update_icon()
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', volume, 1) // Bug the doctors.
|
||||
if(autoeject) // Eject if configured.
|
||||
open_machine()
|
||||
return
|
||||
else if(occupant.stat == DEAD) // We don't bother with dead people.
|
||||
return
|
||||
|
||||
if(occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
|
||||
occupant.Sleeping((occupant.bodytemperature / sleep_factor) * 100)
|
||||
occupant.Paralyse((occupant.bodytemperature / paralyze_factor) * 100)
|
||||
|
||||
if(beaker)
|
||||
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
|
||||
beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic.
|
||||
beaker.reagents.reaction(occupant, VAPOR)
|
||||
air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this.
|
||||
if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker).
|
||||
reagent_transfer = 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
if(!NODE1 || !AIR1 || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work.
|
||||
on = FALSE
|
||||
update_icon()
|
||||
return
|
||||
if(occupant)
|
||||
var/cold_protection = 0
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
if(istype(H))
|
||||
cold_protection = H.get_cold_protection(air1.temperature)
|
||||
|
||||
var/temperature_delta = air1.temperature - occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant.
|
||||
if(abs(temperature_delta) > 1)
|
||||
var/air_heat_capacity = air1.heat_capacity()
|
||||
var/heat = ((1 - cold_protection) / 10 + conduction_coefficient) \
|
||||
* temperature_delta * \
|
||||
(air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity))
|
||||
air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB)
|
||||
occupant.bodytemperature = max(occupant.bodytemperature + heat / heat_capacity, TCMB)
|
||||
|
||||
air1.gases["o2"][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/open_machine()
|
||||
if(!state_open && !panel_open)
|
||||
on = FALSE
|
||||
..()
|
||||
if(beaker)
|
||||
beaker.loc = src
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/close_machine(mob/living/carbon/user)
|
||||
if((isnull(user) || istype(user)) && state_open && !panel_open)
|
||||
..(user)
|
||||
return occupant
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/user)
|
||||
user << "<span class='notice'>You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds.)</span>"
|
||||
audible_message("<span class='notice'>You hear a thump from [src].</span>")
|
||||
if(do_after(user, 300))
|
||||
if(occupant == user) // Check they're still here.
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user)
|
||||
..()
|
||||
if(occupant)
|
||||
if(on)
|
||||
user << "Someone's inside [src]!"
|
||||
else
|
||||
user << "You can barely make out a form floating in [src]."
|
||||
else
|
||||
user << "[src] seems empty."
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
. = 1 //no afterattack
|
||||
if(!user.drop_item())
|
||||
return
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into [src]!</span>"
|
||||
return
|
||||
beaker = I
|
||||
I.loc = src
|
||||
user.visible_message("[user] places [I] in [src].", \
|
||||
"<span class='notice'>You place [I] in [src].</span>")
|
||||
return
|
||||
if(!on && !occupant && !state_open)
|
||||
if(default_deconstruction_screwdriver(user, "cell-o", "cell-off", I))
|
||||
return
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
if(default_change_direction_wrench(user, I))
|
||||
return
|
||||
if(default_pry_open(I))
|
||||
return
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "cryo", name, 400, 550, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()
|
||||
var/list/data = list()
|
||||
data["isOperating"] = on
|
||||
data["hasOccupant"] = occupant ? 1 : 0
|
||||
data["isOpen"] = state_open
|
||||
data["autoEject"] = autoeject
|
||||
|
||||
var/list/occupantData = list()
|
||||
if(occupant)
|
||||
occupantData["name"] = occupant.name
|
||||
occupantData["stat"] = occupant.stat
|
||||
occupantData["health"] = occupant.health
|
||||
occupantData["maxHealth"] = occupant.maxHealth
|
||||
occupantData["minHealth"] = config.health_threshold_dead
|
||||
occupantData["bruteLoss"] = occupant.getBruteLoss()
|
||||
occupantData["oxyLoss"] = occupant.getOxyLoss()
|
||||
occupantData["toxLoss"] = occupant.getToxLoss()
|
||||
occupantData["fireLoss"] = occupant.getFireLoss()
|
||||
occupantData["bodyTemperature"] = occupant.bodytemperature
|
||||
data["occupant"] = occupantData
|
||||
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
data["cellTemperature"] = round(air1.temperature)
|
||||
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
var beakerContents = list()
|
||||
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents += list(list("name" = R.name, "volume" = R.volume))
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
if(on)
|
||||
on = FALSE
|
||||
else if(!state_open)
|
||||
on = TRUE
|
||||
. = TRUE
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("autoeject")
|
||||
autoeject = !autoeject
|
||||
. = TRUE
|
||||
if("ejectbeaker")
|
||||
if(beaker)
|
||||
beaker.loc = loc
|
||||
beaker = null
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
|
||||
return //we don't see the pipe network while inside cryo.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user)
|
||||
user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through()
|
||||
return //can't ventcrawl in or out of cryo.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
|
||||
return 0 //you can't see the pipe network when inside a cryo cell.
|
||||
@@ -0,0 +1,20 @@
|
||||
/obj/machinery/atmospherics/components/unary/generator_input
|
||||
|
||||
icon_state = "he_intact"
|
||||
density = 1
|
||||
|
||||
name = "generator input"
|
||||
desc = "Placeholder"
|
||||
|
||||
var/update_cycle
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/generator_input/update_icon()
|
||||
if(NODE1)
|
||||
icon_state = "intact"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/generator_input/proc/return_exchange_air()
|
||||
return AIR1
|
||||
@@ -0,0 +1,69 @@
|
||||
/obj/machinery/atmospherics/components/unary/heat_exchanger
|
||||
|
||||
icon_state = "he_intact"
|
||||
|
||||
name = "heat exchanger"
|
||||
desc = "Exchanges heat between two input gases. Setup for fast heat transfer"
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/obj/machinery/atmospherics/components/unary/heat_exchanger/partner = null
|
||||
var/update_cycle
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/heat_exchanger/update_icon()
|
||||
if(NODE1)
|
||||
icon_state = "he_intact"
|
||||
var/obj/machinery/atmospherics/node = NODE1
|
||||
color = node.color
|
||||
else
|
||||
icon_state = "he_exposed"
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/heat_exchanger/atmosinit()
|
||||
if(!partner)
|
||||
var/partner_connect = turn(dir,180)
|
||||
|
||||
for(var/obj/machinery/atmospherics/components/unary/heat_exchanger/target in get_step(src,partner_connect))
|
||||
if(target.dir & get_dir(src,target))
|
||||
partner = target
|
||||
partner.partner = src
|
||||
break
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/heat_exchanger/process_atmos()
|
||||
..()
|
||||
if(!partner)
|
||||
return 0
|
||||
|
||||
if(SSair.times_fired <= update_cycle)
|
||||
return 0
|
||||
|
||||
update_cycle = SSair.times_fired
|
||||
partner.update_cycle = SSair.times_fired
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
var/datum/gas_mixture/partner_air_contents = partner.AIR1
|
||||
|
||||
var/air_heat_capacity = air_contents.heat_capacity()
|
||||
var/other_air_heat_capacity = partner_air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = other_air_heat_capacity + air_heat_capacity
|
||||
|
||||
var/old_temperature = air_contents.temperature
|
||||
var/other_old_temperature = partner_air_contents.temperature
|
||||
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = partner_air_contents.temperature*other_air_heat_capacity + air_heat_capacity*air_contents.temperature
|
||||
|
||||
var/new_temperature = combined_energy/combined_heat_capacity
|
||||
air_contents.temperature = new_temperature
|
||||
partner_air_contents.temperature = new_temperature
|
||||
|
||||
if(abs(old_temperature-air_contents.temperature) > 1)
|
||||
update_parents()
|
||||
|
||||
if(abs(other_old_temperature-partner_air_contents.temperature) > 1)
|
||||
partner.update_parents()
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,141 @@
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector
|
||||
icon_state = "inje_map"
|
||||
use_power = 1
|
||||
|
||||
name = "air injector"
|
||||
desc = "Has a valve and pump attached to it"
|
||||
|
||||
var/on = 0
|
||||
var/injecting = 0
|
||||
|
||||
var/volume_rate = 50
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
level = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/Destroy()
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/on
|
||||
on = 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/update_icon_nopipes()
|
||||
if(!NODE1 || !on || stat & (NOPOWER|BROKEN))
|
||||
icon_state = "inje_off"
|
||||
return
|
||||
|
||||
icon_state = "inje_on"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/process_atmos()
|
||||
..()
|
||||
injecting = 0
|
||||
|
||||
if(!on || stat & NOPOWER)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/proc/inject()
|
||||
if(on || injecting)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
injecting = 1
|
||||
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
|
||||
update_parents()
|
||||
|
||||
flick("inje_inject", src)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AO",
|
||||
"power" = on,
|
||||
"volume_rate" = volume_rate,
|
||||
//"timestamp" = world.time,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/atmosinit()
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/outlet_injector/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("inject" in signal.data)
|
||||
spawn inject()
|
||||
return
|
||||
|
||||
if("set_volume_rate" in signal.data)
|
||||
var/number = text2num(signal.data["set_volume_rate"])
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
volume_rate = Clamp(number, 0, air_contents.volume)
|
||||
|
||||
if("status" in signal.data)
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
|
||||
//log_admin("DEBUG \[[world.timeofday]\]: outlet_injector/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]")
|
||||
//return
|
||||
spawn(2)
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
@@ -0,0 +1,54 @@
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator
|
||||
|
||||
icon_state = "o2gen_map"
|
||||
|
||||
name = "oxygen generator"
|
||||
desc = "Generates oxygen"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
|
||||
var/on = 0
|
||||
|
||||
var/oxygen_content = 10
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/update_icon_nopipes()
|
||||
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "scrub_cap", initialize_directions)) //it works for now
|
||||
|
||||
if(!NODE1 || !on || stat & BROKEN)
|
||||
icon_state = "o2gen_off"
|
||||
return
|
||||
|
||||
else
|
||||
icon_state = "o2gen_on"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
air_contents.volume = 50
|
||||
AIR1 = air_contents
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/oxygen_generator/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
var/total_moles = air_contents.total_moles()
|
||||
|
||||
if(total_moles < oxygen_content)
|
||||
var/current_heat_capacity = air_contents.heat_capacity()
|
||||
|
||||
var/added_oxygen = oxygen_content - total_moles
|
||||
|
||||
air_contents.temperature = (current_heat_capacity*air_contents.temperature + 20*added_oxygen*T0C)/(current_heat_capacity+20*added_oxygen)
|
||||
air_contents.assert_gas("o2")
|
||||
air_contents.gases["o2"][MOLES] += added_oxygen
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,40 @@
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector
|
||||
name = "connector port"
|
||||
desc = "For connecting portables devices related to atmospherics control."
|
||||
icon = 'icons/obj/atmospherics/components/unary_devices.dmi'
|
||||
icon_state = "connector_map" //Only for mapping purposes, so mappers can see direction
|
||||
can_unwrench = 1
|
||||
var/obj/machinery/portable_atmospherics/connected_device
|
||||
use_power = 0
|
||||
level = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
air_contents.volume = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/visible
|
||||
level = 2
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/process_atmos()
|
||||
if(!connected_device)
|
||||
return
|
||||
update_parents()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/Destroy()
|
||||
if(connected_device)
|
||||
connected_device.disconnect()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if(connected_device)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], detach [connected_device] first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/portables_connector/portableConnectorReturnAir()
|
||||
return connected_device.portableConnectorReturnAir()
|
||||
|
||||
/obj/proc/portableConnectorReturnAir()
|
||||
@@ -0,0 +1,49 @@
|
||||
#define AIR_CONTENTS (25*ONE_ATMOSPHERE)*(air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
/obj/machinery/atmospherics/components/unary/tank
|
||||
icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi'
|
||||
icon_state = "generic"
|
||||
name = "pressure tank"
|
||||
desc = "A large vessel containing pressurized gas."
|
||||
var/volume = 10000 //in liters, 1 meters by 1 meters by 2 meters
|
||||
density = 1
|
||||
var/gas_type = 0
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
if(gas_type)
|
||||
air_contents.assert_gas(gas_type)
|
||||
air_contents.gases[gas_type][MOLES] = AIR_CONTENTS
|
||||
name = "[name] ([air_contents.gases[gas_type][GAS_META][META_GAS_NAME]])"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/carbon_dioxide
|
||||
gas_type = "co2"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/toxins
|
||||
icon_state = "orange"
|
||||
gas_type = "plasma"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/oxygen_agent_b
|
||||
icon_state = "orange_2"
|
||||
gas_type = "agent_b"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/oxygen
|
||||
icon_state = "blue"
|
||||
gas_type = "o2"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/nitrogen
|
||||
icon_state = "red"
|
||||
gas_type = "n2"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/air
|
||||
icon_state = "grey"
|
||||
name = "pressure tank (Air)"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/tank/air/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
air_contents.assert_gases("o2", "n2")
|
||||
air_contents.gases["o2"][MOLES] = AIR_CONTENTS * 0.2
|
||||
air_contents.gases["n2"][MOLES] = AIR_CONTENTS * 0.8
|
||||
@@ -0,0 +1,232 @@
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine
|
||||
name = "thermomachine"
|
||||
desc = "Heats or cools gas in connected pipes."
|
||||
icon_state = "cold_map"
|
||||
var/icon_state_on = "cold_on"
|
||||
var/icon_state_open = "cold_off"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
var/on = FALSE
|
||||
var/min_temperature = 0
|
||||
var/max_temperature = 0
|
||||
var/target_temperature = T20C
|
||||
var/heat_capacity = 0
|
||||
var/interactive = TRUE // So mapmakers can disable interaction.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/New()
|
||||
..()
|
||||
initialize_directions = dir
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/thermomachine(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/thermomachine
|
||||
name = "circuit board (Thermomachine)"
|
||||
desc = "You can use a screwdriver to switch between heater and freezer."
|
||||
origin_tech = "programming=3;plasmatech=3"
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||
/obj/item/weapon/stock_parts/micro_laser = 2,
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/thermomachine/attackby(obj/item/I, mob/user, params)
|
||||
var/obj/item/weapon/circuitboard/machine/freezer = /obj/item/weapon/circuitboard/machine/thermomachine/freezer
|
||||
var/obj/item/weapon/circuitboard/machine/heater = /obj/item/weapon/circuitboard/machine/thermomachine/heater
|
||||
var/obj/item/weapon/circuitboard/machine/newtype
|
||||
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
var/new_setting = "Heater"
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
if(build_path == initial(heater.build_path))
|
||||
newtype = freezer
|
||||
new_setting = "Freezer"
|
||||
else
|
||||
newtype = heater
|
||||
name = initial(newtype.name)
|
||||
build_path = initial(newtype.build_path)
|
||||
user << "<span class='notice'>You change the circuitboard setting to \"[new_setting]\".</span>"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/construction()
|
||||
..(dir,dir)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/RefreshParts()
|
||||
var/B
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
B += M.rating
|
||||
heat_capacity = 5000 * ((B - 1) ** 2)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/update_icon()
|
||||
if(panel_open)
|
||||
icon_state = icon_state_open
|
||||
else if(on && is_operational())
|
||||
icon_state = icon_state_on
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage(icon, "scrub_cap", initialize_directions))
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/process_atmos()
|
||||
..()
|
||||
if(!on || !NODE1)
|
||||
return
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
|
||||
var/air_heat_capacity = air_contents.heat_capacity()
|
||||
var/combined_heat_capacity = heat_capacity + air_heat_capacity
|
||||
var/old_temperature = air_contents.temperature
|
||||
|
||||
if(combined_heat_capacity > 0)
|
||||
var/combined_energy = heat_capacity * target_temperature + air_heat_capacity * air_contents.temperature
|
||||
air_contents.temperature = combined_energy/combined_heat_capacity
|
||||
|
||||
var/temperature_delta= abs(old_temperature - air_contents.temperature)
|
||||
if(temperature_delta > 1)
|
||||
active_power_usage = (heat_capacity * temperature_delta) / 10 + idle_power_usage
|
||||
update_parents()
|
||||
else
|
||||
active_power_usage = idle_power_usage
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/attackby(obj/item/I, mob/user, params)
|
||||
if(!(on || state_open))
|
||||
if(default_deconstruction_screwdriver(user, icon_state_open, initial(icon_state), I))
|
||||
return
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
if(default_change_direction_wrench(user, I))
|
||||
return
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/default_change_direction_wrench(mob/user, obj/item/weapon/wrench/W)
|
||||
if(!..())
|
||||
return 0
|
||||
SetInitDirections()
|
||||
var/obj/machinery/atmospherics/node = NODE1
|
||||
if(node)
|
||||
node.disconnect(src)
|
||||
NODE1 = null
|
||||
nullifyPipenet(PARENT1)
|
||||
|
||||
atmosinit()
|
||||
node = NODE1
|
||||
if(node)
|
||||
node.atmosinit()
|
||||
node.addMember(src)
|
||||
build_network()
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_status(mob/user)
|
||||
if(interactive)
|
||||
return ..()
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "thermomachine", name, 400, 240, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
|
||||
data["min"] = min_temperature
|
||||
data["max"] = max_temperature
|
||||
data["target"] = target_temperature
|
||||
data["initial"] = initial(target_temperature)
|
||||
|
||||
var/datum/gas_mixture/air1 = AIR1
|
||||
data["temperature"] = air1.temperature
|
||||
data["pressure"] = air1.return_pressure()
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("power")
|
||||
on = !on
|
||||
use_power = 1 + on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if("target")
|
||||
var/target = params["target"]
|
||||
var/adjust = text2num(params["adjust"])
|
||||
if(target == "input")
|
||||
target = input("Set new target ([min_temperature]-[max_temperature] K):", name, target_temperature) as num|null
|
||||
if(!isnull(target) && !..())
|
||||
. = TRUE
|
||||
else if(adjust)
|
||||
target = target_temperature + adjust
|
||||
. = TRUE
|
||||
else if(text2num(target) != null)
|
||||
target = text2num(target)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_temperature = Clamp(target, min_temperature, max_temperature)
|
||||
investigate_log("was set to [target_temperature] K by [key_name(usr)]", "atmos")
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/freezer
|
||||
name = "freezer"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "freezer"
|
||||
icon_state_on = "freezer_1"
|
||||
icon_state_open = "freezer-o"
|
||||
max_temperature = T20C
|
||||
min_temperature = 170
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/New()
|
||||
..()
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/thermomachine/freezer(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/thermomachine/freezer
|
||||
name = "circuit board (Freezer)"
|
||||
build_path = /obj/machinery/atmospherics/components/unary/thermomachine/freezer
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/RefreshParts()
|
||||
..()
|
||||
var/L
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
|
||||
L += M.rating
|
||||
min_temperature = max(T0C - (initial(min_temperature) + L * 15), TCMB)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/heater
|
||||
name = "heater"
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "heater"
|
||||
icon_state_on = "heater_1"
|
||||
icon_state_open = "heater-o"
|
||||
max_temperature = 140
|
||||
min_temperature = T20C
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/heater/New()
|
||||
..()
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/thermomachine/heater(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/thermomachine/heater
|
||||
name = "circuit board (Heater)"
|
||||
build_path = /obj/machinery/atmospherics/components/unary/thermomachine/heater
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/thermomachine/heater/RefreshParts()
|
||||
..()
|
||||
var/L
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
|
||||
L += M.rating
|
||||
max_temperature = T20C + (initial(max_temperature) * L)
|
||||
@@ -0,0 +1,17 @@
|
||||
/obj/machinery/atmospherics/components/unary
|
||||
icon = 'icons/obj/atmospherics/components/unary_devices.dmi'
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
device_type = UNARY
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/SetInitDirections()
|
||||
initialize_directions = dir
|
||||
|
||||
/*
|
||||
Iconnery
|
||||
*/
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/hide(intact)
|
||||
update_icon()
|
||||
|
||||
..(intact)
|
||||
@@ -0,0 +1,301 @@
|
||||
#define EXT_BOUND 1
|
||||
#define INT_BOUND 2
|
||||
#define NO_BOUND 3
|
||||
|
||||
#define SIPHONING 0
|
||||
#define RELEASING 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump
|
||||
name = "air vent"
|
||||
desc = "Has a valve and pump attached to it"
|
||||
icon_state = "vent_map"
|
||||
use_power = 1
|
||||
can_unwrench = 1
|
||||
welded = 0
|
||||
level = 1
|
||||
|
||||
var/id_tag = null
|
||||
var/on = 0
|
||||
var/pump_direction = RELEASING
|
||||
|
||||
var/pressure_checks = EXT_BOUND
|
||||
var/external_pressure_bound = ONE_ATMOSPHERE
|
||||
var/internal_pressure_bound = 0
|
||||
//EXT_BOUND: Do not pass external_pressure_bound
|
||||
//INT_BOUND: Do not pass internal_pressure_bound
|
||||
//NO_BOUND: Do not pass either
|
||||
|
||||
var/frequency = 1439
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/on
|
||||
on = 1
|
||||
icon_state = "vent_out"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/siphon
|
||||
pump_direction = SIPHONING
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/siphon/on
|
||||
on = 1
|
||||
icon_state = "vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/New()
|
||||
..()
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/Destroy()
|
||||
var/area/A = get_area_master(src)
|
||||
A.air_vent_names -= id_tag
|
||||
A.air_vent_info -= id_tag
|
||||
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
radio_connection = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume
|
||||
name = "large air vent"
|
||||
power_channel = EQUIP
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
|
||||
..()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
air_contents.volume = 1000
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "vent_cap", initialize_directions))
|
||||
|
||||
if(welded)
|
||||
icon_state = "vent_welded"
|
||||
return
|
||||
|
||||
if(!NODE1 || !on || stat & (NOPOWER|BROKEN))
|
||||
icon_state = "vent_off"
|
||||
return
|
||||
|
||||
if(pump_direction & RELEASING)
|
||||
icon_state = "vent_out"
|
||||
else //pump_direction == SIPHONING
|
||||
icon_state = "vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/process_atmos()
|
||||
..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if (!NODE1)
|
||||
on = 0
|
||||
if(!on || welded)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction & RELEASING) //internal -> external
|
||||
var/pressure_delta = 10000
|
||||
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (external_pressure_bound - environment_pressure))
|
||||
if(pressure_checks&INT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (air_contents.return_pressure() - internal_pressure_bound))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(air_contents.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
|
||||
|
||||
loc.assume_air(removed)
|
||||
air_update_turf()
|
||||
|
||||
else //external -> internal
|
||||
var/pressure_delta = 10000
|
||||
if(pressure_checks&EXT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound))
|
||||
if(pressure_checks&INT_BOUND)
|
||||
pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure()))
|
||||
|
||||
if(pressure_delta > 0)
|
||||
if(environment.temperature > 0)
|
||||
var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
|
||||
if (isnull(removed)) //in space
|
||||
return
|
||||
|
||||
air_contents.merge(removed)
|
||||
air_update_turf()
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency,radio_filter_in)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id_tag,
|
||||
"frequency" = frequency,
|
||||
"device" = "VP",
|
||||
"timestamp" = world.time,
|
||||
"power" = on,
|
||||
"direction" = pump_direction ? "release" : "siphon",
|
||||
"checks" = pressure_checks,
|
||||
"internal" = internal_pressure_bound,
|
||||
"external" = external_pressure_bound,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
var/area/A = get_area_master(src)
|
||||
if(!A.air_vent_names[id_tag])
|
||||
name = "\improper [A.name] vent pump #[A.air_vent_names.len + 1]"
|
||||
A.air_vent_names[id_tag] = name
|
||||
A.air_vent_info[id_tag] = signal.data
|
||||
|
||||
radio_connection.post_signal(src, signal, radio_filter_out)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/atmosinit()
|
||||
//some vents work his own spesial way
|
||||
radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/receive_signal(datum/signal/signal)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
//log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/components/unary/vent_pump/receive_signal([signal.debug_print()])")
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if("purge" in signal.data)
|
||||
pressure_checks &= ~EXT_BOUND
|
||||
pump_direction = SIPHONING
|
||||
|
||||
if("stabalize" in signal.data)
|
||||
pressure_checks |= EXT_BOUND
|
||||
pump_direction = RELEASING
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("checks" in signal.data)
|
||||
pressure_checks = text2num(signal.data["checks"])
|
||||
|
||||
if("checks_toggle" in signal.data)
|
||||
pressure_checks = (pressure_checks?0:NO_BOUND)
|
||||
|
||||
if("direction" in signal.data)
|
||||
pump_direction = text2num(signal.data["direction"])
|
||||
|
||||
if("set_internal_pressure" in signal.data)
|
||||
internal_pressure_bound = Clamp(text2num(signal.data["set_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("set_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(text2num(signal.data["set_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("reset_external_pressure" in signal.data)
|
||||
external_pressure_bound = ONE_ATMOSPHERE
|
||||
|
||||
if("adjust_internal_pressure" in signal.data)
|
||||
internal_pressure_bound = Clamp(internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("adjust_external_pressure" in signal.data)
|
||||
external_pressure_bound = Clamp(external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),0,ONE_ATMOSPHERE*50)
|
||||
|
||||
if("init" in signal.data)
|
||||
name = signal.data["init"]
|
||||
return
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
|
||||
//log_admin("DEBUG \[[world.timeofday]\]: vent_pump/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]")
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if (WT.remove_fuel(0,user))
|
||||
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
|
||||
user << "<span class='notice'>You begin welding the vent...</span>"
|
||||
if(do_after(user, 20/W.toolspeed, target = src))
|
||||
if(!src || !WT.isOn()) return
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
if(!welded)
|
||||
user.visible_message("[user] welds the vent shut.", "<span class='notice'>You weld the vent shut.</span>", "<span class='italics'>You hear welding.</span>")
|
||||
welded = 1
|
||||
else
|
||||
user.visible_message("[user] unwelds the vent.", "<span class='notice'>You unweld the vent.</span>", "<span class='italics'>You hear welding.</span>")
|
||||
welded = 0
|
||||
update_icon()
|
||||
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if(!(stat & NOPOWER) && on)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/examine(mob/user)
|
||||
..()
|
||||
if(welded)
|
||||
user << "It seems welded shut."
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/power_change()
|
||||
..()
|
||||
update_icon_nopipes()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/can_crawl_through()
|
||||
return !welded
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/attack_alien(mob/user)
|
||||
if(!welded || !(do_after(user, 20, target = src)))
|
||||
return
|
||||
user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the vent", "You hear loud scraping noises.")
|
||||
welded = 0
|
||||
update_icon()
|
||||
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
|
||||
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
|
||||
|
||||
|
||||
#undef INT_BOUND
|
||||
#undef EXT_BOUND
|
||||
#undef NO_BOUND
|
||||
|
||||
#undef SIPHONING
|
||||
#undef RELEASING
|
||||
@@ -0,0 +1,352 @@
|
||||
#define SIPHONING 0
|
||||
#define SCRUBBING 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber
|
||||
name = "air scrubber"
|
||||
desc = "Has a valve and pump attached to it"
|
||||
icon_state = "scrub_map"
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 60
|
||||
can_unwrench = 1
|
||||
welded = 0
|
||||
level = 1
|
||||
|
||||
var/id_tag = null
|
||||
var/on = 0
|
||||
var/scrubbing = SCRUBBING //0 = siphoning, 1 = scrubbing
|
||||
|
||||
var/scrub_CO2 = 1
|
||||
var/scrub_Toxins = 0
|
||||
var/scrub_N2O = 0
|
||||
var/scrub_BZ = 0
|
||||
|
||||
var/volume_rate = 200
|
||||
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
|
||||
var/list/turf/adjacent_turfs = list()
|
||||
|
||||
var/frequency = 1439
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/New()
|
||||
..()
|
||||
if(!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/Destroy()
|
||||
var/area/A = get_area_master(src)
|
||||
A.air_scrub_names -= id_tag
|
||||
A.air_scrub_info -= id_tag
|
||||
|
||||
if(SSradio)
|
||||
SSradio.remove_object(src,frequency)
|
||||
radio_connection = null
|
||||
|
||||
for(var/I in adjacent_turfs)
|
||||
I = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/auto_use_power()
|
||||
if(!powered(power_channel))
|
||||
return 0
|
||||
if(!on || welded)
|
||||
return 0
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
|
||||
var/amount = idle_power_usage
|
||||
|
||||
if(scrubbing & SCRUBBING)
|
||||
if(scrub_CO2)
|
||||
amount += idle_power_usage
|
||||
if(scrub_Toxins)
|
||||
amount += idle_power_usage
|
||||
if(scrub_N2O)
|
||||
amount += idle_power_usage
|
||||
if(scrub_BZ)
|
||||
amount += idle_power_usage
|
||||
else //scrubbing == SIPHONING
|
||||
amount = active_power_usage
|
||||
|
||||
if(widenet)
|
||||
amount += amount * (adjacent_turfs.len * (adjacent_turfs.len / 2))
|
||||
use_power(amount, power_channel)
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
if(showpipe)
|
||||
add_overlay(getpipeimage('icons/obj/atmospherics/components/unary_devices.dmi', "scrub_cap", initialize_directions))
|
||||
|
||||
if(welded)
|
||||
icon_state = "scrub_welded"
|
||||
return
|
||||
|
||||
if(!NODE1 || !on || stat & (NOPOWER|BROKEN))
|
||||
icon_state = "scrub_off"
|
||||
return
|
||||
|
||||
if(scrubbing & SCRUBBING)
|
||||
icon_state = "scrub_on"
|
||||
else //scrubbing == SIPHONING
|
||||
icon_state = "scrub_purge"
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, frequency, radio_filter_in)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = 1 //radio signal
|
||||
signal.source = src
|
||||
signal.data = list(
|
||||
"tag" = id_tag,
|
||||
"frequency" = frequency,
|
||||
"device" = "VS",
|
||||
"timestamp" = world.time,
|
||||
"power" = on,
|
||||
"scrubbing" = scrubbing,
|
||||
"widenet" = widenet,
|
||||
"filter_co2" = scrub_CO2,
|
||||
"filter_toxins" = scrub_Toxins,
|
||||
"filter_n2o" = scrub_N2O,
|
||||
"filter_bz" = scrub_BZ,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
var/area/A = get_area_master(src)
|
||||
if(!A.air_scrub_names[id_tag])
|
||||
name = "\improper [A.name] air scrubber #[A.air_scrub_names.len + 1]"
|
||||
A.air_scrub_names[id_tag] = name
|
||||
A.air_scrub_info[id_tag] = signal.data
|
||||
|
||||
radio_connection.post_signal(src, signal, radio_filter_out)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit()
|
||||
radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null
|
||||
radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
check_turfs()
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos()
|
||||
..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if (!NODE1)
|
||||
on = 0
|
||||
if(!on || welded)
|
||||
return 0
|
||||
scrub(loc)
|
||||
if(widenet)
|
||||
for (var/turf/tile in adjacent_turfs)
|
||||
scrub(tile)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/scrub(var/turf/tile)
|
||||
if (!istype(tile))
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = tile.return_air()
|
||||
var/datum/gas_mixture/air_contents = AIR1
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
if(scrubbing & SCRUBBING)
|
||||
var/should_we_scrub = FALSE
|
||||
for(var/id in env_gases)
|
||||
if(id == "n2" || id == "o2")
|
||||
continue
|
||||
if(env_gases[id][MOLES])
|
||||
should_we_scrub = TRUE
|
||||
break
|
||||
if(should_we_scrub)
|
||||
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
|
||||
|
||||
//Take a gas sample
|
||||
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
|
||||
var/list/removed_gases = removed.gases
|
||||
if (isnull(removed)) //in space
|
||||
return
|
||||
|
||||
//Filter it
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
var/list/filtered_gases = filtered_out.gases
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
if(scrub_Toxins && removed_gases["plasma"])
|
||||
filtered_out.assert_gas("plasma")
|
||||
filtered_gases["plasma"][MOLES] = removed_gases["plasma"][MOLES]
|
||||
removed.gases["plasma"][MOLES] = 0
|
||||
|
||||
if(scrub_CO2 && removed_gases["co2"])
|
||||
filtered_out.assert_gas("co2")
|
||||
filtered_out.gases["co2"][MOLES] = removed_gases["co2"][MOLES]
|
||||
removed.gases["co2"][MOLES] = 0
|
||||
|
||||
if(removed_gases["agent_b"])
|
||||
filtered_out.assert_gas("agent_b")
|
||||
filtered_out.gases["agent_b"][MOLES] = removed_gases["agent_b"][MOLES]
|
||||
removed.gases["agent_b"][MOLES] = 0
|
||||
|
||||
if(scrub_N2O && removed_gases["n2o"])
|
||||
filtered_out.assert_gas("n2o")
|
||||
filtered_out.gases["n2o"][MOLES] = removed_gases["n2o"][MOLES]
|
||||
removed.gases["n2o"][MOLES] = 0
|
||||
|
||||
if(scrub_BZ && removed_gases["bz"])
|
||||
filtered_out.assert_gas("bz")
|
||||
filtered_out.gases["bz"][MOLES] = removed_gases["bz"][MOLES]
|
||||
removed.gases["bz"][MOLES] = 0
|
||||
|
||||
removed.garbage_collect()
|
||||
|
||||
//Remix the resulting gases
|
||||
air_contents.merge(filtered_out)
|
||||
|
||||
tile.assume_air(removed)
|
||||
tile.air_update_turf()
|
||||
|
||||
else //Just siphoning all air
|
||||
if (air_contents.return_pressure()>=50*ONE_ATMOSPHERE)
|
||||
return
|
||||
|
||||
var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
|
||||
|
||||
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
|
||||
|
||||
air_contents.merge(removed)
|
||||
tile.air_update_turf()
|
||||
|
||||
update_parents()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//There is no easy way for an object to be notified of changes to atmos can pass flags
|
||||
// So we check every machinery process (2 seconds)
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/process()
|
||||
if (widenet)
|
||||
check_turfs()
|
||||
|
||||
//we populate a list of turfs with nonatmos-blocked cardinal turfs AND
|
||||
// diagonal turfs that can share atmos with *both* of the cardinal turfs
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/proc/check_turfs()
|
||||
adjacent_turfs.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
adjacent_turfs = T.GetAtmosAdjacentTurfs(alldir = 1)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if("power" in signal.data)
|
||||
on = text2num(signal.data["power"])
|
||||
if("power_toggle" in signal.data)
|
||||
on = !on
|
||||
|
||||
if("widenet" in signal.data)
|
||||
widenet = text2num(signal.data["widenet"])
|
||||
if("toggle_widenet" in signal.data)
|
||||
widenet = !widenet
|
||||
|
||||
if("scrubbing" in signal.data)
|
||||
scrubbing = text2num(signal.data["scrubbing"])
|
||||
if("toggle_scrubbing" in signal.data)
|
||||
scrubbing = !scrubbing
|
||||
|
||||
if("co2_scrub" in signal.data)
|
||||
scrub_CO2 = text2num(signal.data["co2_scrub"])
|
||||
if("toggle_co2_scrub" in signal.data)
|
||||
scrub_CO2 = !scrub_CO2
|
||||
|
||||
if("tox_scrub" in signal.data)
|
||||
scrub_Toxins = text2num(signal.data["tox_scrub"])
|
||||
if("toggle_tox_scrub" in signal.data)
|
||||
scrub_Toxins = !scrub_Toxins
|
||||
|
||||
if("n2o_scrub" in signal.data)
|
||||
scrub_N2O = text2num(signal.data["n2o_scrub"])
|
||||
if("toggle_n2o_scrub" in signal.data)
|
||||
scrub_N2O = !scrub_N2O
|
||||
|
||||
if("bz_scrub" in signal.data)
|
||||
scrub_BZ = text2num(signal.data["bz_scrub"])
|
||||
if("toggle_bz_scrub" in signal.data)
|
||||
scrub_BZ = !scrub_BZ
|
||||
|
||||
if("init" in signal.data)
|
||||
name = signal.data["init"]
|
||||
return
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status()
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/power_change()
|
||||
..()
|
||||
update_icon_nopipes()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0,user))
|
||||
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
|
||||
user << "<span class='notice'>Now welding the scrubber.</span>"
|
||||
if(do_after(user, 20/W.toolspeed, target = src))
|
||||
if(!src || !WT.isOn())
|
||||
return
|
||||
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
|
||||
if(!welded)
|
||||
user.visible_message("[user] welds the scrubber shut.","You weld the scrubber shut.", "You hear welding.")
|
||||
welded = 1
|
||||
else
|
||||
user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.")
|
||||
welded = 0
|
||||
update_icon()
|
||||
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_unwrench(mob/user)
|
||||
if(..())
|
||||
if (!(stat & NOPOWER) && on)
|
||||
user << "<span class='warning'>You cannot unwrench this [src], turn it off first!</span>"
|
||||
else
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through()
|
||||
return !welded
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user)
|
||||
if(!welded || !(do_after(user, 20, target = src)))
|
||||
return
|
||||
user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.")
|
||||
welded = 0
|
||||
update_icon()
|
||||
pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir)
|
||||
playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1)
|
||||
|
||||
|
||||
|
||||
#undef SIPHONING
|
||||
#undef SCRUBBING
|
||||
Reference in New Issue
Block a user