@@ -1,162 +1,162 @@
//node1, air1, network1 correspond to input
//node2, air2, network2 correspond to output

/obj/machinery/atmospherics/binary/circulator
name = "circulator"
desc = "A gas circulator turbine and heat exchanger."
icon = 'icons/obj/pipes.dmi'
icon_state = "circ-off"
anchored = 0

use_power = 0

var/obj/machinery/power/generator/linked_generator

var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency
var/volume_ratio = 0.2

var/recent_moles_transferred = 0
var/last_heat_capacity = 0
var/last_temperature = 0
var/last_pressure_delta = 0
var/last_worldtime_transfer = 0

var/last_stored_energy_transferred = 0
var/volume_capacity_used = 0
var/stored_energy = 0

density = 1

machine_flags = WRENCHMOVE | FIXED2WORK

/obj/machinery/atmospherics/binary/circulator/New()
. = ..()
air1.volume = 1000

/obj/machinery/atmospherics/binary/circulator/Destroy()
. = ..()
if(linked_generator)
linked_generator.reconnect()

/obj/machinery/atmospherics/binary/circulator/examine(var/mob/user)
. = ..()
to_chat(user, "Its outlet port is to the [dir2text(dir)].")

/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
if(!anchored || stat & BROKEN || !network1)
return

var/datum/gas_mixture/removed
var/input_starting_pressure = air1.return_pressure()
var/output_starting_pressure = air2.return_pressure()
last_pressure_delta = max(input_starting_pressure - output_starting_pressure - 5, 0)

//Only circulate air if there is a pressure difference (plus 5kPa kinetic, 10kPa static friction).
if(air1.temperature > 0 && last_pressure_delta > 5)

//Calculate necessary moles to transfer using PV = nRT.
recent_moles_transferred = (last_pressure_delta * air1.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)) / 3 //Uses the volume of the whole network, not just itself.
volume_capacity_used = min((last_pressure_delta * air1.volume / 3) / (input_starting_pressure * air1.volume), 1) //How much of the gas in the input air volume is consumed.

//Calculate energy generated from kinetic turbine.
stored_energy += 1 / ADIABATIC_EXPONENT * min(last_pressure_delta * air1.volume, input_starting_pressure * air1.volume) * (1 - volume_ratio ** ADIABATIC_EXPONENT) * kinetic_efficiency


//Actually transfer the gas.
removed = air1.remove(recent_moles_transferred)
if(removed)
last_heat_capacity = removed.heat_capacity()
last_temperature = removed.temperature

//Update the gas networks.
network1.update = 1

last_worldtime_transfer = world.time
else
recent_moles_transferred = 0

update_icon()
return removed

/obj/machinery/atmospherics/binary/circulator/proc/return_stored_energy()
last_stored_energy_transferred = stored_energy
stored_energy = 0
return last_stored_energy_transferred

/obj/machinery/atmospherics/binary/circulator/process()
. = ..()

if(last_worldtime_transfer < world.time - 50)
recent_moles_transferred = 0
update_icon()

/obj/machinery/atmospherics/binary/circulator/update_icon()
if(!linked_generator || linked_generator.stat & (NOPOWER | BROKEN)) //These get power from the TeG itself.
icon_state = "circ-p"

else if(last_pressure_delta > 0 && recent_moles_transferred > 0)
if(last_pressure_delta > 5* ONE_ATMOSPHERE)
icon_state = "circ-run"
else
icon_state = "circ-slow"
else
icon_state = "circ-off"

return 1

/obj/machinery/atmospherics/binary/circulator/wrenchAnchor(mob/user)
. = ..()
if(anchored)
if(dir & (NORTH|SOUTH))
initialize_directions = NORTH|SOUTH
else if(dir & (EAST|WEST))
initialize_directions = EAST|WEST

initialize()
build_network()
if (node1)
node1.initialize()
node1.build_network()
if (node2)
node2.initialize()
node2.build_network()

var/gendir = turn(dir, -90)
for(var/obj/machinery/power/generator/pot_gen in get_step(src, gendir))
pot_gen.reconnect()

else
if(node1)
node1.disconnect(src)
if(network1)
returnToPool(network1)
if(node2)
node2.disconnect(src)
if(network2)
returnToPool(network2)

node1 = null
node2 = null

linked_generator.reconnect()


/obj/machinery/atmospherics/binary/circulator/verb/rotate_clockwise()
set category = "Object"
set name = "Rotate Circulator (Clockwise)"
set src in view(1)

if(usr.isUnconscious() || usr.restrained() || anchored)
return

src.dir = turn(src.dir, 90)

/obj/machinery/atmospherics/binary/circulator/verb/rotate_anticlockwise()
set category = "Object"
set name = "Rotate Circulator (Counterclockwise)"
set src in view(1)

if(usr.isUnconscious() || usr.restrained() || anchored)
return

src.dir = turn(src.dir, -90)
//node1, air1, network1 correspond to input
//node2, air2, network2 correspond to output

/obj/machinery/atmospherics/binary/circulator
name = "circulator"
desc = "A gas circulator turbine and heat exchanger."
icon = 'icons/obj/pipes.dmi'
icon_state = "circ-off"
anchored = 0

use_power = 0

var/obj/machinery/power/generator/linked_generator

var/kinetic_efficiency = 0.04 //combined kinetic and kinetic-to-electric efficiency
var/volume_ratio = 0.2

var/recent_moles_transferred = 0
var/last_heat_capacity = 0
var/last_temperature = 0
var/last_pressure_delta = 0
var/last_worldtime_transfer = 0

var/last_stored_energy_transferred = 0
var/volume_capacity_used = 0
var/stored_energy = 0

density = 1

machine_flags = WRENCHMOVE | FIXED2WORK

/obj/machinery/atmospherics/binary/circulator/New()
. = ..()
air1.volume = 1000

/obj/machinery/atmospherics/binary/circulator/Destroy()
. = ..()
if(linked_generator)
linked_generator.reconnect()

/obj/machinery/atmospherics/binary/circulator/examine(var/mob/user)
. = ..()
to_chat(user, "Its outlet port is to the [dir2text(dir)].")

/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
if(!anchored || stat & BROKEN || !network1)
return

var/datum/gas_mixture/removed
var/input_starting_pressure = air1.return_pressure()
var/output_starting_pressure = air2.return_pressure()
last_pressure_delta = max(input_starting_pressure - output_starting_pressure - 5, 0)

//Only circulate air if there is a pressure difference (plus 5kPa kinetic, 10kPa static friction).
if(air1.temperature > 0 && last_pressure_delta > 5)

//Calculate necessary moles to transfer using PV = nRT.
recent_moles_transferred = (last_pressure_delta * air1.volume / (air1.temperature * R_IDEAL_GAS_EQUATION)) / 3 //Uses the volume of the whole network, not just itself.
volume_capacity_used = min((last_pressure_delta * air1.volume / 3) / (input_starting_pressure * air1.volume), 1) //How much of the gas in the input air volume is consumed.

//Calculate energy generated from kinetic turbine.
stored_energy += 1 / ADIABATIC_EXPONENT * min(last_pressure_delta * air1.volume, input_starting_pressure * air1.volume) * (1 - volume_ratio ** ADIABATIC_EXPONENT) * kinetic_efficiency


//Actually transfer the gas.
removed = air1.remove(recent_moles_transferred)
if(removed)
last_heat_capacity = removed.heat_capacity()
last_temperature = removed.temperature

//Update the gas networks.
network1.update = 1

last_worldtime_transfer = world.time
else
recent_moles_transferred = 0

update_icon()
return removed

/obj/machinery/atmospherics/binary/circulator/proc/return_stored_energy()
last_stored_energy_transferred = stored_energy
stored_energy = 0
return last_stored_energy_transferred

/obj/machinery/atmospherics/binary/circulator/process()
. = ..()

if(last_worldtime_transfer < world.time - 50)
recent_moles_transferred = 0
update_icon()

/obj/machinery/atmospherics/binary/circulator/update_icon()
if(!linked_generator || linked_generator.stat & (NOPOWER | BROKEN)) //These get power from the TeG itself.
icon_state = "circ-p"

else if(last_pressure_delta > 0 && recent_moles_transferred > 0)
if(last_pressure_delta > 5* ONE_ATMOSPHERE)
icon_state = "circ-run"
else
icon_state = "circ-slow"
else
icon_state = "circ-off"

return 1

/obj/machinery/atmospherics/binary/circulator/wrenchAnchor(mob/user)
. = ..()
if(anchored)
if(dir & (NORTH|SOUTH))
initialize_directions = NORTH|SOUTH
else if(dir & (EAST|WEST))
initialize_directions = EAST|WEST

initialize()
build_network()
if (node1)
node1.initialize()
node1.build_network()
if (node2)
node2.initialize()
node2.build_network()

var/gendir = turn(dir, -90)
for(var/obj/machinery/power/generator/pot_gen in get_step(src, gendir))
pot_gen.reconnect()

else
if(node1)
node1.disconnect(src)
if(network1)
returnToPool(network1)
if(node2)
node2.disconnect(src)
if(network2)
returnToPool(network2)

node1 = null
node2 = null

linked_generator.reconnect()


/obj/machinery/atmospherics/binary/circulator/verb/rotate_clockwise()
set category = "Object"
set name = "Rotate Circulator (Clockwise)"
set src in view(1)

if(usr.isUnconscious() || usr.restrained() || anchored)
return

src.dir = turn(src.dir, 90)

/obj/machinery/atmospherics/binary/circulator/verb/rotate_anticlockwise()
set category = "Object"
set name = "Rotate Circulator (Counterclockwise)"
set src in view(1)

if(usr.isUnconscious() || usr.restrained() || anchored)
return

src.dir = turn(src.dir, -90)

Large diffs are not rendered by default.

@@ -1,156 +1,156 @@
/obj/machinery/atmospherics/binary/passive_gate
//Tries to achieve target pressure at output (like a normal pump) except
// Uses no power but can not transfer gases from a low pressure area to a high pressure area
icon = 'icons/obj/atmospherics/passive_gate.dmi'
icon_state = "intact_off"

name = "Passive gate"
desc = "A one-way air valve that does not require power"

var/on = 0
var/target_pressure = ONE_ATMOSPHERE

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/passive_gate/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()
return

/obj/machinery/atmospherics/binary/passive_gate/process()
. = ..()
if(!on)
return

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

//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)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1


//Radio remote control


/obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA)

/obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AGP",
"power" = on,
"target_output" = target_pressure,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)

return 1

/obj/machinery/atmospherics/binary/passive_gate/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[round(target_pressure,0.1)]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")

/obj/machinery/atmospherics/binary/passive_gate/initialize()
..()
if(frequency)
set_frequency(frequency)

/obj/machinery/atmospherics/binary/passive_gate/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0

var/old_on=on
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("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
if(old_on!=on)
investigation_log(I_ATMOS,"was powered [on ? "on" : "off"] by a remote signal")
return



/obj/machinery/atmospherics/binary/passive_gate/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
/obj/machinery/atmospherics/binary/passive_gate
//Tries to achieve target pressure at output (like a normal pump) except
// Uses no power but can not transfer gases from a low pressure area to a high pressure area
icon = 'icons/obj/atmospherics/passive_gate.dmi'
icon_state = "intact_off"

name = "Passive gate"
desc = "A one-way air valve that does not require power"

var/on = 0
var/target_pressure = ONE_ATMOSPHERE

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/passive_gate/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()
return

/obj/machinery/atmospherics/binary/passive_gate/process()
. = ..()
if(!on)
return

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

//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)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1


//Radio remote control


/obj/machinery/atmospherics/binary/passive_gate/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA)

/obj/machinery/atmospherics/binary/passive_gate/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AGP",
"power" = on,
"target_output" = target_pressure,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)

return 1

/obj/machinery/atmospherics/binary/passive_gate/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[round(target_pressure,0.1)]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")

/obj/machinery/atmospherics/binary/passive_gate/initialize()
..()
if(frequency)
set_frequency(frequency)

/obj/machinery/atmospherics/binary/passive_gate/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0

var/old_on=on
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("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
if(old_on!=on)
investigation_log(I_ATMOS,"was powered [on ? "on" : "off"] by a remote signal")
return



/obj/machinery/atmospherics/binary/passive_gate/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)]")
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
investigation_log(I_ATMOS,"was set to [target_pressure] kPa by [key_name(usr)]")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/passive_gate/power_change()
..()
update_icon()
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)]")
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
investigation_log(I_ATMOS,"was set to [target_pressure] kPa by [key_name(usr)]")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/passive_gate/power_change()
..()
update_icon()
@@ -1,176 +1,176 @@
/*
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/binary/pump
icon = 'icons/obj/atmospherics/pump.dmi'
icon_state = "intact_off"

name = "Gas pump"
desc = "A pump."
var/on = 0
var/target_pressure = ONE_ATMOSPHERE

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/pump/highcap
name = "High capacity gas pump"
desc = "A high capacity pump"

target_pressure = 15000000 // Holy fuck man

/obj/machinery/atmospherics/binary/pump/on
on = 1
icon_state = "intact_on"

/obj/machinery/atmospherics/binary/pump/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()

/obj/machinery/atmospherics/binary/pump/process()
. = ..()
if((stat & (NOPOWER|BROKEN)) || !on)
return

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

//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)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1

//Radio remote control


/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA)

/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AGP",
"power" = on,
"target_output" = target_pressure,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)

return 1

/obj/machinery/atmospherics/binary/pump/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[round(target_pressure,0.1)]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")

/obj/machinery/atmospherics/binary/pump/initialize()
..()
if(frequency)
set_frequency(frequency)

/obj/machinery/atmospherics/binary/pump/receive_signal(datum/signal/signal)
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("set_output_pressure" in signal.data)
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]), 0, ONE_ATMOSPHERE * 50)

if("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by signal.")
return


/obj/machinery/atmospherics/binary/pump/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
/*
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/binary/pump
icon = 'icons/obj/atmospherics/pump.dmi'
icon_state = "intact_off"

name = "Gas pump"
desc = "A pump."
var/on = 0
var/target_pressure = ONE_ATMOSPHERE

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/pump/highcap
name = "High capacity gas pump"
desc = "A high capacity pump"

target_pressure = 15000000 // Holy fuck man

/obj/machinery/atmospherics/binary/pump/on
on = 1
icon_state = "intact_on"

/obj/machinery/atmospherics/binary/pump/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()

/obj/machinery/atmospherics/binary/pump/process()
. = ..()
if((stat & (NOPOWER|BROKEN)) || !on)
return

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

//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)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1

//Radio remote control


/obj/machinery/atmospherics/binary/pump/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency, filter = RADIO_ATMOSIA)

/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AGP",
"power" = on,
"target_output" = target_pressure,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)

return 1

/obj/machinery/atmospherics/binary/pump/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[round(target_pressure,0.1)]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")

/obj/machinery/atmospherics/binary/pump/initialize()
..()
if(frequency)
set_frequency(frequency)

/obj/machinery/atmospherics/binary/pump/receive_signal(datum/signal/signal)
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("set_output_pressure" in signal.data)
target_pressure = Clamp(text2num(signal.data["set_output_pressure"]), 0, ONE_ATMOSPHERE * 50)

if("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by signal.")
return


/obj/machinery/atmospherics/binary/pump/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)].")
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
investigation_log(I_ATMOS,"was set to [target_pressure] kPa by [key_name(usr)].")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/pump/power_change()
..()
update_icon()

/obj/machinery/atmospherics/binary/pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)].")
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
investigation_log(I_ATMOS,"was set to [target_pressure] kPa by [key_name(usr)].")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/pump/power_change()
..()
update_icon()

/obj/machinery/atmospherics/binary/pump/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
to_chat(user, "<span class='warning'>You cannot unwrench this [src], turn it off first.</span>")
return 1
return ..()
return 1
return ..()
@@ -1,160 +1,160 @@
/*
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/binary/volume_pump
icon = 'icons/obj/atmospherics/volume_pump.dmi'
icon_state = "intact_off"

name = "Volumetric gas pump"
desc = "A volumetric pump"

var/on = 0
var/transfer_rate = 200

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/volume_pump/on
on = 1
icon_state = "intact_on"

/obj/machinery/atmospherics/binary/volume_pump/update_icon(var/adjacent_procd)
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()

/obj/machinery/atmospherics/binary/volume_pump/process()
. = ..()
if((stat & (NOPOWER|BROKEN)) || !on || transfer_rate < 1)
return

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

var/transfer_ratio = max(1, transfer_rate/air1.volume)

var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)

air2.merge(removed)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1

/obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency)

/obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "APV",
"power" = on,
"transfer_rate" = transfer_rate,
"sigtype" = "status"
)
radio_connection.post_signal(src, signal)

return 1

/obj/machinery/atmospherics/binary/volume_pump/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output flow: </b>
[round(transfer_rate,1)]l/s | <a href='?src=\ref[src];set_transfer_rate=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")



/obj/machinery/atmospherics/binary/volume_pump/initialize()
..()

set_frequency(frequency)

/obj/machinery/atmospherics/binary/volume_pump/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
var/old_on=on
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)
transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]), 0, air1.volume)

if("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
if(old_on!=on)
investigation_log(I_ATMOS,"was powered [on ? "on" : "off"] by a remote signal")


/obj/machinery/atmospherics/binary/volume_pump/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
/*
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/binary/volume_pump
icon = 'icons/obj/atmospherics/volume_pump.dmi'
icon_state = "intact_off"

name = "Volumetric gas pump"
desc = "A volumetric pump"

var/on = 0
var/transfer_rate = 200

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

/obj/machinery/atmospherics/binary/volume_pump/on
on = 1
icon_state = "intact_on"

/obj/machinery/atmospherics/binary/volume_pump/update_icon(var/adjacent_procd)
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node1 && node2)
icon_state = "intact_[on?("on"):("off")]"
..()

/obj/machinery/atmospherics/binary/volume_pump/process()
. = ..()
if((stat & (NOPOWER|BROKEN)) || !on || transfer_rate < 1)
return

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

var/transfer_ratio = max(1, transfer_rate/air1.volume)

var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)

air2.merge(removed)

if(network1)
network1.update = 1

if(network2)
network2.update = 1

return 1

/obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency)

/obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "APV",
"power" = on,
"transfer_rate" = transfer_rate,
"sigtype" = "status"
)
radio_connection.post_signal(src, signal)

return 1

/obj/machinery/atmospherics/binary/volume_pump/interact(mob/user as mob)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output flow: </b>
[round(transfer_rate,1)]l/s | <a href='?src=\ref[src];set_transfer_rate=1'>Change</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_pump")
onclose(user, "atmo_pump")



/obj/machinery/atmospherics/binary/volume_pump/initialize()
..()

set_frequency(frequency)

/obj/machinery/atmospherics/binary/volume_pump/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
return 0
var/old_on=on
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)
transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]), 0, air1.volume)

if("status" in signal.data)
spawn(2)
broadcast_status()
return //do not update_icon

spawn(2)
broadcast_status()
update_icon()
if(old_on!=on)
investigation_log(I_ATMOS,"was powered [on ? "on" : "off"] by a remote signal")


/obj/machinery/atmospherics/binary/volume_pump/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)]")
if(href_list["set_transfer_rate"])
var/new_transfer_rate = input(usr,"Enter new output volume (0-200l/s)","Flow control",src.transfer_rate) as num
src.transfer_rate = max(0, min(200, new_transfer_rate))
investigation_log(I_ATMOS,"was set to [transfer_rate] L/s by [key_name(usr)]")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/volume_pump/power_change()
..()
update_icon()
return
usr.set_machine(src)
interact(user)
return

/obj/machinery/atmospherics/binary/volume_pump/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
investigation_log(I_ATMOS,"was turned [on ? "on" : "off"] by [key_name(usr)]")
if(href_list["set_transfer_rate"])
var/new_transfer_rate = input(usr,"Enter new output volume (0-200l/s)","Flow control",src.transfer_rate) as num
src.transfer_rate = max(0, min(200, new_transfer_rate))
investigation_log(I_ATMOS,"was set to [transfer_rate] L/s by [key_name(usr)]")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/binary/volume_pump/power_change()
..()
update_icon()

Large diffs are not rendered by default.

@@ -1,155 +1,155 @@
obj/machinery/atmospherics/trinary/mixer
icon = 'icons/obj/atmospherics/mixer.dmi'
icon_state = "intact_off"

name = "Gas mixer"

mirror = /obj/machinery/atmospherics/trinary/mixer/mirrored

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/trinary/mixer/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "intact_off"
on = 0
..()

obj/machinery/atmospherics/trinary/mixer/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()

obj/machinery/atmospherics/trinary/mixer/New()
..()
air3.volume = 300


obj/machinery/atmospherics/trinary/mixer/process()
. = ..()
if(!on)
return

var/output_starting_pressure = air3.return_pressure()

if(output_starting_pressure >= target_pressure)
//No need to mix if target is already full!
return

//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))
if(!transfer_moles1 || !transfer_moles2) return
var/ratio = min(air1_moles/transfer_moles1, 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(network1 && transfer_moles1)
network1.update = 1

if(network2 && transfer_moles2)
network2.update = 1

if(network3)
network3.update = 1

return 1

obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
obj/machinery/atmospherics/trinary/mixer
icon = 'icons/obj/atmospherics/mixer.dmi'
icon_state = "intact_off"

name = "Gas mixer"

mirror = /obj/machinery/atmospherics/trinary/mixer/mirrored

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/trinary/mixer/update_icon()
if(stat & NOPOWER)
icon_state = "intact_off"
else if(node2 && node3 && node1)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "intact_off"
on = 0
..()

obj/machinery/atmospherics/trinary/mixer/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()

obj/machinery/atmospherics/trinary/mixer/New()
..()
air3.volume = 300


obj/machinery/atmospherics/trinary/mixer/process()
. = ..()
if(!on)
return

var/output_starting_pressure = air3.return_pressure()

if(output_starting_pressure >= target_pressure)
//No need to mix if target is already full!
return

//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))
if(!transfer_moles1 || !transfer_moles2) return
var/ratio = min(air1_moles/transfer_moles1, 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(network1 && transfer_moles1)
network1.update = 1

if(network2 && transfer_moles2)
network2.update = 1

if(network3)
network3.update = 1

return 1

obj/machinery/atmospherics/trinary/mixer/attack_hand(user as mob)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
to_chat(user, "<span class='warning'>Access denied.</span>")
return
usr.set_machine(src)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[target_pressure]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
<br>
<b>Node 1 Concentration:</b>
<a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node1_c=-0.01'>-</a>
[node1_concentration]([node1_concentration*100]%)
<a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node1_c=0.1'>+</a>
<br>
<b>Node 2 Concentration:</b>
<a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node2_c=-0.01'>-</a>
[node2_concentration]([node2_concentration*100]%)
<a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node2_c=0.1'>+</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_mixer")
onclose(user, "atmo_mixer")
return

obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
if(href_list["node1_c"])
var/value = text2num(href_list["node1_c"])
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
if(href_list["node2_c"])
var/value = text2num(href_list["node2_c"])
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/trinary/mixer/mirrored
icon_state = "intactm_off"
pipe_flags = IS_MIRROR

/obj/machinery/atmospherics/trinary/mixer/mirrored/update_icon()
..()
if(stat & NOPOWER)
icon_state = "intactm_off"
else if(node2 && node3 && node1)
icon_state = "intactm_[on?("on"):("off")]"
else
icon_state = "intactm_off"
on = 0
return
return
usr.set_machine(src)
var/dat = {"<b>Power: </b><a href='?src=\ref[src];power=1'>[on?"On":"Off"]</a><br>
<b>Desirable output pressure: </b>
[target_pressure]kPa | <a href='?src=\ref[src];set_press=1'>Change</a>
<br>
<b>Node 1 Concentration:</b>
<a href='?src=\ref[src];node1_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node1_c=-0.01'>-</a>
[node1_concentration]([node1_concentration*100]%)
<a href='?src=\ref[src];node1_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node1_c=0.1'>+</a>
<br>
<b>Node 2 Concentration:</b>
<a href='?src=\ref[src];node2_c=-0.1'><b>-</b></a>
<a href='?src=\ref[src];node2_c=-0.01'>-</a>
[node2_concentration]([node2_concentration*100]%)
<a href='?src=\ref[src];node2_c=0.01'><b>+</b></a>
<a href='?src=\ref[src];node2_c=0.1'>+</a>
"}

user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_mixer")
onclose(user, "atmo_mixer")
return

obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..()) return
if(href_list["power"])
on = !on
if(href_list["set_press"])
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",src.target_pressure) as num
src.target_pressure = max(0, min(4500, new_pressure))
if(href_list["node1_c"])
var/value = text2num(href_list["node1_c"])
src.node1_concentration = max(0, min(1, src.node1_concentration + value))
src.node2_concentration = max(0, min(1, src.node2_concentration - value))
if(href_list["node2_c"])
var/value = text2num(href_list["node2_c"])
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
src.update_icon()
src.updateUsrDialog()
return

/obj/machinery/atmospherics/trinary/mixer/mirrored
icon_state = "intactm_off"
pipe_flags = IS_MIRROR

/obj/machinery/atmospherics/trinary/mixer/mirrored/update_icon()
..()
if(stat & NOPOWER)
icon_state = "intactm_off"
else if(node2 && node3 && node1)
icon_state = "intactm_[on?("on"):("off")]"
else
icon_state = "intactm_off"
on = 0
return

Large diffs are not rendered by default.

@@ -1,33 +1,33 @@
/obj/machinery/atmospherics/unary/cold_sink
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "on_cool"
density = 1
use_power = 1

name = "Cold Sink"
desc = "Cools gas when connected to pipe network"

var/on = 0

var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random


/obj/machinery/atmospherics/unary/cold_sink/process()
. = ..()
if(!on || !network)
return
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = current_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature

if(combined_heat_capacity > 0)
var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature
if(air_contents.temperature > current_temperature) //if it's hotter than we can cool it, cool it
air_contents.temperature = combined_energy/combined_heat_capacity

//todo: have current temperature affected. require power to bring down current temperature again

if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1
/obj/machinery/atmospherics/unary/cold_sink
icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "on_cool"
density = 1
use_power = 1

name = "Cold Sink"
desc = "Cools gas when connected to pipe network"

var/on = 0

var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random


/obj/machinery/atmospherics/unary/cold_sink/process()
. = ..()
if(!on || !network)
return
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = current_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature

if(combined_heat_capacity > 0)
var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature
if(air_contents.temperature > current_temperature) //if it's hotter than we can cool it, cool it
air_contents.temperature = combined_energy/combined_heat_capacity

//todo: have current temperature affected. require power to bring down current temperature again

if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1
return 1
@@ -1,21 +1,21 @@
/obj/machinery/atmospherics/unary/generator_input
icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
icon_state = "intact"
density = 1

name = "Generator Input"
desc = "Placeholder"

var/update_cycle

update_icon()
if(node)
icon_state = "intact"
else
icon_state = "exposed"

return

proc
return_exchange_air()
/obj/machinery/atmospherics/unary/generator_input
icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
icon_state = "intact"
density = 1

name = "Generator Input"
desc = "Placeholder"

var/update_cycle

update_icon()
if(node)
icon_state = "intact"
else
icon_state = "exposed"

return

proc
return_exchange_air()
return air_contents
@@ -1,63 +1,63 @@
/obj/machinery/atmospherics/unary/heat_exchanger

icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
icon_state = "intact"
density = 1

name = "Heat Exchanger"
desc = "Exchanges heat between two input gases. Setup for fast heat transfer"

var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null
var/update_cycle

/obj/machinery/atmospherics/unary/heat_exchanger/update_icon()
if(node)
icon_state = "intact"
else
icon_state = "exposed"
..()
return

/obj/machinery/atmospherics/unary/heat_exchanger/initialize()
if(!partner)
var/partner_connect = turn(dir,180)

for(var/obj/machinery/atmospherics/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/unary/heat_exchanger/process()
. = ..()
if(!partner || !air_master || air_master.current_cycle <= update_cycle)
return

update_cycle = air_master.current_cycle
partner.update_cycle = air_master.current_cycle

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(network)
if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1

if(partner.network)
if(abs(other_old_temperature-partner.air_contents.temperature) > 1)
partner.network.update = 1

return 1
/obj/machinery/atmospherics/unary/heat_exchanger

icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
icon_state = "intact"
density = 1

name = "Heat Exchanger"
desc = "Exchanges heat between two input gases. Setup for fast heat transfer"

var/obj/machinery/atmospherics/unary/heat_exchanger/partner = null
var/update_cycle

/obj/machinery/atmospherics/unary/heat_exchanger/update_icon()
if(node)
icon_state = "intact"
else
icon_state = "exposed"
..()
return

/obj/machinery/atmospherics/unary/heat_exchanger/initialize()
if(!partner)
var/partner_connect = turn(dir,180)

for(var/obj/machinery/atmospherics/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/unary/heat_exchanger/process()
. = ..()
if(!partner || !air_master || air_master.current_cycle <= update_cycle)
return

update_cycle = air_master.current_cycle
partner.update_cycle = air_master.current_cycle

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(network)
if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1

if(partner.network)
if(abs(other_old_temperature-partner.air_contents.temperature) > 1)
partner.network.update = 1

return 1
@@ -1,35 +1,35 @@
/obj/machinery/atmospherics/unary/heat_reservoir
//currently the same code as cold_sink but anticipating process() changes

icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
density = 1
use_power = 1

name = "Heat Reservoir"
desc = "Heats gas when connected to pipe network"

var/on = 0

var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random


/obj/machinery/atmospherics/unary/heat_reservoir/process()
. = ..()
if(!on)
return
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = current_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature

if(combined_heat_capacity > 0)
var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature
if(air_contents.temperature < current_temperature) //if its colder than we can heat it, heat it
air_contents.temperature = combined_energy/combined_heat_capacity

//todo: have current temperature affected. require power to bring up current temperature again

if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1
/obj/machinery/atmospherics/unary/heat_reservoir
//currently the same code as cold_sink but anticipating process() changes

icon = 'icons/obj/atmospherics/cold_sink.dmi'
icon_state = "intact_off"
density = 1
use_power = 1

name = "Heat Reservoir"
desc = "Heats gas when connected to pipe network"

var/on = 0

var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random


/obj/machinery/atmospherics/unary/heat_reservoir/process()
. = ..()
if(!on)
return
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = current_heat_capacity + air_heat_capacity
var/old_temperature = air_contents.temperature

if(combined_heat_capacity > 0)
var/combined_energy = current_temperature*current_heat_capacity + air_heat_capacity*air_contents.temperature
if(air_contents.temperature < current_temperature) //if its colder than we can heat it, heat it
air_contents.temperature = combined_energy/combined_heat_capacity

//todo: have current temperature affected. require power to bring up current temperature again

if(abs(old_temperature-air_contents.temperature) > 1)
network.update = 1
return 1
@@ -1,180 +1,180 @@
/obj/machinery/atmospherics/unary/outlet_injector
icon = 'icons/obj/atmospherics/outlet_injector.dmi'
icon_state = "off"
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/max_rate=50

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

level = 1

machine_flags = MULTITOOL_MENU

/obj/machinery/atmospherics/unary/outlet_injector/update_icon()
if(node)
if(on && !(stat & NOPOWER))
icon_state = "hon"
else
icon_state = "hoff"
else
icon_state = "exposed"
on = 0
..()
if (istype(loc, /turf/simulated/floor) && node)
var/turf/simulated/floor/floor = loc
if(floor.floor_tile && node.alpha == 128)
underlays.Cut()
return

/obj/machinery/atmospherics/unary/outlet_injector/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()


/obj/machinery/atmospherics/unary/outlet_injector/process()
. = ..()
injecting = 0

if(!on || stat & NOPOWER)
return

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)

if(network)
network.update = 1

return 1

/obj/machinery/atmospherics/unary/outlet_injector/proc/inject()
if(on || injecting)
return 0

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)

if(network)
network.update = 1

flick("inject", src)

/obj/machinery/atmospherics/unary/outlet_injector/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency)

/obj/machinery/atmospherics/unary/outlet_injector/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AO",
"power" = on,
"volume_rate" = volume_rate,
//"timestamp" = world.time,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal)

return 1

/obj/machinery/atmospherics/unary/outlet_injector/initialize()
..()

set_frequency(frequency)

/obj/machinery/atmospherics/unary/outlet_injector/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["type"] && signal.data["type"] != "injector"))
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"])
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()

/obj/machinery/atmospherics/unary/outlet_injector/hide(var/i) //to make the little pipe section invisible, the icon changes.
if(node)
if(on)
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]on"
else
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]off"
else
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]exposed"
on = 0
return

/obj/machinery/atmospherics/unary/outlet_injector/interact(mob/user as mob)
update_multitool_menu(user)

/obj/machinery/atmospherics/unary/outlet_injector/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
return {"
<ul>
<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[1439]">Reset</a>)</li>
<li>[format_tag("ID Tag","id_tag","set_id")]</a></li>
</ul>
"}

/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
/obj/machinery/atmospherics/unary/outlet_injector
icon = 'icons/obj/atmospherics/outlet_injector.dmi'
icon_state = "off"
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/max_rate=50

var/frequency = 0
var/id_tag = null
var/datum/radio_frequency/radio_connection

level = 1

machine_flags = MULTITOOL_MENU

/obj/machinery/atmospherics/unary/outlet_injector/update_icon()
if(node)
if(on && !(stat & NOPOWER))
icon_state = "hon"
else
icon_state = "hoff"
else
icon_state = "exposed"
on = 0
..()
if (istype(loc, /turf/simulated/floor) && node)
var/turf/simulated/floor/floor = loc
if(floor.floor_tile && node.alpha == 128)
underlays.Cut()
return

/obj/machinery/atmospherics/unary/outlet_injector/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()


/obj/machinery/atmospherics/unary/outlet_injector/process()
. = ..()
injecting = 0

if(!on || stat & NOPOWER)
return

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)

if(network)
network.update = 1

return 1

/obj/machinery/atmospherics/unary/outlet_injector/proc/inject()
if(on || injecting)
return 0

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)

if(network)
network.update = 1

flick("inject", src)

/obj/machinery/atmospherics/unary/outlet_injector/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = radio_controller.add_object(src, frequency)

/obj/machinery/atmospherics/unary/outlet_injector/proc/broadcast_status()
if(!radio_connection)
return 0

var/datum/signal/signal = getFromPool(/datum/signal)
signal.transmission_method = 1 //radio signal
signal.source = src

signal.data = list(
"tag" = id_tag,
"device" = "AO",
"power" = on,
"volume_rate" = volume_rate,
//"timestamp" = world.time,
"sigtype" = "status"
)

radio_connection.post_signal(src, signal)

return 1

/obj/machinery/atmospherics/unary/outlet_injector/initialize()
..()

set_frequency(frequency)

/obj/machinery/atmospherics/unary/outlet_injector/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["type"] && signal.data["type"] != "injector"))
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"])
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()

/obj/machinery/atmospherics/unary/outlet_injector/hide(var/i) //to make the little pipe section invisible, the icon changes.
if(node)
if(on)
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]on"
else
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]off"
else
icon_state = "[i == 1 && istype(loc, /turf/simulated) ? "h" : "" ]exposed"
on = 0
return

/obj/machinery/atmospherics/unary/outlet_injector/interact(mob/user as mob)
update_multitool_menu(user)

/obj/machinery/atmospherics/unary/outlet_injector/multitool_menu(var/mob/user,var/obj/item/device/multitool/P)
return {"
<ul>
<li><b>Frequency:</b> <a href="?src=\ref[src];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=\ref[src];set_freq=[1439]">Reset</a>)</li>
<li>[format_tag("ID Tag","id_tag","set_id")]</a></li>
</ul>
"}

/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
if (!(stat & NOPOWER) && on)
to_chat(user, "<span class='warning'>You cannot unwrench this [src], turn it off first.</span>")
return 1
return ..()

/obj/machinery/atmospherics/unary/outlet_injector/canClone(var/obj/O)
return istype(O, /obj/machinery/atmospherics/unary/outlet_injector)

/obj/machinery/atmospherics/unary/outlet_injector/clone(var/obj/machinery/atmospherics/unary/outlet_injector/O)
id_tag = O.id_tag
set_frequency(O.frequency)
return 1
return 1
return ..()

/obj/machinery/atmospherics/unary/outlet_injector/canClone(var/obj/O)
return istype(O, /obj/machinery/atmospherics/unary/outlet_injector)

/obj/machinery/atmospherics/unary/outlet_injector/clone(var/obj/machinery/atmospherics/unary/outlet_injector/O)
id_tag = O.id_tag
set_frequency(O.frequency)
return 1
@@ -1,49 +1,49 @@
obj/machinery/atmospherics/unary/oxygen_generator
icon = 'icons/obj/atmospherics/oxygen_generator.dmi'
icon_state = "intact_off"
density = 1

name = "Oxygen Generator"
desc = ""

dir = SOUTH
initialize_directions = SOUTH

var/on = 0

var/oxygen_content = 10

obj/machinery/atmospherics/unary/oxygen_generator/update_icon()
if(node)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "exposed_off"

on = 0

return

obj/machinery/atmospherics/unary/oxygen_generator/New()
..()

air_contents.volume = 50

obj/machinery/atmospherics/unary/oxygen_generator/process()
. = ..()
if(!on)
return

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.oxygen += added_oxygen

if(network)
network.update = 1

obj/machinery/atmospherics/unary/oxygen_generator
icon = 'icons/obj/atmospherics/oxygen_generator.dmi'
icon_state = "intact_off"
density = 1

name = "Oxygen Generator"
desc = ""

dir = SOUTH
initialize_directions = SOUTH

var/on = 0

var/oxygen_content = 10

obj/machinery/atmospherics/unary/oxygen_generator/update_icon()
if(node)
icon_state = "intact_[on?("on"):("off")]"
else
icon_state = "exposed_off"

on = 0

return

obj/machinery/atmospherics/unary/oxygen_generator/New()
..()

air_contents.volume = 50

obj/machinery/atmospherics/unary/oxygen_generator/process()
. = ..()
if(!on)
return

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.oxygen += added_oxygen

if(network)
network.update = 1

return 1
@@ -1,96 +1,96 @@
/obj/machinery/atmospherics/unary
dir = SOUTH
initialize_directions = SOUTH
layer = 2.45 // Cable says we're at 2.45, so we're at 2.45. (old: TURF_LAYER+0.1)

var/datum/gas_mixture/air_contents
var/obj/machinery/atmospherics/node
var/datum/pipe_network/network

/obj/machinery/atmospherics/unary/New()
..()
initialize_directions = dir
air_contents = new

air_contents.temperature = T0C
air_contents.volume = starting_volume

/obj/machinery/atmospherics/unary/update_icon(var/adjacent_procd,node_list)
node_list = list(node)
..(adjacent_procd,node_list)

/obj/machinery/atmospherics/unary/buildFrom(var/mob/usr,var/obj/item/pipe/pipe)
dir = pipe.dir
initialize_directions = pipe.get_pipe_dir()
if (pipe.pipename)
name = pipe.pipename
var/turf/T = loc
level = T.intact ? 2 : 1
initialize()
build_network()
if (node)
node.initialize()
node.build_network()
return 1

// Housekeeping and pipe network stuff below
/obj/machinery/atmospherics/unary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
if(reference == node)
network = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null

/obj/machinery/atmospherics/unary/Destroy()
if(node)
node.disconnect(src)
if(network)
returnToPool(network)
node = null
..()

/obj/machinery/atmospherics/unary/initialize()
if(node) return
var/node_connect = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
if(target.piping_layer == piping_layer || target.pipe_flags & ALL_LAYER)
node = target
break
update_icon()

/obj/machinery/atmospherics/unary/build_network()
if(!network && node)
network = getFromPool(/datum/pipe_network)
network.normal_members += src
network.build_network(node, src)


/obj/machinery/atmospherics/unary/return_network(obj/machinery/atmospherics/reference)
build_network()
if(reference == node || reference == src)
return network
return null

/obj/machinery/atmospherics/unary/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
if(network == old_network)
network = new_network
return 1

/obj/machinery/atmospherics/unary/return_network_air(datum/pipe_network/reference)
var/list/results = list()
if(network == reference)
results += air_contents
return results

/obj/machinery/atmospherics/unary/disconnect(obj/machinery/atmospherics/reference)
if(reference==node)
if(network)
returnToPool(network)
node = null
return null

/obj/machinery/atmospherics/unary/unassign_network(datum/pipe_network/reference)
if(network == reference)
/obj/machinery/atmospherics/unary
dir = SOUTH
initialize_directions = SOUTH
layer = 2.45 // Cable says we're at 2.45, so we're at 2.45. (old: TURF_LAYER+0.1)

var/datum/gas_mixture/air_contents
var/obj/machinery/atmospherics/node
var/datum/pipe_network/network

/obj/machinery/atmospherics/unary/New()
..()
initialize_directions = dir
air_contents = new

air_contents.temperature = T0C
air_contents.volume = starting_volume

/obj/machinery/atmospherics/unary/update_icon(var/adjacent_procd,node_list)
node_list = list(node)
..(adjacent_procd,node_list)

/obj/machinery/atmospherics/unary/buildFrom(var/mob/usr,var/obj/item/pipe/pipe)
dir = pipe.dir
initialize_directions = pipe.get_pipe_dir()
if (pipe.pipename)
name = pipe.pipename
var/turf/T = loc
level = T.intact ? 2 : 1
initialize()
build_network()
if (node)
node.initialize()
node.build_network()
return 1

// Housekeeping and pipe network stuff below
/obj/machinery/atmospherics/unary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
if(reference == node)
network = new_network
if(new_network.normal_members.Find(src))
return 0
new_network.normal_members += src
return null

/obj/machinery/atmospherics/unary/Destroy()
if(node)
node.disconnect(src)
if(network)
returnToPool(network)
node = null
..()

/obj/machinery/atmospherics/unary/initialize()
if(node) return
var/node_connect = dir
for(var/obj/machinery/atmospherics/target in get_step(src,node_connect))
if(target.initialize_directions & get_dir(target,src))
if(target.piping_layer == piping_layer || target.pipe_flags & ALL_LAYER)
node = target
break
update_icon()

/obj/machinery/atmospherics/unary/build_network()
if(!network && node)
network = getFromPool(/datum/pipe_network)
network.normal_members += src
network.build_network(node, src)


/obj/machinery/atmospherics/unary/return_network(obj/machinery/atmospherics/reference)
build_network()
if(reference == node || reference == src)
return network
return null

/obj/machinery/atmospherics/unary/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
if(network == old_network)
network = new_network
return 1

/obj/machinery/atmospherics/unary/return_network_air(datum/pipe_network/reference)
var/list/results = list()
if(network == reference)
results += air_contents
return results

/obj/machinery/atmospherics/unary/disconnect(obj/machinery/atmospherics/reference)
if(reference==node)
if(network)
returnToPool(network)
node = null
return null

/obj/machinery/atmospherics/unary/unassign_network(datum/pipe_network/reference)
if(network == reference)
network = null

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -1,50 +1,50 @@

//---------- actual energy field

/obj/effect/energy_field
name = "energy field"
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
icon = 'code/WorkInProgress/Cael_Aislinn/ShieldGen/shielding.dmi'
icon_state = "shieldsparkles"
anchored = 1
layer = 4.1 //just above mobs
density = 0
invisibility = 101
var/strength = 0

/obj/effect/energy_field/ex_act(var/severity)
Stress(0.5 + severity)

/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
Stress(Proj.damage / 10)

/obj/effect/energy_field/proc/Stress(var/severity)
strength -= severity

//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength < 1)
invisibility = 101
density = 0
else if(strength >= 1)
invisibility = 0
density = 1

/obj/effect/energy_field/proc/Strengthen(var/severity)
strength += severity

//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength >= 1)
invisibility = 0
density = 1
else if(strength < 1)
invisibility = 101
density = 0

/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
//Purpose: Determines if the object (or airflow) can pass this atom.
//Called by: Movement, airflow.
//Inputs: The moving atom (optional), target turf, "height" and air group
//Outputs: Boolean if can pass.

//return (!density || !height || air_group)
return !density

//---------- actual energy field

/obj/effect/energy_field
name = "energy field"
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
icon = 'code/WorkInProgress/Cael_Aislinn/ShieldGen/shielding.dmi'
icon_state = "shieldsparkles"
anchored = 1
layer = 4.1 //just above mobs
density = 0
invisibility = 101
var/strength = 0

/obj/effect/energy_field/ex_act(var/severity)
Stress(0.5 + severity)

/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
Stress(Proj.damage / 10)

/obj/effect/energy_field/proc/Stress(var/severity)
strength -= severity

//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength < 1)
invisibility = 101
density = 0
else if(strength >= 1)
invisibility = 0
density = 1

/obj/effect/energy_field/proc/Strengthen(var/severity)
strength += severity

//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength >= 1)
invisibility = 0
density = 1
else if(strength < 1)
invisibility = 101
density = 0

/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
//Purpose: Determines if the object (or airflow) can pass this atom.
//Called by: Movement, airflow.
//Inputs: The moving atom (optional), target turf, "height" and air group
//Outputs: Boolean if can pass.

//return (!density || !height || air_group)
return !density