mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-24 13:30:42 +01:00
Implement Bay's SSmachinery and power usage updates, further unclogging the toilet (#13910)
This commit is contained in:
@@ -6,5 +6,5 @@
|
||||
if(!.)
|
||||
return
|
||||
|
||||
for(var/obj/machinery/light/L in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/light/L in SSmachinery.machinery)
|
||||
L.fix()
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
return
|
||||
feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
for (var/datum/powernet/PN in SSpower.powernets)
|
||||
for (var/datum/powernet/PN in SSmachinery.powernets)
|
||||
if (!PN.nodes || !PN.nodes.len)
|
||||
if(PN.cables && (PN.cables.len > 1))
|
||||
var/obj/structure/cable/C = PN.cables[1]
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
/client/proc/cmd_debug_make_powernets()
|
||||
set category = "Debug"
|
||||
set name = "Make Powernets"
|
||||
makepowernets()
|
||||
SSmachinery.makepowernets()
|
||||
log_admin("[key_name(src)] has remade the powernet. makepowernets() called.",admin_key=key_name(usr))
|
||||
message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0)
|
||||
feedback_add_details("admin_verb","MPWN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
//--------------------------------------------
|
||||
// Pipe colors
|
||||
//
|
||||
// Add them here and to the pipe_colors list
|
||||
// to automatically add them to all relevant
|
||||
// atmospherics devices.
|
||||
//--------------------------------------------
|
||||
|
||||
/proc/pipe_color_lookup(var/color)
|
||||
for(var/C in pipe_colors)
|
||||
if(color == pipe_colors[C])
|
||||
return "[C]"
|
||||
|
||||
/proc/pipe_color_check(var/color)
|
||||
if(!color)
|
||||
return 1
|
||||
for(var/C in pipe_colors)
|
||||
if(color == pipe_colors[C])
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//--------------------------------------------
|
||||
// Icon cache generation
|
||||
//--------------------------------------------
|
||||
|
||||
/datum/pipe_icon_manager
|
||||
var/list/pipe_icons[]
|
||||
var/list/manifold_icons[]
|
||||
var/list/device_icons[]
|
||||
var/list/underlays[]
|
||||
//var/list/underlays_down[]
|
||||
//var/list/underlays_exposed[]
|
||||
//var/list/underlays_intact[]
|
||||
//var/list/pipe_underlays_exposed[]
|
||||
//var/list/pipe_underlays_intact[]
|
||||
var/list/omni_icons[]
|
||||
|
||||
/datum/pipe_icon_manager/New()
|
||||
check_icons()
|
||||
|
||||
/datum/pipe_icon_manager/proc/get_atmos_icon(var/device, var/dir, var/color, var/state)
|
||||
check_icons()
|
||||
|
||||
device = "[device]"
|
||||
state = "[state]"
|
||||
color = "[color]"
|
||||
dir = "[dir]"
|
||||
|
||||
switch(device)
|
||||
if("pipe")
|
||||
return pipe_icons[state + color]
|
||||
if("manifold")
|
||||
return manifold_icons[state + color]
|
||||
if("device")
|
||||
return device_icons[state]
|
||||
if("omni")
|
||||
return omni_icons[state]
|
||||
if("underlay")
|
||||
return underlays[state + dir + color]
|
||||
// if("underlay_intact")
|
||||
// return underlays_intact[state + dir + color]
|
||||
// if("underlay_exposed")
|
||||
// return underlays_exposed[state + dir + color]
|
||||
// if("underlay_down")
|
||||
// return underlays_down[state + dir + color]
|
||||
// if("pipe_underlay_exposed")
|
||||
// return pipe_underlays_exposed[state + dir + color]
|
||||
// if("pipe_underlay_intact")
|
||||
// return pipe_underlays_intact[state + dir + color]
|
||||
|
||||
/datum/pipe_icon_manager/proc/check_icons()
|
||||
if(!pipe_icons)
|
||||
gen_pipe_icons()
|
||||
if(!manifold_icons)
|
||||
gen_manifold_icons()
|
||||
if(!device_icons)
|
||||
gen_device_icons()
|
||||
if(!omni_icons)
|
||||
gen_omni_icons()
|
||||
//if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact)
|
||||
if(!underlays)
|
||||
gen_underlay_icons()
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_pipe_icons()
|
||||
if(!pipe_icons)
|
||||
pipe_icons = new()
|
||||
|
||||
var/icon/pipe = new('icons/atmos/pipes.dmi')
|
||||
|
||||
for(var/state in pipe.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
|
||||
var/cache_name = state
|
||||
var/image/I = image('icons/atmos/pipes.dmi', icon_state = state)
|
||||
pipe_icons[cache_name] = I
|
||||
|
||||
for(var/pipe_color in pipe_colors)
|
||||
I = image('icons/atmos/pipes.dmi', icon_state = state)
|
||||
I.color = pipe_colors[pipe_color]
|
||||
pipe_icons[state + "[pipe_colors[pipe_color]]"] = I
|
||||
|
||||
pipe = new ('icons/atmos/heat.dmi')
|
||||
for(var/state in pipe.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
pipe_icons["hepipe" + state] = image('icons/atmos/heat.dmi', icon_state = state)
|
||||
|
||||
pipe = new ('icons/atmos/junction.dmi')
|
||||
for(var/state in pipe.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
pipe_icons["hejunction" + state] = image('icons/atmos/junction.dmi', icon_state = state)
|
||||
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_manifold_icons()
|
||||
if(!manifold_icons)
|
||||
manifold_icons = new()
|
||||
|
||||
var/icon/pipe = new('icons/atmos/manifold.dmi')
|
||||
|
||||
for(var/state in pipe.IconStates())
|
||||
if(findtext(state, "clamps"))
|
||||
var/image/I = image('icons/atmos/manifold.dmi', icon_state = state)
|
||||
manifold_icons[state] = I
|
||||
continue
|
||||
|
||||
if(findtext(state, "core") || findtext(state, "4way"))
|
||||
var/image/I = image('icons/atmos/manifold.dmi', icon_state = state)
|
||||
manifold_icons[state] = I
|
||||
for(var/pipe_color in pipe_colors)
|
||||
I = image('icons/atmos/manifold.dmi', icon_state = state)
|
||||
I.color = pipe_colors[pipe_color]
|
||||
manifold_icons[state + pipe_colors[pipe_color]] = I
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_device_icons()
|
||||
if(!device_icons)
|
||||
device_icons = new()
|
||||
|
||||
var/icon/device
|
||||
|
||||
device = new('icons/atmos/vent_pump.dmi')
|
||||
for(var/state in device.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
device_icons["vent" + state] = image('icons/atmos/vent_pump.dmi', icon_state = state)
|
||||
|
||||
device = new('icons/atmos/vent_scrubber.dmi')
|
||||
for(var/state in device.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state)
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_omni_icons()
|
||||
if(!omni_icons)
|
||||
omni_icons = new()
|
||||
|
||||
var/icon/omni = new('icons/atmos/omni_devices.dmi')
|
||||
|
||||
for(var/state in omni.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state)
|
||||
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_underlay_icons()
|
||||
|
||||
if(!underlays)
|
||||
underlays = new()
|
||||
|
||||
var/icon/pipe = new('icons/atmos/pipe_underlays.dmi')
|
||||
|
||||
for(var/state in pipe.IconStates())
|
||||
if(state == "")
|
||||
continue
|
||||
|
||||
var/cache_name = state
|
||||
|
||||
for(var/D in cardinal)
|
||||
var/image/I = image('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D)
|
||||
underlays[cache_name + "[D]"] = I
|
||||
for(var/pipe_color in pipe_colors)
|
||||
I = image('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D)
|
||||
I.color = pipe_colors[pipe_color]
|
||||
underlays[state + "[D]" + "[pipe_colors[pipe_color]]"] = I
|
||||
|
||||
/*
|
||||
Leaving the old icon manager code commented out for now, as we may want to rewrite the new code to cleanly
|
||||
separate the newpipe icon caching (speshul supply and scrubber lines) from the rest of the pipe code.
|
||||
*/
|
||||
|
||||
/*
|
||||
/datum/pipe_icon_manager/proc/gen_underlay_icons()
|
||||
if(!underlays_intact)
|
||||
underlays_intact = new()
|
||||
if(!underlays_exposed)
|
||||
underlays_exposed = new()
|
||||
if(!underlays_down)
|
||||
underlays_down = new()
|
||||
if(!pipe_underlays_exposed)
|
||||
pipe_underlays_exposed = new()
|
||||
if(!pipe_underlays_intact)
|
||||
pipe_underlays_intact = new()
|
||||
|
||||
var/icon/pipe = new('icons/atmos/pipe_underlays.dmi')
|
||||
|
||||
for(var/state in pipe.IconStates())
|
||||
if(state == "")
|
||||
continue
|
||||
|
||||
for(var/D in cardinal)
|
||||
var/image/I = image('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D)
|
||||
switch(state)
|
||||
if("intact")
|
||||
underlays_intact["[D]"] = I
|
||||
if("exposed")
|
||||
underlays_exposed["[D]"] = I
|
||||
if("down")
|
||||
underlays_down["[D]"] = I
|
||||
if("pipe_exposed")
|
||||
pipe_underlays_exposed["[D]"] = I
|
||||
if("pipe_intact")
|
||||
pipe_underlays_intact["[D]"] = I
|
||||
if("intact-supply")
|
||||
underlays_intact["[D]"] = I
|
||||
if("exposed-supply")
|
||||
underlays_exposed["[D]"] = I
|
||||
if("down-supply")
|
||||
underlays_down["[D]"] = I
|
||||
if("pipe_exposed-supply")
|
||||
pipe_underlays_exposed["[D]"] = I
|
||||
if("pipe_intact-supply")
|
||||
pipe_underlays_intact["[D]"] = I
|
||||
if("intact-scrubbers")
|
||||
underlays_intact["[D]"] = I
|
||||
if("exposed-scrubbers")
|
||||
underlays_exposed["[D]"] = I
|
||||
if("down-scrubbers")
|
||||
underlays_down["[D]"] = I
|
||||
if("pipe_exposed-scrubbers")
|
||||
pipe_underlays_exposed["[D]"] = I
|
||||
if("pipe_intact-scrubbers")
|
||||
pipe_underlays_intact["[D]"] = I
|
||||
for(var/pipe_color in pipe_colors)
|
||||
I = image('icons/atmos/pipe_underlays.dmi', icon_state = state, dir = D)
|
||||
I.color = pipe_colors[pipe_color]
|
||||
switch(state)
|
||||
if("intact")
|
||||
underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("exposed")
|
||||
underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("down")
|
||||
underlays_down["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_exposed")
|
||||
pipe_underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_intact")
|
||||
pipe_underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("intact-supply")
|
||||
underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("exposed-supply")
|
||||
underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("down-supply")
|
||||
underlays_down["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_exposed-supply")
|
||||
pipe_underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_intact-supply")
|
||||
pipe_underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("intact-scrubbers")
|
||||
underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("exposed-scrubbers")
|
||||
underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("down-scrubbers")
|
||||
underlays_down["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_exposed-scrubbers")
|
||||
pipe_underlays_exposed["[D]" + pipe_colors[pipe_color]] = I
|
||||
if("pipe_intact-scrubbers")
|
||||
pipe_underlays_intact["[D]" + pipe_colors[pipe_color]] = I
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
Atmos processes
|
||||
|
||||
These procs generalize various processes used by atmos machinery, such as pumping, filtering, or scrubbing gas, allowing them to be reused elsewhere.
|
||||
If no gas was moved/pumped/filtered/whatever, they return a negative number.
|
||||
Otherwise they return the amount of energy needed to do whatever it is they do (equivalently power if done over 1 second).
|
||||
In the case of free-flowing gas you can do things with gas and still use 0 power, hence the distinction between negative and non-negative return values.
|
||||
*/
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/var/last_flow_rate = 0
|
||||
/obj/machinery/atmospherics/var/last_power_draw = 0
|
||||
/obj/machinery/portable_atmospherics/var/last_flow_rate = 0
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/var/debug = 0
|
||||
|
||||
/client/proc/atmos_toggle_debug(var/obj/machinery/atmospherics/M in range(world.view))
|
||||
set name = "Toggle Debug Messages"
|
||||
set category = "Debug"
|
||||
M.debug = !M.debug
|
||||
to_chat(usr, "[M]: Debug messages toggled [M.debug? "on" : "off"].")
|
||||
|
||||
//Generalized gas pumping proc.
|
||||
//Moves gas from one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was pumped.
|
||||
//transfer_moles - Limits the amount of moles to transfer. The actual amount of gas moved may also be limited by available_power, if given.
|
||||
//available_power - the maximum amount of power that may be used when moving gas. If null then the transfer is not limited by power.
|
||||
/proc/pump_gas(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null, var/available_power = null)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
if (isnull(transfer_moles))
|
||||
transfer_moles = source.total_moles
|
||||
else
|
||||
transfer_moles = min(source.total_moles, transfer_moles)
|
||||
|
||||
//Calculate the amount of energy required and limit transfer_moles based on available power
|
||||
var/specific_power = calculate_specific_power(source, sink)/ATMOS_PUMP_EFFICIENCY //this has to be calculated before we modify any gas mixtures
|
||||
if (!isnull(available_power) && specific_power > 0)
|
||||
transfer_moles = min(transfer_moles, available_power / specific_power)
|
||||
|
||||
if (transfer_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update flow rate meter
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
if (A.debug)
|
||||
A.visible_message("[A]: source entropy: [round(source.specific_entropy(), 0.01)] J/Kmol --> sink entropy: [round(sink.specific_entropy(), 0.01)] J/Kmol")
|
||||
A.visible_message("[A]: specific entropy change = [round(sink.specific_entropy() - source.specific_entropy(), 0.01)] J/Kmol")
|
||||
A.visible_message("[A]: specific power = [round(specific_power, 0.1)] W/mol")
|
||||
A.visible_message("[A]: moles transferred = [transfer_moles] mol")
|
||||
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
||||
if (!removed) //Just in case
|
||||
return -1
|
||||
|
||||
var/power_draw = specific_power*transfer_moles
|
||||
|
||||
sink.merge(removed)
|
||||
|
||||
return power_draw
|
||||
|
||||
//Gas 'pumping' proc for the case where the gas flow is passive and driven entirely by pressure differences (but still one-way).
|
||||
/proc/pump_gas_passive(var/obj/machinery/M, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/transfer_moles = null)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
if (isnull(transfer_moles))
|
||||
transfer_moles = source.total_moles
|
||||
else
|
||||
transfer_moles = min(source.total_moles, transfer_moles)
|
||||
|
||||
var/equalize_moles = calculate_equalize_moles(source, sink)
|
||||
transfer_moles = min(transfer_moles, equalize_moles)
|
||||
|
||||
if (transfer_moles < MINIMUM_MOLES_TO_PUMP) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update flow rate meter
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
if (A.debug)
|
||||
A.visible_message("[A]: moles transferred = [transfer_moles] mol")
|
||||
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
||||
if(!removed) //Just in case
|
||||
return -1
|
||||
sink.merge(removed)
|
||||
|
||||
return 0
|
||||
|
||||
//Generalized gas scrubbing proc.
|
||||
//Selectively moves specified gasses one gas_mixture to another and returns the amount of power needed (assuming 1 second), or -1 if no gas was filtered.
|
||||
//filtering - A list of gasids to be scrubbed from source
|
||||
//total_transfer_moles - Limits the amount of moles to scrub. The actual amount of gas scrubbed may also be limited by available_power, if given.
|
||||
//available_power - the maximum amount of power that may be used when scrubbing gas. If null then the scrubbing is not limited by power.
|
||||
/proc/scrub_gas(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
|
||||
|
||||
//Determine the specific power of each filterable gas type, and the total amount of filterable gas (gasses selected to be scrubbed)
|
||||
var/total_filterable_moles = 0 //the total amount of filterable gas
|
||||
var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type
|
||||
for (var/g in filtering)
|
||||
if (source.gas[g] < MINIMUM_MOLES_TO_FILTER)
|
||||
continue
|
||||
|
||||
var/specific_power = calculate_specific_power_gas(g, source, sink)/ATMOS_FILTER_EFFICIENCY
|
||||
specific_power_gas[g] = specific_power
|
||||
total_filterable_moles += source.gas[g]
|
||||
|
||||
if (total_filterable_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//now that we know the total amount of filterable gas, we can calculate the amount of power needed to scrub one mole of gas
|
||||
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
|
||||
for (var/g in filtering)
|
||||
var/ratio = source.gas[g]/total_filterable_moles //this converts the specific power per mole of pure gas to specific power per mole of scrubbed gas
|
||||
total_specific_power += specific_power_gas[g]*ratio
|
||||
|
||||
//Figure out how much of each gas to filter
|
||||
if (isnull(total_transfer_moles))
|
||||
total_transfer_moles = total_filterable_moles
|
||||
else
|
||||
total_transfer_moles = min(total_transfer_moles, total_filterable_moles)
|
||||
|
||||
//limit transfer_moles based on available power
|
||||
if (!isnull(available_power) && total_specific_power > 0)
|
||||
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
|
||||
|
||||
if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update flow rate var
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
var/power_draw = 0
|
||||
for (var/g in filtering)
|
||||
var/transfer_moles = source.gas[g]
|
||||
//filter gas in proportion to the mole ratio
|
||||
transfer_moles = min(transfer_moles, total_transfer_moles*(source.gas[g]/total_filterable_moles))
|
||||
|
||||
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
|
||||
source.adjust_gas(g, -transfer_moles, update=0)
|
||||
sink.adjust_gas_temp(g, transfer_moles, source.temperature, update=0)
|
||||
|
||||
power_draw += specific_power_gas[g]*transfer_moles
|
||||
|
||||
//Remix the resulting gases
|
||||
sink.update_values()
|
||||
source.update_values()
|
||||
|
||||
return power_draw
|
||||
|
||||
//Generalized gas filtering proc.
|
||||
//Filtering is a bit different from scrubbing. Instead of selectively moving the targeted gas types from one gas mix to another, filtering splits
|
||||
//the input gas into two outputs: one that contains /only/ the targeted gas types, and another that completely clean of the targeted gas types.
|
||||
//filtering - A list of gasids to be filtered. These gasses get moved to sink_filtered, while the other gasses get moved to sink_clean.
|
||||
//total_transfer_moles - Limits the amount of moles to input. The actual amount of gas filtered may also be limited by available_power, if given.
|
||||
//available_power - the maximum amount of power that may be used when filtering gas. If null then the filtering is not limited by power.
|
||||
/proc/filter_gas(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink_filtered, var/datum/gas_mixture/sink_clean, var/total_transfer_moles = null, var/available_power = null)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
|
||||
|
||||
var/total_specific_power = 0 //the power required to remove one mole of input gas
|
||||
var/total_filterable_moles = 0 //the total amount of filterable gas
|
||||
var/total_unfilterable_moles = 0 //the total amount of non-filterable gas
|
||||
var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type
|
||||
for (var/g in source.gas)
|
||||
if (source.gas[g] < MINIMUM_MOLES_TO_FILTER)
|
||||
continue
|
||||
|
||||
if (g in filtering)
|
||||
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_filtered)/ATMOS_FILTER_EFFICIENCY
|
||||
total_filterable_moles += source.gas[g]
|
||||
else
|
||||
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_clean)/ATMOS_FILTER_EFFICIENCY
|
||||
total_unfilterable_moles += source.gas[g]
|
||||
|
||||
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
|
||||
total_specific_power += specific_power_gas[g]*ratio
|
||||
|
||||
//Figure out how much of each gas to filter
|
||||
if (isnull(total_transfer_moles))
|
||||
total_transfer_moles = source.total_moles
|
||||
else
|
||||
total_transfer_moles = min(total_transfer_moles, source.total_moles)
|
||||
|
||||
//limit transfer_moles based on available power
|
||||
if (!isnull(available_power) && total_specific_power > 0)
|
||||
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
|
||||
|
||||
if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update flow rate var
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
var/datum/gas_mixture/removed = source.remove(total_transfer_moles)
|
||||
if (!removed) //Just in case
|
||||
return -1
|
||||
|
||||
var/filtered_power_used = 0 //power used to move filterable gas to sink_filtered
|
||||
var/unfiltered_power_used = 0 //power used to move unfilterable gas to sink_clean
|
||||
for (var/g in removed.gas)
|
||||
var/power_used = specific_power_gas[g]*removed.gas[g]
|
||||
|
||||
if (g in filtering)
|
||||
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
|
||||
sink_filtered.adjust_gas_temp(g, removed.gas[g], removed.temperature, update=0)
|
||||
removed.adjust_gas(g, -removed.gas[g], update=0)
|
||||
filtered_power_used += power_used
|
||||
else
|
||||
unfiltered_power_used += power_used
|
||||
|
||||
sink_filtered.update_values()
|
||||
removed.update_values()
|
||||
|
||||
sink_clean.merge(removed)
|
||||
|
||||
return filtered_power_used + unfiltered_power_used
|
||||
|
||||
//For omni devices. Instead filtering is an associative list mapping gasids to gas mixtures.
|
||||
//I don't like the copypasta, but I decided to keep both versions of gas filtering as filter_gas is slightly faster (doesn't create as many temporary lists, doesn't call update_values() as much)
|
||||
//filter_gas can be removed and replaced with this proc if need be.
|
||||
/proc/filter_gas_multi(var/obj/machinery/M, var/list/filtering, var/datum/gas_mixture/source, var/datum/gas_mixture/sink_clean, var/total_transfer_moles = null, var/available_power = null)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
filtering = filtering & source.gas //only filter gasses that are actually there. DO NOT USE &=
|
||||
|
||||
var/total_specific_power = 0 //the power required to remove one mole of input gas
|
||||
var/total_filterable_moles = 0 //the total amount of filterable gas
|
||||
var/total_unfilterable_moles = 0 //the total amount of non-filterable gas
|
||||
var/list/specific_power_gas = list() //the power required to remove one mole of pure gas, for each gas type
|
||||
for (var/g in source.gas)
|
||||
if (source.gas[g] < MINIMUM_MOLES_TO_FILTER)
|
||||
continue
|
||||
|
||||
if (g in filtering)
|
||||
var/datum/gas_mixture/sink_filtered = filtering[g]
|
||||
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_filtered)/ATMOS_FILTER_EFFICIENCY
|
||||
total_filterable_moles += source.gas[g]
|
||||
else
|
||||
specific_power_gas[g] = calculate_specific_power_gas(g, source, sink_clean)/ATMOS_FILTER_EFFICIENCY
|
||||
total_unfilterable_moles += source.gas[g]
|
||||
|
||||
var/ratio = source.gas[g]/source.total_moles //converts the specific power per mole of pure gas to specific power per mole of input gas mix
|
||||
total_specific_power += specific_power_gas[g]*ratio
|
||||
|
||||
//Figure out how much of each gas to filter
|
||||
if (isnull(total_transfer_moles))
|
||||
total_transfer_moles = source.total_moles
|
||||
else
|
||||
total_transfer_moles = min(total_transfer_moles, source.total_moles)
|
||||
|
||||
//limit transfer_moles based on available power
|
||||
if (!isnull(available_power) && total_specific_power > 0)
|
||||
total_transfer_moles = min(total_transfer_moles, available_power/total_specific_power)
|
||||
|
||||
if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update Flow Rate var
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (total_transfer_moles/source.total_moles)*source.volume //group_multiplier gets divided out here
|
||||
|
||||
var/datum/gas_mixture/removed = source.remove(total_transfer_moles)
|
||||
if (!removed) //Just in case
|
||||
return -1
|
||||
|
||||
var/list/filtered_power_used = list() //power used to move filterable gas to the filtered gas mixes
|
||||
var/unfiltered_power_used = 0 //power used to move unfilterable gas to sink_clean
|
||||
for (var/g in removed.gas)
|
||||
var/power_used = specific_power_gas[g]*removed.gas[g]
|
||||
|
||||
if (g in filtering)
|
||||
var/datum/gas_mixture/sink_filtered = filtering[g]
|
||||
//use update=0. All the filtered gasses are supposed to be added simultaneously, so we update after the for loop.
|
||||
sink_filtered.adjust_gas_temp(g, removed.gas[g], removed.temperature, update=1)
|
||||
removed.adjust_gas(g, -removed.gas[g], update=0)
|
||||
if (power_used)
|
||||
filtered_power_used[sink_filtered] = power_used
|
||||
else
|
||||
unfiltered_power_used += power_used
|
||||
|
||||
removed.update_values()
|
||||
|
||||
var/power_draw = unfiltered_power_used
|
||||
for (var/datum/gas_mixture/sink_filtered in filtered_power_used)
|
||||
power_draw += filtered_power_used[sink_filtered]
|
||||
|
||||
sink_clean.merge(removed)
|
||||
|
||||
return power_draw
|
||||
|
||||
//Similar deal as the other atmos process procs.
|
||||
//mix_sources maps input gas mixtures to mix ratios. The mix ratios MUST add up to 1.
|
||||
/proc/mix_gas(var/obj/machinery/M, var/list/mix_sources, var/datum/gas_mixture/sink, var/total_transfer_moles = null, var/available_power = null)
|
||||
if (!mix_sources.len)
|
||||
return -1
|
||||
|
||||
var/total_specific_power = 0 //the power needed to mix one mole of gas
|
||||
var/total_mixing_moles = null //the total amount of gas that can be mixed, given our mix ratios
|
||||
var/total_input_volume = 0 //for flow rate calculation
|
||||
var/total_input_moles = 0 //for flow rate calculation
|
||||
var/list/source_specific_power = list()
|
||||
for (var/datum/gas_mixture/source in mix_sources)
|
||||
if (source.total_moles < MINIMUM_MOLES_TO_FILTER)
|
||||
return -1 //either mix at the set ratios or mix no gas at all
|
||||
|
||||
var/mix_ratio = mix_sources[source]
|
||||
if (!mix_ratio)
|
||||
continue //this gas is not being mixed in
|
||||
|
||||
//mixing rate is limited by the source with the least amount of available gas
|
||||
var/this_mixing_moles = source.total_moles/mix_ratio
|
||||
if (isnull(total_mixing_moles) || total_mixing_moles > this_mixing_moles)
|
||||
total_mixing_moles = this_mixing_moles
|
||||
|
||||
source_specific_power[source] = calculate_specific_power(source, sink)*mix_ratio/ATMOS_FILTER_EFFICIENCY
|
||||
total_specific_power += source_specific_power[source]
|
||||
total_input_volume += source.volume
|
||||
total_input_moles += source.total_moles
|
||||
|
||||
if (total_mixing_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
if (isnull(total_transfer_moles))
|
||||
total_transfer_moles = total_mixing_moles
|
||||
else
|
||||
total_transfer_moles = min(total_mixing_moles, total_transfer_moles)
|
||||
|
||||
//limit transfer_moles based on available power
|
||||
if (!isnull(available_power) && total_specific_power > 0)
|
||||
total_transfer_moles = min(total_transfer_moles, available_power / total_specific_power)
|
||||
|
||||
if (total_transfer_moles < MINIMUM_MOLES_TO_FILTER) //if we cant transfer enough gas just stop to avoid further processing
|
||||
return -1
|
||||
|
||||
//Update flow rate var
|
||||
if (istype(M, /obj/machinery/atmospherics))
|
||||
var/obj/machinery/atmospherics/A = M
|
||||
A.last_flow_rate = (total_transfer_moles/total_input_moles)*total_input_volume //group_multiplier gets divided out here
|
||||
if (istype(M, /obj/machinery/portable_atmospherics))
|
||||
var/obj/machinery/portable_atmospherics/P = M
|
||||
P.last_flow_rate = (total_transfer_moles/total_input_moles)*total_input_volume //group_multiplier gets divided out here
|
||||
|
||||
var/total_power_draw = 0
|
||||
for (var/datum/gas_mixture/source in mix_sources)
|
||||
var/mix_ratio = mix_sources[source]
|
||||
if (!mix_ratio)
|
||||
continue
|
||||
|
||||
var/transfer_moles = total_transfer_moles * mix_ratio
|
||||
|
||||
var/datum/gas_mixture/removed = source.remove(transfer_moles)
|
||||
|
||||
var/power_draw = transfer_moles * source_specific_power[source]
|
||||
total_power_draw += power_draw
|
||||
|
||||
sink.merge(removed)
|
||||
|
||||
return total_power_draw
|
||||
|
||||
/*
|
||||
Helper procs for various things.
|
||||
*/
|
||||
|
||||
//Calculates the amount of power needed to move one mole from source to sink.
|
||||
/proc/calculate_specific_power(datum/gas_mixture/source, datum/gas_mixture/sink)
|
||||
//Calculate the amount of energy required
|
||||
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
||||
var/specific_entropy = sink.specific_entropy() - source.specific_entropy() //sink is gaining moles, source is loosing
|
||||
var/specific_power = 0 // W/mol
|
||||
|
||||
//If specific_entropy is < 0 then power is required to move gas
|
||||
if (specific_entropy < 0)
|
||||
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
||||
|
||||
return specific_power
|
||||
|
||||
//Calculates the amount of power needed to move one mole of a certain gas from source to sink.
|
||||
/proc/calculate_specific_power_gas(var/gasid, datum/gas_mixture/source, datum/gas_mixture/sink)
|
||||
//Calculate the amount of energy required
|
||||
var/air_temperature = (sink.temperature > 0)? sink.temperature : source.temperature
|
||||
var/specific_entropy = sink.specific_entropy_gas(gasid) - source.specific_entropy_gas(gasid) //sink is gaining moles, source is loosing
|
||||
var/specific_power = 0 // W/mol
|
||||
|
||||
//If specific_entropy is < 0 then power is required to move gas
|
||||
if (specific_entropy < 0)
|
||||
specific_power = -specific_entropy*air_temperature //how much power we need per mole
|
||||
|
||||
return specific_power
|
||||
|
||||
//Calculates the APPROXIMATE amount of moles that would need to be transferred to change the pressure of sink by pressure_delta
|
||||
//If set, sink_volume_mod adjusts the effective output volume used in the calculation. This is useful when the output gas_mixture is
|
||||
//part of a pipenetwork, and so it's volume isn't representative of the actual volume since the gas will be shared across the pipenetwork when it processes.
|
||||
/proc/calculate_transfer_moles(datum/gas_mixture/source, datum/gas_mixture/sink, var/pressure_delta, var/sink_volume_mod=0)
|
||||
if(source.temperature == 0 || source.total_moles == 0) return 0
|
||||
|
||||
var/output_volume = (sink.volume * sink.group_multiplier) + sink_volume_mod
|
||||
var/source_total_moles = source.total_moles * source.group_multiplier
|
||||
|
||||
var/air_temperature = source.temperature
|
||||
if(sink.total_moles > 0 && sink.temperature > 0)
|
||||
//estimate the final temperature of the sink after transfer
|
||||
var/estimate_moles = pressure_delta*output_volume/(sink.temperature * R_IDEAL_GAS_EQUATION)
|
||||
var/sink_heat_capacity = sink.heat_capacity()
|
||||
var/transfer_heat_capacity = source.heat_capacity()*estimate_moles/source_total_moles
|
||||
air_temperature = (sink.temperature*sink_heat_capacity + source.temperature*transfer_heat_capacity) / (sink_heat_capacity + transfer_heat_capacity)
|
||||
|
||||
//get the number of moles that would have to be transfered to bring sink to the target pressure
|
||||
return pressure_delta*output_volume/(air_temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Calculates the APPROXIMATE amount of moles that would need to be transferred to bring source and sink to the same pressure
|
||||
/proc/calculate_equalize_moles(datum/gas_mixture/source, datum/gas_mixture/sink)
|
||||
if(source.temperature == 0) return 0
|
||||
|
||||
//Make the approximation that the sink temperature is unchanged after transferring gas
|
||||
var/source_volume = source.volume * source.group_multiplier
|
||||
var/sink_volume = sink.volume * sink.group_multiplier
|
||||
|
||||
var/source_pressure = source.return_pressure()
|
||||
var/sink_pressure = sink.return_pressure()
|
||||
|
||||
return (source_pressure - sink_pressure)/(R_IDEAL_GAS_EQUATION * (source.temperature/source_volume + sink.temperature/sink_volume))
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
Quick overview:
|
||||
|
||||
Pipes combine to form pipelines
|
||||
Pipelines and other atmospheric objects combine to form pipe_networks
|
||||
Note: A single pipe_network represents a completely open space
|
||||
|
||||
Pipes -> Pipelines
|
||||
Pipelines + Other Objects -> Pipe network
|
||||
|
||||
*/
|
||||
/obj/machinery/atmospherics
|
||||
anchored = 1
|
||||
idle_power_usage = 0
|
||||
active_power_usage = 0
|
||||
power_channel = ENVIRON
|
||||
var/nodealert = 0
|
||||
var/power_rating //the maximum amount of power the machine can use to do work, affects how powerful the machine is, in Watts
|
||||
|
||||
layer = 2.4 //under wires with their 2.44
|
||||
|
||||
var/connect_types = CONNECT_TYPE_REGULAR
|
||||
var/icon_connect_type = "" //"-supply" or "-scrubbers"
|
||||
|
||||
var/initialize_directions = 0
|
||||
var/pipe_color
|
||||
|
||||
var/global/datum/pipe_icon_manager/icon_manager
|
||||
var/obj/machinery/atmospherics/node1
|
||||
var/obj/machinery/atmospherics/node2
|
||||
gfi_layer_rotation = GFI_ROTATION_OVERDIR
|
||||
|
||||
/obj/machinery/atmospherics/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!icon_manager)
|
||||
icon_manager = new()
|
||||
|
||||
if(!pipe_color)
|
||||
pipe_color = color
|
||||
color = null
|
||||
|
||||
if(!pipe_color_check(pipe_color))
|
||||
pipe_color = null
|
||||
|
||||
if (mapload)
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/atmospherics/proc/atmos_init()
|
||||
|
||||
// atmos_init() and Initialize() must be separate, as atmos_init() can be called multiple times after the machine has been initialized.
|
||||
|
||||
/obj/machinery/atmospherics/LateInitialize()
|
||||
atmos_init()
|
||||
|
||||
/obj/machinery/atmospherics/attackby(atom/A, mob/user as mob)
|
||||
if(istype(A, /obj/item/device/pipe_painter))
|
||||
return FALSE
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/proc/add_underlay(var/turf/T, var/obj/machinery/atmospherics/node, var/direction, var/icon_connect_type)
|
||||
if(node)
|
||||
if(!T.is_plating() && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
//underlays += icon_manager.get_atmos_icon("underlay_down", direction, color_cache_name(node))
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "down" + icon_connect_type)
|
||||
else
|
||||
//underlays += icon_manager.get_atmos_icon("underlay_intact", direction, color_cache_name(node))
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "intact" + icon_connect_type)
|
||||
else
|
||||
//underlays += icon_manager.get_atmos_icon("underlay_exposed", direction, pipe_color)
|
||||
underlays += icon_manager.get_atmos_icon("underlay", direction, color_cache_name(node), "exposed" + icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/proc/update_underlays()
|
||||
if(check_icon_cache())
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/atmos1, obj/machinery/atmospherics/atmos2)
|
||||
return (atmos1.connect_types & atmos2.connect_types)
|
||||
|
||||
/obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/atmospherics/atmos1, obj/item/pipe/pipe2)
|
||||
return (atmos1.connect_types & pipe2.connect_types)
|
||||
|
||||
/obj/machinery/atmospherics/proc/check_icon_cache(var/safety = 0)
|
||||
if(!istype(icon_manager))
|
||||
if(!safety) //to prevent infinite loops
|
||||
icon_manager = new()
|
||||
check_icon_cache(1)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/proc/color_cache_name(var/obj/machinery/atmospherics/node)
|
||||
//Don't use this for standard pipes
|
||||
if(!istype(node))
|
||||
return null
|
||||
|
||||
return node.pipe_color
|
||||
|
||||
/obj/machinery/atmospherics/process()
|
||||
last_flow_rate = 0
|
||||
last_power_draw = 0
|
||||
|
||||
build_network()
|
||||
|
||||
/obj/machinery/atmospherics/proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
// Check to see if should be added to network. Add self if so and adjust variables appropriately.
|
||||
// Note don't forget to have neighbors look as well!
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/proc/build_network()
|
||||
// Called to build a network from this node
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/proc/return_network(obj/machinery/atmospherics/reference)
|
||||
// Returns pipe_network associated with connection to reference
|
||||
// Notes: should create network if necessary
|
||||
// Should never return null
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/proc/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
// Used when two pipe_networks are combining
|
||||
|
||||
/obj/machinery/atmospherics/proc/remove_network(datum/pipe_network/network)
|
||||
reassign_network(network, null)
|
||||
|
||||
/obj/machinery/atmospherics/proc/return_network_air(datum/pipe_network/reference)
|
||||
// Return a list of gas_mixture(s) in the object
|
||||
// associated with reference pipe_network for use in rebuilding the networks gases list
|
||||
// Is permitted to return null
|
||||
|
||||
/obj/machinery/atmospherics/proc/disconnect(obj/machinery/atmospherics/reference)
|
||||
|
||||
/obj/machinery/atmospherics/update_icon()
|
||||
return null
|
||||
@@ -0,0 +1,139 @@
|
||||
/obj/machinery/atmospherics/binary
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH
|
||||
|
||||
var/datum/gas_mixture/air1
|
||||
var/datum/gas_mixture/air2
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
|
||||
/obj/machinery/atmospherics/binary/Initialize()
|
||||
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
|
||||
air1 = new
|
||||
air2 = new
|
||||
|
||||
air1.volume = 200
|
||||
air2.volume = 200
|
||||
. = ..()
|
||||
|
||||
// Housekeeping and pipe network stuff below
|
||||
/obj/machinery/atmospherics/binary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network1 = new_network
|
||||
|
||||
else if(reference == node2)
|
||||
network2 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/binary/Destroy()
|
||||
QDEL_NULL(air1)
|
||||
QDEL_NULL(air2)
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
QDEL_NULL(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
QDEL_NULL(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/binary/atmos_init()
|
||||
if(node1 && node2) return
|
||||
|
||||
var/node2_connect = dir
|
||||
var/node1_connect = turn(dir, 180)
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/binary/build_network()
|
||||
if(!network1 && node1)
|
||||
network1 = new /datum/pipe_network()
|
||||
network1.normal_members += src
|
||||
network1.build_network(node1, src)
|
||||
|
||||
if(!network2 && node2)
|
||||
network2 = new /datum/pipe_network()
|
||||
network2.normal_members += src
|
||||
network2.build_network(node2, src)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/binary/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network1
|
||||
|
||||
if(reference==node2)
|
||||
return network2
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/binary/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network1 == old_network)
|
||||
network1 = new_network
|
||||
if(network2 == old_network)
|
||||
network2 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(network1 == reference)
|
||||
results += air1
|
||||
if(network2 == reference)
|
||||
results += air2
|
||||
|
||||
return results
|
||||
|
||||
/obj/machinery/atmospherics/binary/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network2)
|
||||
node2 = null
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/binary/AltClick(var/mob/user)
|
||||
if(!allowed(user))
|
||||
to_chat(user, SPAN_WARNING("Access denied."))
|
||||
return
|
||||
Topic(src, list("power" = "1"))
|
||||
@@ -0,0 +1,126 @@
|
||||
//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."
|
||||
desc_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
|
||||
the center of the machine gives an indicator of how much elecrtricity is being generated."
|
||||
icon = 'icons/obj/pipes.dmi'
|
||||
icon_state = "circ-off"
|
||||
anchored = FALSE
|
||||
obj_flags = OBJ_FLAG_ROTATABLE
|
||||
|
||||
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 = TRUE
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/Initialize()
|
||||
. = ..()
|
||||
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
||||
air1.volume = 400
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
|
||||
var/datum/gas_mixture/removed
|
||||
if(anchored && !(stat&BROKEN) && network1)
|
||||
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*network1.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*network1.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 * network1.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(stat & (BROKEN|NOPOWER) || !anchored)
|
||||
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/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (W.iswrench())
|
||||
playsound(src.loc, W.usesound, 75, 1)
|
||||
anchored = !anchored
|
||||
user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \
|
||||
"You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \
|
||||
"You hear a ratchet")
|
||||
|
||||
if(anchored)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
initialize_directions = NORTH|SOUTH
|
||||
else if(dir & (EAST|WEST))
|
||||
initialize_directions = EAST|WEST
|
||||
|
||||
atmos_init()
|
||||
build_network()
|
||||
if (node1)
|
||||
node1.atmos_init()
|
||||
node1.build_network()
|
||||
if (node2)
|
||||
node2.atmos_init()
|
||||
node2.build_network()
|
||||
else
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
return TRUE
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,271 @@
|
||||
#define DEFAULT_PRESSURE_DELTA 10000
|
||||
|
||||
#define EXTERNAL_PRESSURE_BOUND ONE_ATMOSPHERE
|
||||
#define INTERNAL_PRESSURE_BOUND 0
|
||||
#define PRESSURE_CHECKS 1
|
||||
|
||||
#define PRESSURE_CHECK_EXTERNAL 1
|
||||
#define PRESSURE_CHECK_INPUT 2
|
||||
#define PRESSURE_CHECK_OUTPUT 4
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_dp_vent"
|
||||
|
||||
//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
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //7500 W ~ 10 HP
|
||||
|
||||
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY|CONNECT_TYPE_SCRUBBER //connects to regular, supply and scrubbers pipes
|
||||
|
||||
var/pump_direction = 1 //0 = siphoning, 1 = releasing
|
||||
|
||||
var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND
|
||||
var/input_pressure_min = INTERNAL_PRESSURE_BOUND
|
||||
var/output_pressure_max = DEFAULT_PRESSURE_DELTA
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/pressure_checks = PRESSURE_CHECK_EXTERNAL
|
||||
//1: Do not pass external_pressure_bound
|
||||
//2: Do not pass input_pressure_min
|
||||
//4: Do not pass output_pressure_max
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/Initialize()
|
||||
. = ..()
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_PUMP
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_PUMP
|
||||
icon = null
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume
|
||||
name = "Large Dual Port Air Vent"
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume/Initialize()
|
||||
. = ..()
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_PUMP + 800
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_PUMP + 800
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/update_icon(var/safety = 0)
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
var/istate = ""
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
istate += "h"
|
||||
|
||||
if(!powered())
|
||||
istate += "off"
|
||||
else
|
||||
istate += "[use_power ? "[pump_direction ? "out" : "in"]" : "off"]"
|
||||
|
||||
icon_state = istate
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!T.is_plating() && node1 && node2 && node1.level == 1 && node2.level == 1 && istype(node1, /obj/machinery/atmospherics/pipe) && istype(node2, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if (node1)
|
||||
add_underlay(T, node1, turn(dir, -180), node1.icon_connect_type)
|
||||
else
|
||||
add_underlay(T, node1, turn(dir, -180))
|
||||
if (node2)
|
||||
add_underlay(T, node2, dir, node2.icon_connect_type)
|
||||
else
|
||||
add_underlay(T, node2, dir)
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/hide(var/i)
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/process()
|
||||
..()
|
||||
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if(stat & (NOPOWER|BROKEN) || !use_power)
|
||||
return 0
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/power_draw = -1
|
||||
|
||||
//Figure out the target pressure difference
|
||||
var/pressure_delta = get_pressure_delta(environment)
|
||||
|
||||
if(pressure_delta > 0.5)
|
||||
if(pump_direction) //internal -> external
|
||||
if (node1 && (environment.temperature || air1.temperature))
|
||||
var/transfer_moles = calculate_transfer_moles(air1, environment, pressure_delta)
|
||||
power_draw = pump_gas(src, air1, environment, transfer_moles, power_rating)
|
||||
|
||||
if(power_draw >= 0 && network1)
|
||||
network1.update = 1
|
||||
else //external -> internal
|
||||
if (node2 && (environment.temperature || air2.temperature))
|
||||
var/transfer_moles = calculate_transfer_moles(environment, air2, pressure_delta, (network2)? network2.volume : 0)
|
||||
|
||||
//limit flow rate from turfs
|
||||
transfer_moles = min(transfer_moles, environment.total_moles*air2.volume/environment.volume) //group_multiplier gets divided out here
|
||||
power_draw = pump_gas(src, environment, air2, transfer_moles, power_rating)
|
||||
|
||||
if(power_draw >= 0 && network2)
|
||||
network2.update = 1
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/proc/get_pressure_delta(datum/gas_mixture/environment)
|
||||
var/pressure_delta = DEFAULT_PRESSURE_DELTA
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction) //internal -> external
|
||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||
pressure_delta = min(pressure_delta, external_pressure_bound - environment_pressure) //increasing the pressure here
|
||||
if(pressure_checks & PRESSURE_CHECK_INPUT)
|
||||
pressure_delta = min(pressure_delta, air1.return_pressure() - input_pressure_min) //decreasing the pressure here
|
||||
else //external -> internal
|
||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||
pressure_delta = min(pressure_delta, environment_pressure - external_pressure_bound) //decreasing the pressure here
|
||||
if(pressure_checks & PRESSURE_CHECK_OUTPUT)
|
||||
pressure_delta = min(pressure_delta, output_pressure_max - air2.return_pressure()) //increasing the pressure here
|
||||
|
||||
return pressure_delta
|
||||
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/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/binary/dp_vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "ADVP",
|
||||
"power" = use_power,
|
||||
"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/binary/dp_vent_pump/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
if(signal.data["power"])
|
||||
update_use_power(text2num(signal.data["power"]))
|
||||
|
||||
if(signal.data["power_toggle"])
|
||||
update_use_power(!use_power)
|
||||
|
||||
if(signal.data["direction"])
|
||||
pump_direction = text2num(signal.data["direction"])
|
||||
|
||||
if(signal.data["checks"])
|
||||
pressure_checks = text2num(signal.data["checks"])
|
||||
|
||||
if(signal.data["purge"])
|
||||
pressure_checks &= ~1
|
||||
pump_direction = 0
|
||||
|
||||
if(signal.data["stabalize"])
|
||||
pressure_checks |= 1
|
||||
pump_direction = 1
|
||||
|
||||
if(signal.data["set_input_pressure"])
|
||||
input_pressure_min = between(
|
||||
0,
|
||||
text2num(signal.data["set_input_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["set_output_pressure"])
|
||||
output_pressure_max = between(
|
||||
0,
|
||||
text2num(signal.data["set_output_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["set_external_pressure"])
|
||||
external_pressure_bound = between(
|
||||
0,
|
||||
text2num(signal.data["set_external_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["status"])
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
|
||||
#undef DEFAULT_PRESSURE_DELTA
|
||||
|
||||
#undef EXTERNAL_PRESSURE_BOUND
|
||||
#undef INTERNAL_PRESSURE_BOUND
|
||||
#undef PRESSURE_CHECKS
|
||||
|
||||
#undef PRESSURE_CHECK_EXTERNAL
|
||||
#undef PRESSURE_CHECK_INPUT
|
||||
#undef PRESSURE_CHECK_OUTPUT
|
||||
@@ -0,0 +1,300 @@
|
||||
#define REGULATE_NONE 0
|
||||
#define REGULATE_INPUT 1 //shuts off when input side is below the target pressure
|
||||
#define REGULATE_OUTPUT 2 //shuts off when output side is above the target pressure
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate
|
||||
name = "pressure regulator"
|
||||
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. Does not require power."
|
||||
desc_info = "This is a one-way regulator, allowing gas to flow only at a specific pressure and flow rate. If the light is green, it is flowing."
|
||||
icon = 'icons/atmos/passive_gate.dmi'
|
||||
icon_state = "map"
|
||||
level = 1
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
interact_offline = 1
|
||||
var/unlocked = 0 //If 0, then the valve is locked closed, otherwise it is open(-able, it's a one-way valve so it closes if gas would flow backwards).
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
var/max_pressure_setting = ATMOS_PUMP_MAX_PRESSURE //kPa
|
||||
var/set_flow_rate = ATMOS_DEFAULT_VOLUME_PUMP * 2.5
|
||||
var/regulate_mode = REGULATE_OUTPUT
|
||||
|
||||
var/flowing = 0 //for icons - becomes zero if the valve closes itself due to regulation mode
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/on
|
||||
unlocked = 1
|
||||
/obj/machinery/atmospherics/binary/passive_gate/on/input
|
||||
regulate_mode = REGULATE_INPUT
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/on/output/max/Initialize()
|
||||
. = ..()
|
||||
target_pressure = max_pressure_setting
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/on/input/max/Initialize()
|
||||
. = ..()
|
||||
target_pressure = max_pressure_setting
|
||||
/obj/machinery/atmospherics/binary/passive_gate/scrubbers
|
||||
name = "scrubbers pressure regulator"
|
||||
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. This is one is for scrubber pipes."
|
||||
icon_state = "map-scrubbers"
|
||||
connect_types = CONNECT_TYPE_SCRUBBER
|
||||
icon_connect_type = "-scrubbers"
|
||||
|
||||
unlocked = TRUE
|
||||
target_pressure = 200
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/supply
|
||||
name = "supply pressure regulator"
|
||||
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. This is one is for supply pipes."
|
||||
icon_state = "map-supply"
|
||||
connect_types = CONNECT_TYPE_SUPPLY
|
||||
icon_connect_type = "-supply"
|
||||
|
||||
unlocked = TRUE
|
||||
target_pressure = 200
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/Initialize()
|
||||
. = ..()
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_PUMP * 2.5
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_PUMP * 2.5
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/update_icon()
|
||||
icon_state = (unlocked && flowing)? "on" + icon_connect_type : "off" + icon_connect_type
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node1, turn(dir, 180), icon_connect_type)
|
||||
add_underlay(T, node2, dir, icon_connect_type)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/process()
|
||||
..()
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
last_flow_rate = 0
|
||||
|
||||
if(!unlocked)
|
||||
return 0
|
||||
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
var/input_starting_pressure = air1.return_pressure()
|
||||
|
||||
var/pressure_delta
|
||||
switch (regulate_mode)
|
||||
if (REGULATE_INPUT)
|
||||
pressure_delta = input_starting_pressure - target_pressure
|
||||
if (REGULATE_OUTPUT)
|
||||
pressure_delta = target_pressure - output_starting_pressure
|
||||
|
||||
//-1 if pump_gas() did not move any gas, >= 0 otherwise
|
||||
var/returnval = -1
|
||||
if((regulate_mode == REGULATE_NONE || pressure_delta > 0.01) && (air1.temperature > 0 || air2.temperature > 0)) //since it's basically a valve, it makes sense to check both temperatures
|
||||
flowing = 1
|
||||
|
||||
//flow rate limit
|
||||
var/transfer_moles = (set_flow_rate/air1.volume)*air1.total_moles
|
||||
|
||||
//Figure out how much gas to transfer to meet the target pressure.
|
||||
switch (regulate_mode)
|
||||
if (REGULATE_INPUT)
|
||||
transfer_moles = min(transfer_moles, air1.total_moles*(pressure_delta/input_starting_pressure))
|
||||
if (REGULATE_OUTPUT)
|
||||
transfer_moles = min(transfer_moles, calculate_transfer_moles(air1, air2, pressure_delta, (network2)? network2.volume : 0))
|
||||
|
||||
//pump_gas() will return a negative number if no flow occurred
|
||||
returnval = pump_gas_passive(src, air1, air2, transfer_moles)
|
||||
|
||||
if (returnval >= 0)
|
||||
if(network1)
|
||||
network1.update = 1
|
||||
|
||||
if(network2)
|
||||
network2.update = 1
|
||||
|
||||
if (last_flow_rate)
|
||||
flowing = 1
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/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/binary/passive_gate/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AGP",
|
||||
"power" = unlocked,
|
||||
"target_output" = target_pressure,
|
||||
"regulate_mode" = regulate_mode,
|
||||
"set_flow_rate" = set_flow_rate,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if("power" in signal.data)
|
||||
unlocked = text2num(signal.data["power"])
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
unlocked = !unlocked
|
||||
|
||||
if("set_target_pressure" in signal.data)
|
||||
target_pressure = between(
|
||||
0,
|
||||
text2num(signal.data["set_target_pressure"]),
|
||||
max_pressure_setting
|
||||
)
|
||||
|
||||
if("set_regulate_mode" in signal.data)
|
||||
regulate_mode = text2num(signal.data["set_regulate_mode"])
|
||||
|
||||
if("set_flow_rate" in signal.data)
|
||||
regulate_mode = text2num(signal.data["set_flow_rate"])
|
||||
|
||||
if("status" in signal.data)
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
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)
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
|
||||
data = list(
|
||||
"on" = unlocked,
|
||||
"pressure_set" = round(target_pressure*100), //Nano UI can't handle rounded non-integers, apparently.
|
||||
"max_pressure" = max_pressure_setting,
|
||||
"input_pressure" = round(air1.return_pressure()*100),
|
||||
"output_pressure" = round(air2.return_pressure()*100),
|
||||
"regulate_mode" = regulate_mode,
|
||||
"set_flow_rate" = round(set_flow_rate*10),
|
||||
"last_flow_rate" = round(last_flow_rate*10)
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "pressure_regulator.tmpl", name, 470, 370)
|
||||
ui.set_initial_data(data) // when the ui is first opened this is the data it will use
|
||||
ui.open() // open the new ui window
|
||||
ui.set_auto_update(1) // auto update every Master Controller tick
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/Topic(href,href_list)
|
||||
if(..()) return 1
|
||||
|
||||
if(href_list["toggle_valve"])
|
||||
unlocked = !unlocked
|
||||
|
||||
if(href_list["regulate_mode"])
|
||||
switch(href_list["regulate_mode"])
|
||||
if ("off") regulate_mode = REGULATE_NONE
|
||||
if ("input") regulate_mode = REGULATE_INPUT
|
||||
if ("output") regulate_mode = REGULATE_OUTPUT
|
||||
|
||||
switch(href_list["set_press"])
|
||||
if ("min")
|
||||
target_pressure = 0
|
||||
if ("max")
|
||||
target_pressure = max_pressure_setting
|
||||
if ("set")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure Control",src.target_pressure) as num
|
||||
src.target_pressure = between(0, new_pressure, max_pressure_setting)
|
||||
|
||||
switch(href_list["set_flow_rate"])
|
||||
if ("min")
|
||||
set_flow_rate = 0
|
||||
if ("max")
|
||||
set_flow_rate = air1.volume
|
||||
if ("set")
|
||||
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[air1.volume]kPa)","Flow Rate Control",src.set_flow_rate) as num
|
||||
src.set_flow_rate = between(0, new_flow_rate, air1.volume)
|
||||
|
||||
usr.set_machine(src) //Is this even needed with NanoUI?
|
||||
src.update_icon()
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/binary/passive_gate/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
if (unlocked)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], turn it off first.</span>")
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
#undef REGULATE_NONE
|
||||
#undef REGULATE_INPUT
|
||||
#undef REGULATE_OUTPUT
|
||||
@@ -0,0 +1,250 @@
|
||||
/obj/machinery/atmospherics/pipeturbine
|
||||
name = "turbine"
|
||||
desc = "A gas turbine. Converting pressure into energy since 1884."
|
||||
icon = 'icons/obj/pipeturbine.dmi'
|
||||
icon_state = "turbine"
|
||||
anchored = 0
|
||||
density = 1
|
||||
obj_flags = OBJ_FLAG_ROTATABLE
|
||||
|
||||
var/efficiency = 0.4
|
||||
var/kin_energy = 0
|
||||
var/datum/gas_mixture/air_in
|
||||
var/datum/gas_mixture/air_out
|
||||
var/volume_ratio = 0.2
|
||||
var/kin_loss = 0.001
|
||||
|
||||
var/dP = 0
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
|
||||
Initialize()
|
||||
air_in = new
|
||||
air_in.volume = 200
|
||||
air_out = new
|
||||
air_out.volume = 800
|
||||
volume_ratio = air_in.volume / (air_in.volume + air_out.volume)
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = EAST|WEST
|
||||
if(SOUTH)
|
||||
initialize_directions = EAST|WEST
|
||||
if(EAST)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
if(WEST)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
. = ..()
|
||||
|
||||
Destroy()
|
||||
loc = null
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
return ..()
|
||||
|
||||
process()
|
||||
..()
|
||||
if(anchored && !(stat&BROKEN))
|
||||
kin_energy *= 1 - kin_loss
|
||||
dP = max(air_in.return_pressure() - air_out.return_pressure(), 0)
|
||||
if(dP > 10)
|
||||
kin_energy += 1/ADIABATIC_EXPONENT * dP * air_in.volume * (1 - volume_ratio**ADIABATIC_EXPONENT) * efficiency
|
||||
air_in.temperature *= volume_ratio**ADIABATIC_EXPONENT
|
||||
|
||||
var/datum/gas_mixture/air_all = new
|
||||
air_all.volume = air_in.volume + air_out.volume
|
||||
air_all.merge(air_in.remove_ratio(1))
|
||||
air_all.merge(air_out.remove_ratio(1))
|
||||
|
||||
air_in.merge(air_all.remove(volume_ratio))
|
||||
air_out.merge(air_all)
|
||||
|
||||
update_icon()
|
||||
|
||||
if (network1)
|
||||
network1.update = 1
|
||||
if (network2)
|
||||
network2.update = 1
|
||||
|
||||
update_icon()
|
||||
cut_overlays()
|
||||
if (dP > 10)
|
||||
add_overlay("moto-turb")
|
||||
if (kin_energy > 100000)
|
||||
add_overlay("low-turb")
|
||||
if (kin_energy > 500000)
|
||||
add_overlay("med-turb")
|
||||
if (kin_energy > 1000000)
|
||||
add_overlay("hi-turb")
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(W.iswrench())
|
||||
anchored = !anchored
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>")
|
||||
|
||||
if(anchored)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
initialize_directions = EAST|WEST
|
||||
else if(dir & (EAST|WEST))
|
||||
initialize_directions = NORTH|SOUTH
|
||||
|
||||
atmos_init()
|
||||
build_network()
|
||||
if (node1)
|
||||
node1.atmos_init()
|
||||
node1.build_network()
|
||||
if (node2)
|
||||
node2.atmos_init()
|
||||
node2.build_network()
|
||||
else
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
//Goddamn copypaste from binary base class because atmospherics machinery API is not damn flexible
|
||||
network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network1 = new_network
|
||||
|
||||
else if(reference == node2)
|
||||
network2 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
return null
|
||||
|
||||
atmos_init()
|
||||
if(node1 && node2) return
|
||||
|
||||
var/node2_connect = turn(dir, -90)
|
||||
var/node1_connect = turn(dir, 90)
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
build_network()
|
||||
if(!network1 && node1)
|
||||
network1 = new /datum/pipe_network()
|
||||
network1.normal_members += src
|
||||
network1.build_network(node1, src)
|
||||
|
||||
if(!network2 && node2)
|
||||
network2 = new /datum/pipe_network()
|
||||
network2.normal_members += src
|
||||
network2.build_network(node2, src)
|
||||
|
||||
|
||||
return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network1
|
||||
|
||||
if(reference==node2)
|
||||
return network2
|
||||
|
||||
return null
|
||||
|
||||
reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network1 == old_network)
|
||||
network1 = new_network
|
||||
if(network2 == old_network)
|
||||
network2 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(network1 == reference)
|
||||
results += air_in
|
||||
if(network2 == reference)
|
||||
results += air_out
|
||||
|
||||
return results
|
||||
|
||||
disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network2)
|
||||
node2 = null
|
||||
|
||||
return null
|
||||
|
||||
|
||||
/obj/machinery/power/turbinemotor
|
||||
name = "motor"
|
||||
desc = "Electrogenerator. Converts rotation into power."
|
||||
icon = 'icons/obj/pipeturbine.dmi'
|
||||
icon_state = "motor"
|
||||
anchored = 0
|
||||
density = 1
|
||||
obj_flags = OBJ_FLAG_ROTATABLE
|
||||
|
||||
var/kin_to_el_ratio = 0.1 //How much kinetic energy will be taken from turbine and converted into electricity
|
||||
var/obj/machinery/atmospherics/pipeturbine/turbine
|
||||
|
||||
Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
LateInitialize()
|
||||
..()
|
||||
updateConnection()
|
||||
|
||||
proc/updateConnection()
|
||||
turbine = null
|
||||
if(src.loc && anchored)
|
||||
turbine = locate(/obj/machinery/atmospherics/pipeturbine) in get_step(src,dir)
|
||||
if (turbine.stat & (BROKEN) || !turbine.anchored || turn(turbine.dir,180) != dir)
|
||||
turbine = null
|
||||
|
||||
process()
|
||||
updateConnection()
|
||||
if(!turbine || !anchored || stat & (BROKEN))
|
||||
return
|
||||
|
||||
var/power_generated = kin_to_el_ratio * turbine.kin_energy
|
||||
turbine.kin_energy -= power_generated
|
||||
add_avail(power_generated)
|
||||
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(W.iswrench())
|
||||
anchored = !anchored
|
||||
turbine = null
|
||||
to_chat(user, "<span class='notice'>You [anchored ? "secure" : "unsecure"] the bolts holding \the [src] to the floor.</span>")
|
||||
updateConnection()
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
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
|
||||
name = "gas pump"
|
||||
desc = "A pump."
|
||||
desc_info = "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output."
|
||||
icon = 'icons/atmos/pump.dmi'
|
||||
icon_state = "map_off"
|
||||
level = 1
|
||||
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
//var/max_volume_transfer = 10000
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //7500 W ~ 10 HP
|
||||
|
||||
var/max_pressure_setting = ATMOS_PUMP_MAX_PRESSURE //kPa
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/Initialize()
|
||||
. = ..()
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_PUMP
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_PUMP
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/on
|
||||
icon_state = "map_on"
|
||||
use_power = POWER_USE_IDLE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/update_icon()
|
||||
if(!powered())
|
||||
icon_state = "off"
|
||||
else
|
||||
icon_state = "[use_power ? "on" : "off"]"
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node1, turn(dir, -180))
|
||||
add_underlay(T, node2, dir)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/process()
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if((stat & (NOPOWER|BROKEN)) || !use_power)
|
||||
return
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
var/power_draw = -1
|
||||
var/pressure_delta = target_pressure - air2.return_pressure()
|
||||
|
||||
if(pressure_delta > 0.01 && air1.temperature > 0)
|
||||
//Figure out how much gas to transfer to meet the target pressure.
|
||||
var/transfer_moles = calculate_transfer_moles(air1, air2, pressure_delta, (network2)? network2.volume : 0)
|
||||
power_draw = pump_gas(src, air1, air2, transfer_moles, power_rating)
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
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)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AGP",
|
||||
"power" = use_power,
|
||||
"target_output" = target_pressure,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
var/data[0]
|
||||
|
||||
data = list(
|
||||
"on" = use_power,
|
||||
"pressure_set" = round(target_pressure*100), //Nano UI can't handle rounded non-integers, apparently.
|
||||
"max_pressure" = max_pressure_setting,
|
||||
"last_flow_rate" = round(last_flow_rate*10),
|
||||
"last_power_draw" = round(last_power_draw),
|
||||
"max_power_draw" = power_rating
|
||||
)
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "gas_pump.tmpl", name, 470, 290)
|
||||
ui.set_initial_data(data) // when the ui is first opened this is the data it will use
|
||||
ui.open() // open the new ui window
|
||||
ui.set_auto_update(1) // auto update every Master Controller tick
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if(signal.data["power"])
|
||||
if(text2num(signal.data["power"]))
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
else
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
if("power_toggle" in signal.data)
|
||||
update_use_power(!use_power)
|
||||
|
||||
if(signal.data["set_output_pressure"])
|
||||
target_pressure = between(
|
||||
0,
|
||||
text2num(signal.data["set_output_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["status"])
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
|
||||
/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)
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/Topic(href,href_list)
|
||||
if(..()) return 1
|
||||
|
||||
if(href_list["power"])
|
||||
update_use_power(!use_power)
|
||||
|
||||
switch(href_list["set_press"])
|
||||
if ("min")
|
||||
target_pressure = 0
|
||||
if ("max")
|
||||
target_pressure = max_pressure_setting
|
||||
if ("set")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-[max_pressure_setting]kPa)","Pressure control",src.target_pressure) as num
|
||||
src.target_pressure = between(0, new_pressure, max_pressure_setting)
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
src.update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench() && !istype(W, /obj/item/pipewrench))
|
||||
return ..()
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench this [src], turn it off first.</span>")
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE && !istype(W, /obj/item/pipewrench))
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench this [src], it's too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You struggle to unwrench \the [src] with your pipe wrench.</span>")
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, istype(W, /obj/item/pipewrench) ? 80/W.toolspeed : 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
@@ -0,0 +1,19 @@
|
||||
/obj/machinery/atmospherics/binary/pump/high_power
|
||||
icon = 'icons/atmos/volume_pump.dmi'
|
||||
icon_state = "map_off"
|
||||
level = 1
|
||||
|
||||
name = "high power gas pump"
|
||||
desc = "A pump. Has double the power rating of the standard gas pump."
|
||||
|
||||
power_rating = 15000 //15000 W ~ 20 HP
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/high_power/on
|
||||
use_power = POWER_USE_IDLE
|
||||
icon_state = "map_on"
|
||||
|
||||
/obj/machinery/atmospherics/binary/pump/high_power/update_icon()
|
||||
if(!powered())
|
||||
icon_state = "off"
|
||||
else
|
||||
icon_state = "[use_power ? "on" : "off"]"
|
||||
@@ -0,0 +1,111 @@
|
||||
//--------------------------------------------
|
||||
// Omni device port types
|
||||
//--------------------------------------------
|
||||
#define ATM_NONE 0
|
||||
#define ATM_INPUT 1
|
||||
#define ATM_OUTPUT 2
|
||||
|
||||
#define ATM_O2 3
|
||||
#define ATM_N2 4
|
||||
#define ATM_CO2 5
|
||||
#define ATM_P 6 //Phoron
|
||||
#define ATM_N2O 7
|
||||
#define ATM_H2 8 //Hydrogen
|
||||
|
||||
//--------------------------------------------
|
||||
// Omni port datum
|
||||
//
|
||||
// Used by omni devices to manage connections
|
||||
// to other atmospheric objects.
|
||||
//--------------------------------------------
|
||||
/datum/omni_port
|
||||
var/obj/machinery/atmospherics/omni/master
|
||||
var/dir
|
||||
var/update = 1
|
||||
var/mode = 0
|
||||
var/concentration = 0
|
||||
var/con_lock = 0
|
||||
var/transfer_moles = 0
|
||||
var/datum/gas_mixture/air
|
||||
var/obj/machinery/atmospherics/node
|
||||
var/datum/pipe_network/network
|
||||
|
||||
/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH)
|
||||
..()
|
||||
dir = direction
|
||||
if(istype(M))
|
||||
master = M
|
||||
air = new
|
||||
air.volume = 200
|
||||
|
||||
/datum/omni_port/proc/connect()
|
||||
if(node)
|
||||
return
|
||||
master.atmos_init()
|
||||
master.build_network()
|
||||
if(node)
|
||||
node.atmos_init()
|
||||
node.build_network()
|
||||
|
||||
/datum/omni_port/proc/disconnect()
|
||||
if(node)
|
||||
node.disconnect(master)
|
||||
master.disconnect(node)
|
||||
|
||||
|
||||
//--------------------------------------------
|
||||
// Need to find somewhere else for these
|
||||
//--------------------------------------------
|
||||
|
||||
//returns a text string based on the direction flag input
|
||||
// if capitalize is true, it will return the string capitalized
|
||||
// otherwise it will return the direction string in lower case
|
||||
/proc/dir_name(var/dir, var/capitalize = 0)
|
||||
var/string = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
string = "North"
|
||||
if(SOUTH)
|
||||
string = "South"
|
||||
if(EAST)
|
||||
string = "East"
|
||||
if(WEST)
|
||||
string = "West"
|
||||
|
||||
if(!capitalize && string)
|
||||
string = lowertext(string)
|
||||
|
||||
return string
|
||||
|
||||
//returns a direction flag based on the string passed to it
|
||||
// case insensitive
|
||||
/proc/dir_flag(var/dir)
|
||||
dir = lowertext(dir)
|
||||
switch(dir)
|
||||
if("north")
|
||||
return NORTH
|
||||
if("south")
|
||||
return SOUTH
|
||||
if("east")
|
||||
return EAST
|
||||
if("west")
|
||||
return WEST
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/proc/mode_to_gasid(var/mode)
|
||||
switch(mode)
|
||||
if(ATM_O2)
|
||||
return GAS_OXYGEN
|
||||
if(ATM_N2)
|
||||
return GAS_NITROGEN
|
||||
if(ATM_CO2)
|
||||
return GAS_CO2
|
||||
if(ATM_P)
|
||||
return GAS_PHORON
|
||||
if(ATM_N2O)
|
||||
return GAS_N2O
|
||||
if(ATM_H2)
|
||||
return GAS_HYDROGEN
|
||||
else
|
||||
return null
|
||||
@@ -0,0 +1,270 @@
|
||||
//--------------------------------------------
|
||||
// Gas filter - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
name = "omni gas filter"
|
||||
icon_state = "map_filter"
|
||||
base_icon = "filter"
|
||||
desc_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
|
||||
output. The filtered output's arrows glow orange."
|
||||
|
||||
var/list/active_filters = new()
|
||||
var/datum/omni_port/input
|
||||
var/datum/omni_port/output
|
||||
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //7500 W ~ 10 HP
|
||||
|
||||
var/max_flow_rate = 200
|
||||
var/set_flow_rate = 200
|
||||
|
||||
var/list/filtering_outputs = list() //maps gasids to gas_mixtures
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Initialize()
|
||||
. = ..()
|
||||
rebuild_filtering_list()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.air.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Destroy()
|
||||
input = null
|
||||
output = null
|
||||
active_filters.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(input == P)
|
||||
input = null
|
||||
if(active_filters.Find(P))
|
||||
active_filters -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
if(ATM_O2 to ATM_H2)
|
||||
active_filters += P
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/error_check()
|
||||
if(!input || !output || !active_filters)
|
||||
return 1
|
||||
if(active_filters.len < 1) //requires at least 1 filter ~otherwise why are you using a filter?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/process()
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference
|
||||
var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug*
|
||||
|
||||
//Figure out the amount of moles to transfer
|
||||
var/transfer_moles = (set_flow_rate/input_air.volume)*input_air.total_moles
|
||||
|
||||
var/power_draw = -1
|
||||
if (transfer_moles > MINIMUM_MOLES_TO_FILTER)
|
||||
power_draw = filter_gas_multi(src, filtering_outputs, input_air, output_air, transfer_moles, power_rating)
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
if(input.network)
|
||||
input.network.update = 1
|
||||
if(output.network)
|
||||
output.network.update = 1
|
||||
for(var/datum/omni_port/P in active_filters)
|
||||
if(P.network)
|
||||
P.network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
|
||||
var/list/data = new()
|
||||
|
||||
data = build_uidata()
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330)
|
||||
ui.set_initial_data(data)
|
||||
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/build_uidata()
|
||||
var/list/data = new()
|
||||
|
||||
data["power"] = use_power
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
var/filter = 1
|
||||
var/f_type = null
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
filter = 0
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
filter = 0
|
||||
if(ATM_O2 to ATM_H2)
|
||||
f_type = mode_send_switch(P.mode)
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"filter" = filter, \
|
||||
"f_type" = f_type)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["set_flow_rate"] = round(set_flow_rate*10) //because nanoui can't handle rounded decimals.
|
||||
data["last_flow_rate"] = round(last_flow_rate*10)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE)
|
||||
switch(mode)
|
||||
if(ATM_O2)
|
||||
return "Oxygen"
|
||||
if(ATM_N2)
|
||||
return "Nitrogen"
|
||||
if(ATM_CO2)
|
||||
return "Carbon Dioxide"
|
||||
if(ATM_P)
|
||||
return "Phoron" //*cough* Plasma *cough*
|
||||
if(ATM_N2O)
|
||||
return "Nitrous Oxide"
|
||||
if(ATM_H2)
|
||||
return "Hydrogen"
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Topic(href, href_list)
|
||||
if(..()) return 1
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
update_use_power(!use_power)
|
||||
else
|
||||
update_use_power(POWER_USE_OFF)
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !use_power)
|
||||
switch(href_list["command"])
|
||||
if("set_flow_rate")
|
||||
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
|
||||
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
|
||||
if("switch_filter")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide", "Hydrogen")
|
||||
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode)
|
||||
switch(mode)
|
||||
if("Oxygen")
|
||||
return ATM_O2
|
||||
if("Nitrogen")
|
||||
return ATM_N2
|
||||
if("Carbon Dioxide")
|
||||
return ATM_CO2
|
||||
if("Phoron")
|
||||
return ATM_P
|
||||
if("Nitrous Oxide")
|
||||
return ATM_N2O
|
||||
if("Hydrogen")
|
||||
return ATM_H2
|
||||
if("in")
|
||||
return ATM_INPUT
|
||||
if("out")
|
||||
return ATM_OUTPUT
|
||||
if("None")
|
||||
return ATM_NONE
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode)
|
||||
//check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == dir)
|
||||
if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT)
|
||||
return
|
||||
|
||||
switch_mode(dir, mode)
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode)
|
||||
if(mode == null || !port)
|
||||
return
|
||||
var/datum/omni_port/target_port = null
|
||||
var/list/other_ports = new()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == port)
|
||||
target_port = P
|
||||
else
|
||||
other_ports += P
|
||||
|
||||
var/previous_mode = null
|
||||
if(target_port)
|
||||
previous_mode = target_port.mode
|
||||
target_port.mode = mode
|
||||
if(target_port.mode != previous_mode)
|
||||
handle_port_change(target_port)
|
||||
rebuild_filtering_list()
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in other_ports)
|
||||
if(P.mode == mode)
|
||||
var/old_mode = P.mode
|
||||
P.mode = previous_mode
|
||||
if(P.mode != old_mode)
|
||||
handle_port_change(P)
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/rebuild_filtering_list()
|
||||
filtering_outputs.Cut()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/gasid = mode_to_gasid(P.mode)
|
||||
if(gasid)
|
||||
filtering_outputs[gasid] = P.air
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
@@ -0,0 +1,298 @@
|
||||
//--------------------------------------------
|
||||
// Gas mixer - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
name = "omni gas mixer"
|
||||
icon_state = "map_mixer"
|
||||
base_icon = "mixer"
|
||||
desc_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined."
|
||||
|
||||
use_power = POWER_USE_IDLE
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 3700 //3700 W ~ 5 HP
|
||||
|
||||
var/list/inputs = new()
|
||||
var/datum/omni_port/output
|
||||
|
||||
//setup tags for initial concentration values (must be decimal)
|
||||
var/tag_north_con
|
||||
var/tag_south_con
|
||||
var/tag_east_con
|
||||
var/tag_west_con
|
||||
|
||||
var/max_flow_rate = 200
|
||||
var/set_flow_rate = 200
|
||||
|
||||
var/list/mixing_inputs = list()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Initialize()
|
||||
. = ..()
|
||||
if(mapper_set())
|
||||
var/con = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
if(tag_north_con && tag_north == 1)
|
||||
P.concentration = tag_north_con
|
||||
con += max(0, tag_north_con)
|
||||
if(SOUTH)
|
||||
if(tag_south_con && tag_south == 1)
|
||||
P.concentration = tag_south_con
|
||||
con += max(0, tag_south_con)
|
||||
if(EAST)
|
||||
if(tag_east_con && tag_east == 1)
|
||||
P.concentration = tag_east_con
|
||||
con += max(0, tag_east_con)
|
||||
if(WEST)
|
||||
if(tag_west_con && tag_west == 1)
|
||||
P.concentration = tag_west_con
|
||||
con += max(0, tag_west_con)
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.air.volume = ATMOS_DEFAULT_VOLUME_MIXER
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Destroy()
|
||||
inputs.Cut()
|
||||
output = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(inputs.Find(P))
|
||||
inputs -= P
|
||||
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
inputs += P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
|
||||
if(!mapper_set())
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.concentration = 1 / max(1, inputs.len)
|
||||
|
||||
if(output)
|
||||
output.air.volume = ATMOS_DEFAULT_VOLUME_MIXER * 0.75 * inputs.len
|
||||
output.concentration = 1
|
||||
|
||||
rebuild_mixing_inputs()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/mapper_set()
|
||||
return (tag_north_con || tag_south_con || tag_east_con || tag_west_con)
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/error_check()
|
||||
if(!output || !inputs)
|
||||
return 1
|
||||
if(inputs.len < 2) //requires at least 2 inputs ~otherwise why are you using a mixer?
|
||||
return 1
|
||||
|
||||
//concentration must add to 1
|
||||
var/total = 0
|
||||
for (var/datum/omni_port/P in inputs)
|
||||
total += P.concentration
|
||||
|
||||
if (total != 1)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/process()
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
//Figure out the amount of moles to transfer
|
||||
var/transfer_moles = 0
|
||||
for (var/datum/omni_port/P in inputs)
|
||||
transfer_moles += (set_flow_rate*P.concentration/P.air.volume)*P.air.total_moles
|
||||
|
||||
var/power_draw = -1
|
||||
if (transfer_moles > MINIMUM_MOLES_TO_FILTER)
|
||||
power_draw = mix_gas(src, mixing_inputs, output.air, transfer_moles, power_rating)
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.concentration && P.network)
|
||||
P.network.update = 1
|
||||
|
||||
if(output.network)
|
||||
output.network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
usr.set_machine(src)
|
||||
|
||||
var/list/data = new()
|
||||
|
||||
data = build_uidata()
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330)
|
||||
ui.set_initial_data(data)
|
||||
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/build_uidata()
|
||||
var/list/data = new()
|
||||
|
||||
data["power"] = use_power
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"concentration" = P.concentration, \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"con_lock" = P.con_lock)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["set_flow_rate"] = round(set_flow_rate*10) //because nanoui can't handle rounded decimals.
|
||||
data["last_flow_rate"] = round(last_flow_rate*10)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
|
||||
if(..()) return 1
|
||||
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
update_use_power(!use_power)
|
||||
else
|
||||
update_use_power(POWER_USE_OFF)
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !use_power)
|
||||
switch(href_list["command"])
|
||||
if("set_flow_rate")
|
||||
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",set_flow_rate) as num
|
||||
set_flow_rate = between(0, new_flow_rate, max_flow_rate)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
|
||||
if("switch_con")
|
||||
change_concentration(dir_flag(href_list["dir"]))
|
||||
if("switch_conlock")
|
||||
con_lock(dir_flag(href_list["dir"]))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
|
||||
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
|
||||
switch(mode)
|
||||
if("in")
|
||||
mode = ATM_INPUT
|
||||
if("out")
|
||||
mode = ATM_OUTPUT
|
||||
else
|
||||
mode = ATM_NONE
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/old_mode = P.mode
|
||||
if(P.dir == port)
|
||||
switch(mode)
|
||||
if(ATM_INPUT)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
P.mode = mode
|
||||
if(ATM_OUTPUT)
|
||||
P.mode = mode
|
||||
if(ATM_NONE)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
if(P.mode == ATM_INPUT && inputs.len > 2)
|
||||
P.mode = mode
|
||||
else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT)
|
||||
P.mode = ATM_INPUT
|
||||
if(P.mode != old_mode)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
rebuild_mixing_inputs()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
var/old_con = 0
|
||||
var/non_locked = 0
|
||||
var/remain_con = 1
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
old_con = P.concentration
|
||||
else if(!P.con_lock)
|
||||
non_locked++
|
||||
else
|
||||
remain_con -= P.concentration
|
||||
|
||||
//return if no adjustable ports
|
||||
if(non_locked < 1)
|
||||
return
|
||||
|
||||
var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100
|
||||
|
||||
//cap it between 0 and the max remaining concentration
|
||||
new_con = between(0, new_con, remain_con)
|
||||
|
||||
//new_con = min(remain_con, new_con)
|
||||
|
||||
//clamp remaining concentration so we don't go into negatives
|
||||
remain_con = max(0, remain_con - new_con)
|
||||
|
||||
//distribute remaining concentration between unlocked ports evenly
|
||||
remain_con /= max(1, non_locked)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.concentration = new_con
|
||||
else if(!P.con_lock)
|
||||
P.concentration = remain_con
|
||||
|
||||
rebuild_mixing_inputs()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/rebuild_mixing_inputs()
|
||||
mixing_inputs.Cut()
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
mixing_inputs[P.air] = P.concentration
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH)
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.con_lock = !P.con_lock
|
||||
@@ -0,0 +1,286 @@
|
||||
//--------------------------------------------
|
||||
// Base omni device
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni
|
||||
name = "omni device"
|
||||
icon = 'icons/atmos/omni_devices.dmi'
|
||||
icon_state = "base"
|
||||
initialize_directions = 0
|
||||
level = 1
|
||||
|
||||
var/configuring = 0
|
||||
//var/target_pressure = ONE_ATMOSPHERE //a base type as abstract as this should NOT be making these kinds of assumptions
|
||||
|
||||
var/base_icon
|
||||
|
||||
var/tag_north = ATM_NONE
|
||||
var/tag_south = ATM_NONE
|
||||
var/tag_east = ATM_NONE
|
||||
var/tag_west = ATM_NONE
|
||||
|
||||
var/list/on_states = list()
|
||||
var/list/off_states = list()
|
||||
|
||||
var/underlays_current[4]
|
||||
|
||||
var/list/ports = new()
|
||||
|
||||
/obj/machinery/atmospherics/omni/Initialize()
|
||||
icon_state = "base"
|
||||
ports = new()
|
||||
for(var/d in cardinal)
|
||||
var/datum/omni_port/new_port = new(src, d)
|
||||
switch(d)
|
||||
if(NORTH)
|
||||
new_port.mode = tag_north
|
||||
if(SOUTH)
|
||||
new_port.mode = tag_south
|
||||
if(EAST)
|
||||
new_port.mode = tag_east
|
||||
if(WEST)
|
||||
new_port.mode = tag_west
|
||||
if(new_port.mode > 0)
|
||||
initialize_directions |= d
|
||||
ports += new_port
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_icon()
|
||||
cut_overlays()
|
||||
var/list/to_add = list(base_icon)
|
||||
if(stat & NOPOWER)
|
||||
to_add += off_states
|
||||
else if(error_check())
|
||||
to_add += "error"
|
||||
else if (use_power)
|
||||
to_add[1] = "[base_icon]_glow"
|
||||
to_add += on_states
|
||||
else
|
||||
to_add += off_states
|
||||
|
||||
add_overlay(to_add)
|
||||
|
||||
underlays = underlays_current
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/error_check()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/process()
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if(error_check())
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
if((stat & (NOPOWER|BROKEN)) || !use_power)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if(!W.iswrench())
|
||||
return ..()
|
||||
|
||||
var/int_pressure = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
int_pressure += P.air.return_pressure()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
if(do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_hand(user as mob)
|
||||
if(..())
|
||||
return
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_port_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
on_states.Cut()
|
||||
off_states.Cut()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/ref_layer = 0
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
ref_layer = 1
|
||||
if(SOUTH)
|
||||
ref_layer = 2
|
||||
if(EAST)
|
||||
ref_layer = 3
|
||||
if(WEST)
|
||||
ref_layer = 4
|
||||
|
||||
if(!ref_layer)
|
||||
continue
|
||||
|
||||
var/list/underlay_icon = select_port_icons(P)
|
||||
if(underlay_icon)
|
||||
if(P.node)
|
||||
underlays_current[ref_layer] = underlay_icon
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
|
||||
update_icon()
|
||||
|
||||
// Assumes on_states and off_states have been cut if required.
|
||||
/obj/machinery/atmospherics/omni/proc/select_port_icons(datum/omni_port/P)
|
||||
if(!istype(P))
|
||||
return
|
||||
|
||||
if(P.mode > 0)
|
||||
var/ic_dir = dir_name(P.dir)
|
||||
var/ic_on = ic_dir
|
||||
var/ic_off = ic_dir
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
ic_on += "_in_glow"
|
||||
ic_off += "_in"
|
||||
if(ATM_OUTPUT)
|
||||
ic_on += "_out_glow"
|
||||
ic_off += "_out"
|
||||
if(ATM_O2 to ATM_H2)
|
||||
ic_on += "_filter"
|
||||
ic_off += "_out"
|
||||
|
||||
on_states += ic_on
|
||||
off_states += ic_off
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!T.is_plating() && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
. = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
|
||||
else
|
||||
. = icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_underlays()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_ports()
|
||||
sort_ports()
|
||||
update_port_icons()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/sort_ports()
|
||||
return
|
||||
|
||||
|
||||
// Housekeeping and pipe network stuff below
|
||||
|
||||
/obj/machinery/atmospherics/omni/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
P.network = new_network
|
||||
break
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/Destroy()
|
||||
loc = null
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node)
|
||||
P.node.disconnect(src)
|
||||
qdel(P.network)
|
||||
P.node = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/atmos_init()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node || P.mode == 0)
|
||||
continue
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, P.dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
P.node = target
|
||||
break
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/build_network()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!P.network && P.node)
|
||||
P.network = new /datum/pipe_network()
|
||||
P.network.normal_members += src
|
||||
P.network.build_network(P.node, src)
|
||||
|
||||
/obj/machinery/atmospherics/omni/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
return P.network
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.network == old_network)
|
||||
P.network = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.network == reference)
|
||||
results += P.air
|
||||
|
||||
return results
|
||||
|
||||
/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
qdel(P.network)
|
||||
P.node = null
|
||||
P.update = 1
|
||||
break
|
||||
|
||||
update_ports()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/AltClick(var/mob/user)
|
||||
if(!allowed(user))
|
||||
to_chat(user, SPAN_WARNING("Access denied."))
|
||||
return
|
||||
Topic(src, list("power" = "1"))
|
||||
@@ -0,0 +1,156 @@
|
||||
/obj/machinery/atmospherics/portables_connector
|
||||
icon = 'icons/atmos/connector.dmi'
|
||||
icon_state = "map_connector"
|
||||
|
||||
name = "Connector Port"
|
||||
desc = "For connecting portables devices related to atmospherics control."
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
|
||||
var/obj/machinery/portable_atmospherics/connected_device
|
||||
|
||||
var/obj/machinery/atmospherics/node
|
||||
|
||||
var/datum/pipe_network/network
|
||||
|
||||
var/on = 0
|
||||
use_power = POWER_USE_OFF
|
||||
level = 1
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/Initialize()
|
||||
initialize_directions = dir
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/update_icon()
|
||||
icon_state = "connector"
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node, dir)
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/process()
|
||||
..()
|
||||
if(!on)
|
||||
return
|
||||
if(!connected_device)
|
||||
on = 0
|
||||
return
|
||||
if(network)
|
||||
network.update = 1
|
||||
return 1
|
||||
|
||||
// Housekeeping and pipe network stuff below
|
||||
/obj/machinery/atmospherics/portables_connector/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/portables_connector/Destroy()
|
||||
loc = null
|
||||
|
||||
if(connected_device)
|
||||
connected_device.disconnect()
|
||||
|
||||
if(node)
|
||||
node.disconnect(src)
|
||||
qdel(network)
|
||||
|
||||
node = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/atmos_init()
|
||||
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 (check_connect_types(target,src))
|
||||
node = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/build_network()
|
||||
if(!network && node)
|
||||
network = new /datum/pipe_network()
|
||||
network.normal_members += src
|
||||
network.build_network(node, src)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node)
|
||||
return network
|
||||
|
||||
if(reference==connected_device)
|
||||
return network
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network == old_network)
|
||||
network = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(connected_device)
|
||||
results += connected_device.air_contents
|
||||
|
||||
return results
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node)
|
||||
qdel(network)
|
||||
node = null
|
||||
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/portables_connector/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
if (connected_device)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], dettach \the [connected_device] first.</span>")
|
||||
return TRUE
|
||||
if (locate(/obj/machinery/portable_atmospherics, src.loc))
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
@@ -0,0 +1,286 @@
|
||||
/obj/machinery/atmospherics/trinary/filter
|
||||
icon = 'icons/atmos/filter.dmi'
|
||||
icon_state = "map"
|
||||
density = 0
|
||||
level = 1
|
||||
|
||||
name = "Gas filter"
|
||||
|
||||
use_power = POWER_USE_IDLE
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //This also doubles as a measure of how powerful the filter is, in Watts. 7500 W ~ 10 HP
|
||||
|
||||
var/temp = null // -- TLE
|
||||
|
||||
var/set_flow_rate = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
|
||||
/*
|
||||
Filter types:
|
||||
-1: Nothing
|
||||
0: Phoron: Phoron, Oxygen Agent B
|
||||
1: Oxygen: Oxygen ONLY
|
||||
2: Nitrogen: Nitrogen ONLY
|
||||
3: Carbon Dioxide: Carbon Dioxide ONLY
|
||||
4: Sleeping Agent (N2O)
|
||||
5: Hydrogen (H2)
|
||||
*/
|
||||
var/filter_type = -1
|
||||
var/list/filtered_out = list()
|
||||
|
||||
|
||||
var/frequency = 0
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/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/trinary/filter/Initialize()
|
||||
. = ..()
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
filtered_out = list(GAS_PHORON)
|
||||
if(1) //removing O2
|
||||
filtered_out = list(GAS_OXYGEN)
|
||||
if(2) //removing N2
|
||||
filtered_out = list(GAS_NITROGEN)
|
||||
if(3) //removing CO2
|
||||
filtered_out = list(GAS_CO2)
|
||||
if(4)//removing N2O
|
||||
filtered_out = list(GAS_N2O)
|
||||
if(5)//removing H2
|
||||
filtered_out = list(GAS_HYDROGEN)
|
||||
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
air3.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/update_icon()
|
||||
if(istype(src, /obj/machinery/atmospherics/trinary/filter/m_filter))
|
||||
icon_state = "m"
|
||||
else
|
||||
icon_state = ""
|
||||
|
||||
if(!powered())
|
||||
icon_state += "off"
|
||||
else if(node2 && node3 && node1)
|
||||
icon_state += use_power ? "on" : "off"
|
||||
else
|
||||
icon_state += "off"
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
add_underlay(T, node1, turn(dir, -180))
|
||||
|
||||
if(istype(src, /obj/machinery/atmospherics/trinary/filter/m_filter))
|
||||
add_underlay(T, node2, turn(dir, 90))
|
||||
else
|
||||
add_underlay(T, node2, turn(dir, -90))
|
||||
|
||||
add_underlay(T, node3, dir)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/process()
|
||||
..()
|
||||
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if((stat & (NOPOWER|BROKEN)) || !use_power)
|
||||
return
|
||||
|
||||
//Figure out the amount of moles to transfer
|
||||
var/transfer_moles = (set_flow_rate/air1.volume)*air1.total_moles
|
||||
|
||||
var/power_draw = -1
|
||||
if (transfer_moles > MINIMUM_MOLES_TO_FILTER)
|
||||
power_draw = filter_gas(src, filtered_out, air1, air2, air3, transfer_moles, power_rating)
|
||||
|
||||
if(network2)
|
||||
network2.update = 1
|
||||
|
||||
if(network3)
|
||||
network3.update = 1
|
||||
|
||||
if(network1)
|
||||
network1.update = 1
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/atmos_init()
|
||||
set_frequency(frequency)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attack_hand(user as mob) // -- TLE
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
|
||||
var/dat
|
||||
var/current_filter_type
|
||||
switch(filter_type)
|
||||
if(0)
|
||||
current_filter_type = "Phoron"
|
||||
if(1)
|
||||
current_filter_type = "Oxygen"
|
||||
if(2)
|
||||
current_filter_type = "Nitrogen"
|
||||
if(3)
|
||||
current_filter_type = "Carbon Dioxide"
|
||||
if(4)
|
||||
current_filter_type = "Nitrous Oxide"
|
||||
if(5)
|
||||
current_filter_type = "Hydrogen"
|
||||
if(-1)
|
||||
current_filter_type = "Nothing"
|
||||
else
|
||||
current_filter_type = "ERROR - Report this bug to the admin, please!"
|
||||
|
||||
dat += {"
|
||||
<b>Power: </b><a href='?src=\ref[src];power=1'>[use_power?"On":"Off"]</a><br>
|
||||
<b>Filtering: </b>[current_filter_type]<br><HR>
|
||||
<h4>Set Filter Type:</h4>
|
||||
<A href='?src=\ref[src];filterset=0'>Phoron</A><BR>
|
||||
<A href='?src=\ref[src];filterset=1'>Oxygen</A><BR>
|
||||
<A href='?src=\ref[src];filterset=2'>Nitrogen</A><BR>
|
||||
<A href='?src=\ref[src];filterset=3'>Carbon Dioxide</A><BR>
|
||||
<A href='?src=\ref[src];filterset=4'>Nitrous Oxide</A><BR>
|
||||
<A href='?src=\ref[src];filterset=5'>Hydrogen</A><BR>
|
||||
<A href='?src=\ref[src];filterset=-1'>Nothing</A><BR>
|
||||
<HR>
|
||||
<B>Set Flow Rate Limit:</B>
|
||||
[src.set_flow_rate]L/s | <a href='?src=\ref[src];set_flow_rate=1'>Change</a><BR>
|
||||
<B>Flow rate: </B>[round(last_flow_rate, 0.1)]L/s
|
||||
"}
|
||||
|
||||
user << browse("<HEAD><TITLE>[src.name] control</TITLE></HEAD><TT>[dat]</TT>", "window=atmo_filter")
|
||||
onclose(user, "atmo_filter")
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
|
||||
if(..())
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["filterset"])
|
||||
filter_type = text2num(href_list["filterset"])
|
||||
|
||||
filtered_out.Cut() //no need to create new lists unnecessarily
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
filtered_out += GAS_PHORON
|
||||
if(1) //removing O2
|
||||
filtered_out += GAS_OXYGEN
|
||||
if(2) //removing N2
|
||||
filtered_out += GAS_NITROGEN
|
||||
if(3) //removing CO2
|
||||
filtered_out += GAS_CO2
|
||||
if(4)//removing N2O
|
||||
filtered_out += GAS_N2O
|
||||
if(5)//removing H2
|
||||
filtered_out += GAS_HYDROGEN
|
||||
|
||||
if (href_list["temp"])
|
||||
src.temp = null
|
||||
if(href_list["set_flow_rate"])
|
||||
var/new_flow_rate = input(usr,"Enter new flow rate (0-[air1.volume]L/s)","Flow Rate Control",src.set_flow_rate) as num
|
||||
src.set_flow_rate = max(0, min(air1.volume, new_flow_rate))
|
||||
if(href_list["power"])
|
||||
update_use_power(!use_power)
|
||||
src.update_icon()
|
||||
src.updateUsrDialog()
|
||||
/*
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.attack_hand(M)
|
||||
*/
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/m_filter
|
||||
icon_state = "mmap"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH|EAST
|
||||
|
||||
obj/machinery/atmospherics/trinary/filter/m_filter/Initialize()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = WEST|NORTH|SOUTH
|
||||
if(SOUTH)
|
||||
initialize_directions = SOUTH|EAST|NORTH
|
||||
if(EAST)
|
||||
initialize_directions = EAST|WEST|NORTH
|
||||
if(WEST)
|
||||
initialize_directions = WEST|SOUTH|EAST
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/m_filter/atmos_init()
|
||||
set_frequency(frequency)
|
||||
|
||||
if(node1 && node2 && node3) return
|
||||
|
||||
var/node1_connect = turn(dir, -180)
|
||||
var/node2_connect = turn(dir, 90)
|
||||
var/node3_connect = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
@@ -0,0 +1,277 @@
|
||||
/obj/machinery/atmospherics/trinary/mixer
|
||||
icon = 'icons/atmos/mixer.dmi'
|
||||
icon_state = "map"
|
||||
density = 0
|
||||
level = 1
|
||||
|
||||
name = "Gas mixer"
|
||||
|
||||
use_power = POWER_USE_IDLE
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 3700 //This also doubles as a measure of how powerful the mixer is, in Watts. 3700 W ~ 5 HP
|
||||
|
||||
var/set_flow_rate = ATMOS_DEFAULT_VOLUME_MIXER
|
||||
var/list/mixing_inputs
|
||||
|
||||
//for mapping
|
||||
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(var/safety = 0)
|
||||
if(istype(src, /obj/machinery/atmospherics/trinary/mixer/m_mixer))
|
||||
icon_state = "m"
|
||||
else if(istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer))
|
||||
icon_state = "t"
|
||||
else
|
||||
icon_state = ""
|
||||
|
||||
if(!powered())
|
||||
icon_state += "off"
|
||||
else if(node2 && node3 && node1)
|
||||
icon_state += use_power ? "on" : "off"
|
||||
else
|
||||
icon_state += "off"
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer))
|
||||
add_underlay(T, node1, turn(dir, -90))
|
||||
else
|
||||
add_underlay(T, node1, turn(dir, -180))
|
||||
|
||||
if(istype(src, /obj/machinery/atmospherics/trinary/mixer/m_mixer) || istype(src, /obj/machinery/atmospherics/trinary/mixer/t_mixer))
|
||||
add_underlay(T, node2, turn(dir, 90))
|
||||
else
|
||||
add_underlay(T, node2, turn(dir, -90))
|
||||
|
||||
add_underlay(T, node3, dir)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/Initialize()
|
||||
. = ..()
|
||||
air1.volume = ATMOS_DEFAULT_VOLUME_MIXER
|
||||
air2.volume = ATMOS_DEFAULT_VOLUME_MIXER
|
||||
air3.volume = ATMOS_DEFAULT_VOLUME_MIXER * 1.5
|
||||
|
||||
if (!mixing_inputs)
|
||||
mixing_inputs = list(src.air1 = node1_concentration, src.air2 = node2_concentration)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/process()
|
||||
..()
|
||||
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if((stat & (NOPOWER|BROKEN)) || !use_power)
|
||||
return
|
||||
|
||||
//Figure out the amount of moles to transfer
|
||||
var/transfer_moles = (set_flow_rate*mixing_inputs[air1]/air1.volume)*air1.total_moles + (set_flow_rate*mixing_inputs[air1]/air2.volume)*air2.total_moles
|
||||
|
||||
var/power_draw = -1
|
||||
if (transfer_moles > MINIMUM_MOLES_TO_FILTER)
|
||||
power_draw = mix_gas(src, mixing_inputs, air3, transfer_moles, power_rating)
|
||||
|
||||
if(network1 && mixing_inputs[air1])
|
||||
network1.update = 1
|
||||
|
||||
if(network2 && mixing_inputs[air2])
|
||||
network2.update = 1
|
||||
|
||||
if(network3)
|
||||
network3.update = 1
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/trinary/mixer/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/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'>[use_power?"On":"Off"]</a><br>
|
||||
<b>Set Flow Rate Limit: </b>
|
||||
[set_flow_rate]L/s | <a href='?src=\ref[src];set_press=1'>Change</a>
|
||||
<br>
|
||||
<b>Flow Rate: </b>[round(last_flow_rate, 0.1)]L/s
|
||||
<br><hr>
|
||||
<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>
|
||||
[mixing_inputs[air1]]([mixing_inputs[air1]*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>
|
||||
[mixing_inputs[air2]]([mixing_inputs[air2]*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 1
|
||||
if(href_list["power"])
|
||||
update_use_power(!use_power)
|
||||
if(href_list["set_press"])
|
||||
var/max_flow_rate = min(air1.volume, air2.volume)
|
||||
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",src.set_flow_rate) as num
|
||||
src.set_flow_rate = max(0, min(max_flow_rate, new_flow_rate))
|
||||
if(href_list["node1_c"])
|
||||
var/value = text2num(href_list["node1_c"])
|
||||
src.mixing_inputs[air1] = max(0, min(1, src.mixing_inputs[air1] + value))
|
||||
src.mixing_inputs[air2] = 1.0 - mixing_inputs[air1]
|
||||
if(href_list["node2_c"])
|
||||
var/value = text2num(href_list["node2_c"])
|
||||
src.mixing_inputs[air2] = max(0, min(1, src.mixing_inputs[air2] + value))
|
||||
src.mixing_inputs[air1] = 1.0 - mixing_inputs[air2]
|
||||
src.update_icon()
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/t_mixer
|
||||
icon_state = "tmap"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|EAST|WEST
|
||||
|
||||
//node 3 is the outlet, nodes 1 & 2 are intakes
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/t_mixer/north
|
||||
icon_state = "tmap"
|
||||
|
||||
dir = NORTH
|
||||
initialize_directions = NORTH|EAST|WEST
|
||||
|
||||
//node 3 is the outlet, nodes 1 & 2 are intakes
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/t_mixer/Initialize()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = EAST|NORTH|WEST
|
||||
if(SOUTH)
|
||||
initialize_directions = SOUTH|WEST|EAST
|
||||
if(EAST)
|
||||
initialize_directions = EAST|NORTH|SOUTH
|
||||
if(WEST)
|
||||
initialize_directions = WEST|NORTH|SOUTH
|
||||
. = ..()
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/t_mixer/atmos_init()
|
||||
..()
|
||||
if(node1 && node2 && node3) return
|
||||
|
||||
var/node1_connect = turn(dir, -90)
|
||||
var/node2_connect = turn(dir, 90)
|
||||
var/node3_connect = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/m_mixer
|
||||
icon_state = "mmap"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH|EAST
|
||||
|
||||
//node 3 is the outlet, nodes 1 & 2 are intakes
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/m_mixer/Initialize()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = WEST|NORTH|SOUTH
|
||||
if(SOUTH)
|
||||
initialize_directions = SOUTH|EAST|NORTH
|
||||
if(EAST)
|
||||
initialize_directions = EAST|WEST|NORTH
|
||||
if(WEST)
|
||||
initialize_directions = WEST|SOUTH|EAST
|
||||
. = ..()
|
||||
|
||||
obj/machinery/atmospherics/trinary/mixer/m_mixer/atmos_init()
|
||||
..()
|
||||
if(node1 && node2 && node3) return
|
||||
|
||||
var/node1_connect = turn(dir, -180)
|
||||
var/node2_connect = turn(dir, 90)
|
||||
var/node3_connect = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
@@ -0,0 +1,175 @@
|
||||
/obj/machinery/atmospherics/trinary
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH|WEST
|
||||
use_power = POWER_USE_OFF
|
||||
|
||||
var/datum/gas_mixture/air1
|
||||
var/datum/gas_mixture/air2
|
||||
var/datum/gas_mixture/air3
|
||||
|
||||
var/obj/machinery/atmospherics/node3
|
||||
|
||||
var/datum/pipe_network/network1
|
||||
var/datum/pipe_network/network2
|
||||
var/datum/pipe_network/network3
|
||||
|
||||
/obj/machinery/atmospherics/trinary/Initialize()
|
||||
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
|
||||
air1 = new
|
||||
air2 = new
|
||||
air3 = new
|
||||
|
||||
air1.volume = 200
|
||||
air2.volume = 200
|
||||
air3.volume = 200
|
||||
. = ..()
|
||||
|
||||
// Housekeeping and pipe network stuff below
|
||||
/obj/machinery/atmospherics/trinary/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network1 = new_network
|
||||
|
||||
else if(reference == node2)
|
||||
network2 = new_network
|
||||
|
||||
else if (reference == node3)
|
||||
network3 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/trinary/Destroy()
|
||||
QDEL_NULL(air1)
|
||||
QDEL_NULL(air2)
|
||||
QDEL_NULL(air3)
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
QDEL_NULL(network1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
QDEL_NULL(network2)
|
||||
if(node3)
|
||||
node3.disconnect(src)
|
||||
QDEL_NULL(network3)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
node3 = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/atmos_init()
|
||||
if(node1 && node2 && node3) return
|
||||
|
||||
var/node1_connect = turn(dir, -180)
|
||||
var/node2_connect = turn(dir, -90)
|
||||
var/node3_connect = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node2 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_connect))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/build_network()
|
||||
if(!network1 && node1)
|
||||
network1 = new /datum/pipe_network()
|
||||
network1.normal_members += src
|
||||
network1.build_network(node1, src)
|
||||
|
||||
if(!network2 && node2)
|
||||
network2 = new /datum/pipe_network()
|
||||
network2.normal_members += src
|
||||
network2.build_network(node2, src)
|
||||
|
||||
if(!network3 && node3)
|
||||
network3 = new /datum/pipe_network()
|
||||
network3.normal_members += src
|
||||
network3.build_network(node3, src)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/trinary/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network1
|
||||
|
||||
if(reference==node2)
|
||||
return network2
|
||||
|
||||
if(reference==node3)
|
||||
return network3
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/trinary/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network1 == old_network)
|
||||
network1 = new_network
|
||||
if(network2 == old_network)
|
||||
network2 = new_network
|
||||
if(network3 == old_network)
|
||||
network3 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/trinary/return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(network1 == reference)
|
||||
results += air1
|
||||
if(network2 == reference)
|
||||
results += air2
|
||||
if(network3 == reference)
|
||||
results += air3
|
||||
|
||||
return results
|
||||
|
||||
/obj/machinery/atmospherics/trinary/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network2)
|
||||
node2 = null
|
||||
|
||||
else if(reference==node3)
|
||||
qdel(network3)
|
||||
node3 = null
|
||||
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/trinary/AltClick(var/mob/user)
|
||||
if(!allowed(user))
|
||||
to_chat(user, SPAN_WARNING("Access denied."))
|
||||
return
|
||||
Topic(src, list("power" = "1"))
|
||||
@@ -0,0 +1,485 @@
|
||||
/obj/machinery/atmospherics/tvalve
|
||||
name = "manual switching valve"
|
||||
desc = "A pipe valve."
|
||||
desc_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow."
|
||||
icon = 'icons/atmos/tvalve.dmi'
|
||||
icon_state = "map_tvalve0"
|
||||
|
||||
level = 1
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH|WEST
|
||||
|
||||
var/state = 0 // 0 = go straight, 1 = go to side
|
||||
|
||||
// like a trinary component, node1 is input, node2 is side output, node3 is straight output
|
||||
var/obj/machinery/atmospherics/node3
|
||||
|
||||
var/datum/pipe_network/network_node1
|
||||
var/datum/pipe_network/network_node2
|
||||
var/datum/pipe_network/network_node3
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/bypass
|
||||
icon_state = "map_tvalve1"
|
||||
state = 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/update_icon(animation)
|
||||
if(animation)
|
||||
flick("tvalve[src.state][!src.state]",src)
|
||||
else
|
||||
icon_state = "tvalve[state]"
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node1, turn(dir, -180))
|
||||
|
||||
if(istype(src, /obj/machinery/atmospherics/tvalve/mirrored))
|
||||
add_underlay(T, node2, turn(dir, 90))
|
||||
else
|
||||
add_underlay(T, node2, turn(dir, -90))
|
||||
|
||||
add_underlay(T, node3, dir)
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/Initialize()
|
||||
initialize_directions()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/proc/initialize_directions()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = SOUTH|NORTH|EAST
|
||||
if(SOUTH)
|
||||
initialize_directions = NORTH|SOUTH|WEST
|
||||
if(EAST)
|
||||
initialize_directions = WEST|EAST|SOUTH
|
||||
if(WEST)
|
||||
initialize_directions = EAST|WEST|NORTH
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network_node1 = new_network
|
||||
if(state)
|
||||
network_node2 = new_network
|
||||
else
|
||||
network_node3 = new_network
|
||||
else if(reference == node2)
|
||||
network_node2 = new_network
|
||||
if(state)
|
||||
network_node1 = new_network
|
||||
else if(reference == node3)
|
||||
network_node3 = new_network
|
||||
if(!state)
|
||||
network_node1 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
if(state)
|
||||
if(reference == node1)
|
||||
if(node2)
|
||||
return node2.network_expand(new_network, src)
|
||||
else if(reference == node2)
|
||||
if(node1)
|
||||
return node1.network_expand(new_network, src)
|
||||
else
|
||||
if(reference == node1)
|
||||
if(node3)
|
||||
return node3.network_expand(new_network, src)
|
||||
else if(reference == node3)
|
||||
if(node1)
|
||||
return node1.network_expand(new_network, src)
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/Destroy()
|
||||
loc = null
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network_node1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network_node2)
|
||||
if(node3)
|
||||
node3.disconnect(src)
|
||||
qdel(network_node3)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
node3 = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/proc/go_to_side()
|
||||
|
||||
if(state) return 0
|
||||
|
||||
state = 1
|
||||
update_icon()
|
||||
|
||||
if(network_node1)
|
||||
qdel(network_node1)
|
||||
if(network_node3)
|
||||
qdel(network_node3)
|
||||
build_network()
|
||||
|
||||
if(network_node1&&network_node2)
|
||||
network_node1.merge(network_node2)
|
||||
network_node2 = network_node1
|
||||
|
||||
if(network_node1)
|
||||
network_node1.update = 1
|
||||
else if(network_node2)
|
||||
network_node2.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/proc/go_straight()
|
||||
|
||||
if(!state)
|
||||
return 0
|
||||
|
||||
state = 0
|
||||
update_icon()
|
||||
|
||||
if(network_node1)
|
||||
qdel(network_node1)
|
||||
if(network_node2)
|
||||
qdel(network_node2)
|
||||
build_network()
|
||||
|
||||
if(network_node1&&network_node3)
|
||||
network_node1.merge(network_node3)
|
||||
network_node3 = network_node1
|
||||
|
||||
if(network_node1)
|
||||
network_node1.update = 1
|
||||
else if(network_node3)
|
||||
network_node3.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/attack_ai(mob/user as mob)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(usr)
|
||||
update_icon(1)
|
||||
sleep(10)
|
||||
if (src.state)
|
||||
src.go_straight()
|
||||
else
|
||||
src.go_to_side()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/process()
|
||||
..()
|
||||
. = PROCESS_KILL
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/atmos_init()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
var/node3_dir
|
||||
|
||||
node1_dir = turn(dir, 180)
|
||||
node2_dir = turn(dir, -90)
|
||||
node3_dir = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node1 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node2 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/build_network()
|
||||
if(!network_node1 && node1)
|
||||
network_node1 = new /datum/pipe_network()
|
||||
network_node1.normal_members += src
|
||||
network_node1.build_network(node1, src)
|
||||
|
||||
if(!network_node2 && node2)
|
||||
network_node2 = new /datum/pipe_network()
|
||||
network_node2.normal_members += src
|
||||
network_node2.build_network(node2, src)
|
||||
|
||||
if(!network_node3 && node3)
|
||||
network_node3 = new /datum/pipe_network()
|
||||
network_node3.normal_members += src
|
||||
network_node3.build_network(node3, src)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network_node1
|
||||
|
||||
if(reference==node2)
|
||||
return network_node2
|
||||
|
||||
if(reference==node3)
|
||||
return network_node3
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network_node1 == old_network)
|
||||
network_node1 = new_network
|
||||
if(network_node2 == old_network)
|
||||
network_node2 = new_network
|
||||
if(network_node3 == old_network)
|
||||
network_node3 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/return_network_air(datum/pipe_network/reference)
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network_node1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network_node2)
|
||||
node2 = null
|
||||
|
||||
else if(reference==node3)
|
||||
qdel(network_node3)
|
||||
node2 = null
|
||||
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital // can be controlled by AI
|
||||
name = "digital switching valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon = 'icons/atmos/digital_tvalve.dmi'
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/bypass
|
||||
icon_state = "map_tvalve1"
|
||||
state = 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/update_icon()
|
||||
..()
|
||||
if(!powered())
|
||||
icon_state = "tvalvenopower"
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/attack_ai(mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/attack_hand(mob/user as mob)
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
//Radio remote control
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/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/tvalve/digital/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/digital/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id))
|
||||
return 0
|
||||
|
||||
switch(signal.data["command"])
|
||||
if("valve_open")
|
||||
if(!state)
|
||||
go_to_side()
|
||||
|
||||
if("valve_close")
|
||||
if(state)
|
||||
go_straight()
|
||||
|
||||
if("valve_toggle")
|
||||
if(state)
|
||||
go_straight()
|
||||
else
|
||||
go_to_side()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
if (istype(src, /obj/machinery/atmospherics/tvalve/digital))
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it's too complicated.</span>")
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warnng'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored
|
||||
icon_state = "map_tvalvem0"
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/bypass
|
||||
icon_state = "map_tvalvem1"
|
||||
state = 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/initialize_directions()
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
initialize_directions = SOUTH|NORTH|WEST
|
||||
if(SOUTH)
|
||||
initialize_directions = NORTH|SOUTH|EAST
|
||||
if(EAST)
|
||||
initialize_directions = WEST|EAST|NORTH
|
||||
if(WEST)
|
||||
initialize_directions = EAST|WEST|SOUTH
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/atmos_init()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
var/node3_dir
|
||||
|
||||
node1_dir = turn(dir, 180)
|
||||
node2_dir = turn(dir, 90)
|
||||
node3_dir = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/update_icon(animation)
|
||||
if(animation)
|
||||
flick("tvalvem[src.state][!src.state]",src)
|
||||
else
|
||||
icon_state = "tvalvem[state]"
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital // can be controlled by AI
|
||||
name = "digital switching valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon = 'icons/atmos/digital_tvalve.dmi'
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/bypass
|
||||
icon_state = "map_tvalvem1"
|
||||
state = 1
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/update_icon()
|
||||
..()
|
||||
if(!powered())
|
||||
icon_state = "tvalvemnopower"
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/attack_ai(mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/attack_hand(mob/user as mob)
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
//Radio remote control -eh?
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/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/tvalve/mirrored/digital/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/tvalve/mirrored/digital/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id))
|
||||
return 0
|
||||
|
||||
switch(signal.data["command"])
|
||||
if("valve_open")
|
||||
if(!state)
|
||||
go_to_side()
|
||||
|
||||
if("valve_close")
|
||||
if(state)
|
||||
go_straight()
|
||||
|
||||
if("valve_toggle")
|
||||
if(state)
|
||||
go_straight()
|
||||
else
|
||||
go_to_side()
|
||||
@@ -0,0 +1,186 @@
|
||||
//TODO: Put this under a common parent type with heaters to cut down on the copypasta
|
||||
#define FREEZER_PERF_MULT 2.5
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer
|
||||
name = "gas cooling system"
|
||||
desc = "Cools gas when connected to pipe network."
|
||||
desc_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
icon = 'icons/obj/sleeper.dmi'
|
||||
icon_state = "freezer_0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 5 // 5 Watts for thermostat related circuitry
|
||||
|
||||
var/heatsink_temperature = T20C // The constant temperature reservoir into which the freezer pumps heat. Probably the hull of the station or something.
|
||||
var/internal_volume = 600 // L
|
||||
|
||||
var/max_power_rating = 20000 // Power rating when the usage is turned up to 100
|
||||
var/power_setting = 100
|
||||
|
||||
var/set_temperature = T20C // Thermostat
|
||||
var/cooling = 0
|
||||
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/unary_atmos/cooler,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/capacitor = 2,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stack/cable_coil{amount = 2}
|
||||
)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/Initialize()
|
||||
initialize_directions = dir
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/atmos_init()
|
||||
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))
|
||||
node = target
|
||||
break
|
||||
|
||||
//copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday.
|
||||
//check that there are no incompatible pipes/machinery in our own location
|
||||
for(var/obj/machinery/atmospherics/M in src.loc)
|
||||
if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type
|
||||
node = null
|
||||
break
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/update_icon()
|
||||
if(node)
|
||||
if(use_power && cooling)
|
||||
icon_state = "freezer_1"
|
||||
else
|
||||
icon_state = "freezer"
|
||||
else
|
||||
icon_state = "freezer_0"
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/attack_ai(mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if(!ui)
|
||||
ui = new(user, src, "machinery-atmospherics-freezer", 440, 300, "Gas Cooling System")
|
||||
ui.auto_update_content = TRUE
|
||||
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/vueui_data_change(list/data, mob/user, datum/vueui/ui)
|
||||
data = list()
|
||||
|
||||
data["on"] = use_power ? 1 : 0
|
||||
data["gasPressure"] = round(air_contents.return_pressure())
|
||||
data["gasTemperature"] = round(air_contents.temperature)
|
||||
data["minGasTemperature"] = 0
|
||||
data["maxGasTemperature"] = round(T20C+500)
|
||||
data["targetGasTemperature"] = round(set_temperature)
|
||||
data["powerSetting"] = power_setting
|
||||
|
||||
data["gasTemperatureBadTop"] = (T0C - 20)
|
||||
data["gasTemperatureBadBottom"] = null
|
||||
data["gasTemperatureAvgTop"] = (T0C - 20)
|
||||
data["gasTemperatureAvgBottom"] = (T0C - 100)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["toggleStatus"])
|
||||
update_use_power(!use_power)
|
||||
update_icon()
|
||||
if(href_list["temp"])
|
||||
var/amount = text2num(href_list["temp"])
|
||||
if(amount > 0)
|
||||
set_temperature = min(set_temperature + amount, 1000)
|
||||
else
|
||||
set_temperature = max(set_temperature + amount, 0)
|
||||
if(href_list["setPower"]) //setting power to 0 is redundant anyways
|
||||
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
|
||||
set_power_level(new_setting)
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/process()
|
||||
..()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN) || !use_power)
|
||||
cooling = 0
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(network && air_contents.temperature > set_temperature)
|
||||
cooling = 1
|
||||
|
||||
var/heat_transfer = max( -air_contents.get_thermal_energy_change(set_temperature - 5), 0 )
|
||||
|
||||
//Assume the heat is being pumped into the hull which is fixed at heatsink_temperature
|
||||
//not /really/ proper thermodynamics but whatever
|
||||
var/cop = FREEZER_PERF_MULT * air_contents.temperature/heatsink_temperature //heatpump coefficient of performance from thermodynamics -> power used = heat_transfer/cop
|
||||
heat_transfer = min(heat_transfer, cop * power_rating) //limit heat transfer by available power
|
||||
|
||||
var/removed = -air_contents.add_thermal_energy(-heat_transfer) //remove the heat
|
||||
if(debug)
|
||||
visible_message("[src]: Removing [removed] W.")
|
||||
|
||||
use_power_oneoff(power_rating)
|
||||
|
||||
network.update = 1
|
||||
else
|
||||
cooling = 0
|
||||
|
||||
update_icon()
|
||||
|
||||
//upgrading parts
|
||||
/obj/machinery/atmospherics/unary/freezer/RefreshParts()
|
||||
..()
|
||||
var/cap_rating = 0
|
||||
var/manip_rating = 0
|
||||
var/bin_rating = 0
|
||||
for(var/obj/item/stock_parts/P in component_parts)
|
||||
if(iscapacitor(P))
|
||||
cap_rating += P.rating
|
||||
else if(ismanipulator(P))
|
||||
manip_rating += P.rating
|
||||
else if(ismatterbin(P))
|
||||
bin_rating += P.rating
|
||||
|
||||
power_rating = initial(power_rating) * cap_rating / 2 //more powerful
|
||||
heatsink_temperature = initial(heatsink_temperature) / ((manip_rating + bin_rating) / 2) //more efficient
|
||||
air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating
|
||||
set_power_level(power_setting)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/proc/set_power_level(var/new_power_setting)
|
||||
power_setting = new_power_setting
|
||||
power_rating = max_power_rating * (power_setting/100)
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return TRUE
|
||||
if(default_part_replacement(user, O))
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/freezer/examine(mob/user)
|
||||
..(user)
|
||||
if(panel_open)
|
||||
to_chat(user, "The maintenance hatch is open.")
|
||||
@@ -0,0 +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()
|
||||
return air_contents
|
||||
@@ -0,0 +1,89 @@
|
||||
/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
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
|
||||
return
|
||||
|
||||
atmos_init()
|
||||
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
|
||||
|
||||
..()
|
||||
|
||||
process()
|
||||
..()
|
||||
if(QDELETED(partner))
|
||||
return 0
|
||||
|
||||
if(!SSair || SSair.times_fired <= update_cycle)
|
||||
return 0
|
||||
|
||||
update_cycle = SSair.times_fired
|
||||
partner.update_cycle = SSair.times_fired
|
||||
|
||||
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
|
||||
|
||||
attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
var/turf/T = src.loc
|
||||
if (level==1 && isturf(T) && !T.is_plating())
|
||||
to_chat(user, "<span class='warning'>You must remove the plating first.</span>")
|
||||
return 1
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,174 @@
|
||||
//TODO: Put this under a common parent type with freezers to cut down on the copypasta
|
||||
#define HEATER_PERF_MULT 2.5
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater
|
||||
name = "gas heating system"
|
||||
desc = "Heats gas when connected to a pipe network."
|
||||
desc_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
icon = 'icons/obj/sleeper.dmi'
|
||||
icon_state = "heater_0"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 5 //5 Watts for thermostat related circuitry
|
||||
|
||||
var/max_temperature = T20C + 680
|
||||
var/internal_volume = 600 //L
|
||||
|
||||
var/max_power_rating = 20000 //power rating when the usage is turned up to 100
|
||||
var/power_setting = 100
|
||||
|
||||
var/set_temperature = T20C //thermostat
|
||||
var/heating = 0 //mainly for icon updates
|
||||
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/unary_atmos/heater,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/capacitor = 2,
|
||||
/obj/item/stack/cable_coil{amount = 5}
|
||||
)
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/Initialize()
|
||||
initialize_directions = dir
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/atmos_init()
|
||||
if(node)
|
||||
return
|
||||
|
||||
var/node_connect = dir
|
||||
|
||||
//check that there is something to connect to
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, node_connect))
|
||||
if(target.initialize_directions & get_dir(target, src))
|
||||
node = target
|
||||
break
|
||||
|
||||
//copied from pipe construction code since heaters/freezers don't use fittings and weren't doing this check - this all really really needs to be refactored someday.
|
||||
//check that there are no incompatible pipes/machinery in our own location
|
||||
for(var/obj/machinery/atmospherics/M in src.loc)
|
||||
if(M != src && (M.initialize_directions & node_connect) && M.check_connect_types(M,src)) // matches at least one direction on either type of pipe & same connection type
|
||||
node = null
|
||||
break
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/update_icon()
|
||||
if(node)
|
||||
if(use_power && heating)
|
||||
icon_state = "heater_1"
|
||||
else
|
||||
icon_state = "heater"
|
||||
else
|
||||
icon_state = "heater_0"
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/process()
|
||||
..()
|
||||
|
||||
if(stat & (NOPOWER|BROKEN) || !use_power)
|
||||
heating = 0
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(network && air_contents.total_moles && air_contents.temperature < set_temperature)
|
||||
air_contents.add_thermal_energy(power_rating * HEATER_PERF_MULT)
|
||||
use_power_oneoff(power_rating)
|
||||
|
||||
heating = 1
|
||||
network.update = 1
|
||||
else
|
||||
heating = 0
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/attack_ai(mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/ui_interact(mob/user)
|
||||
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
|
||||
if(!ui)
|
||||
ui = new(user, src, "machinery-atmospherics-freezer", 440, 300, "Gas Heating System")
|
||||
ui.auto_update_content = TRUE
|
||||
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/vueui_data_change(list/data, mob/user, datum/vueui/ui)
|
||||
data = list()
|
||||
|
||||
data["on"] = use_power ? 1 : 0
|
||||
data["gasPressure"] = round(air_contents.return_pressure())
|
||||
data["gasTemperature"] = round(air_contents.temperature)
|
||||
data["minGasTemperature"] = 0
|
||||
data["maxGasTemperature"] = round(max_temperature)
|
||||
data["targetGasTemperature"] = round(set_temperature)
|
||||
data["powerSetting"] = power_setting
|
||||
|
||||
data["gasTemperatureBadTop"] = (T20C+40)
|
||||
data["gasTemperatureBadBottom"] = null
|
||||
data["gasTemperatureAvgTop"] = null
|
||||
data["gasTemperatureAvgBottom"] = null
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["toggleStatus"])
|
||||
update_use_power(!use_power)
|
||||
update_icon()
|
||||
if(href_list["temp"])
|
||||
var/amount = text2num(href_list["temp"])
|
||||
if(amount > 0)
|
||||
set_temperature = min(set_temperature + amount, max_temperature)
|
||||
else
|
||||
set_temperature = max(set_temperature + amount, 0)
|
||||
if(href_list["setPower"]) //setting power to 0 is redundant anyways
|
||||
var/new_setting = between(0, text2num(href_list["setPower"]), 100)
|
||||
set_power_level(new_setting)
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
//upgrading parts
|
||||
/obj/machinery/atmospherics/unary/heater/RefreshParts()
|
||||
..()
|
||||
var/cap_rating = 0
|
||||
var/bin_rating = 0
|
||||
for(var/obj/item/stock_parts/P in component_parts)
|
||||
if(iscapacitor(P))
|
||||
cap_rating += P.rating
|
||||
else if(ismatterbin(P))
|
||||
bin_rating += P.rating
|
||||
|
||||
max_power_rating = initial(max_power_rating) * cap_rating / 2
|
||||
max_temperature = max(initial(max_temperature) - T20C, 0) * ((bin_rating * 4 + cap_rating) / 5) + T20C
|
||||
air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating
|
||||
set_power_level(power_setting)
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/proc/set_power_level(var/new_power_setting)
|
||||
power_setting = new_power_setting
|
||||
power_rating = max_power_rating * (power_setting/100)
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
return TRUE
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return TRUE
|
||||
if(default_part_replacement(user, O))
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/heater/examine(mob/user)
|
||||
..(user)
|
||||
if(panel_open)
|
||||
to_chat(user, "The maintenance hatch is open.")
|
||||
@@ -0,0 +1,160 @@
|
||||
//Basically a one way passive valve. If the pressure inside is greater than the environment then gas will flow passively,
|
||||
//but it does not permit gas to flow back from the environment into the injector. Can be turned off to prevent any gas flow.
|
||||
//When it receives the "inject" signal, it will try to pump it's entire contents into the environment regardless of pressure, using power.
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector
|
||||
name = "air injector"
|
||||
desc = "Passively injects air into its surroundings. Has a valve attached to it that can control flow rate."
|
||||
desc_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
|
||||
A green light on it means it is on."
|
||||
icon = 'icons/atmos/injector.dmi'
|
||||
icon_state = "map_injector"
|
||||
layer = 3
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 15000 //15000 W ~ 20 HP
|
||||
|
||||
var/injecting = 0
|
||||
|
||||
var/volume_rate = 50 //flow rate limit
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
level = 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/Initialize()
|
||||
. = ..()
|
||||
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 500 //Give it a small reservoir for injecting. Also allows it to have a higher flow rate limit than vent pumps, to differentiate injectors a bit more.
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/update_icon()
|
||||
if(!powered())
|
||||
icon_state = "off"
|
||||
else
|
||||
icon_state = "[use_power ? "on" : "off"]"
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node, dir)
|
||||
|
||||
/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()
|
||||
..()
|
||||
|
||||
last_power_draw = 0
|
||||
last_flow_rate = 0
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
if((stat & (NOPOWER|BROKEN)) || !use_power)
|
||||
return
|
||||
|
||||
var/power_draw = -1
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
if(environment && air_contents.temperature > 0)
|
||||
var/transfer_moles = (volume_rate/air_contents.volume)*air_contents.total_moles //apply flow rate limit
|
||||
power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating)
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/proc/inject()
|
||||
if(injecting || (stat & NOPOWER))
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if (!environment)
|
||||
return 0
|
||||
|
||||
injecting = 1
|
||||
|
||||
if(air_contents.temperature > 0)
|
||||
var/power_used = pump_gas(src, air_contents, environment, air_contents.total_moles, power_rating)
|
||||
use_power_oneoff(power_used)
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
flick("inject", src)
|
||||
|
||||
/obj/machinery/atmospherics/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/unary/outlet_injector/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"tag" = id,
|
||||
"device" = "AO",
|
||||
"power" = use_power,
|
||||
"volume_rate" = volume_rate,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/atmos_init()
|
||||
..()
|
||||
|
||||
set_frequency(frequency)
|
||||
broadcast_status()
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if(signal.data["power"])
|
||||
update_use_power(text2num(signal.data["power"]))
|
||||
|
||||
if(signal.data["power_toggle"])
|
||||
update_use_power(!use_power)
|
||||
|
||||
if(signal.data["inject"])
|
||||
spawn inject()
|
||||
return
|
||||
|
||||
if(signal.data["set_volume_rate"])
|
||||
var/number = text2num(signal.data["set_volume_rate"])
|
||||
volume_rate = between(0, number, air_contents.volume)
|
||||
|
||||
if(signal.data["status"])
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/hide(var/i)
|
||||
update_underlays()
|
||||
@@ -0,0 +1,48 @@
|
||||
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
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact_[on?("on"):("off")]"
|
||||
else
|
||||
icon_state = "exposed_off"
|
||||
|
||||
on = 0
|
||||
|
||||
return
|
||||
|
||||
Initialize()
|
||||
. = ..()
|
||||
air_contents.volume = 50
|
||||
|
||||
process()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
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.adjust_gas(GAS_OXYGEN, added_oxygen)
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,81 @@
|
||||
#define RADIATION_CAPACITY 30000 //Radiation isn't particularly effective (TODO BALANCE)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/thermal_plate
|
||||
//Based off Heat Reservoir and Space Heater
|
||||
//Transfers heat between a pipe system and environment, based on which has a greater thermal energy concentration
|
||||
|
||||
icon = 'icons/obj/atmospherics/cold_sink.dmi'
|
||||
icon_state = "intact_off"
|
||||
|
||||
name = "Thermal Transfer Plate"
|
||||
desc = "Transfers heat to and from an area"
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact_off"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
return
|
||||
|
||||
process()
|
||||
..()
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
//Get processable air sample and thermal info from environment
|
||||
|
||||
var/transfer_moles = 0.25 * environment.total_moles()
|
||||
var/datum/gas_mixture/external_removed = environment.remove(transfer_moles)
|
||||
|
||||
if (!external_removed)
|
||||
return radiate()
|
||||
|
||||
if (external_removed.total_moles() < 10)
|
||||
return radiate()
|
||||
|
||||
//Get same info from connected gas
|
||||
|
||||
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
|
||||
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
|
||||
|
||||
if (!internal_removed)
|
||||
environment.merge(external_removed)
|
||||
return 1
|
||||
|
||||
var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity()
|
||||
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature
|
||||
|
||||
if(!combined_heat_capacity) combined_heat_capacity = 1
|
||||
var/final_temperature = combined_energy / combined_heat_capacity
|
||||
|
||||
external_removed.temperature = final_temperature
|
||||
environment.merge(external_removed)
|
||||
|
||||
internal_removed.temperature = final_temperature
|
||||
air_contents.merge(internal_removed)
|
||||
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
proc/radiate()
|
||||
|
||||
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
|
||||
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
|
||||
|
||||
if (!internal_removed)
|
||||
return 1
|
||||
|
||||
var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY
|
||||
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * 6.4)
|
||||
|
||||
var/final_temperature = combined_energy / combined_heat_capacity
|
||||
|
||||
internal_removed.temperature = final_temperature
|
||||
air_contents.merge(internal_removed)
|
||||
|
||||
if (network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,102 @@
|
||||
/obj/machinery/atmospherics/unary
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
//layer = TURF_LAYER+0.1
|
||||
|
||||
var/datum/gas_mixture/air_contents
|
||||
|
||||
var/obj/machinery/atmospherics/node
|
||||
|
||||
var/datum/pipe_network/network
|
||||
|
||||
Initialize()
|
||||
initialize_directions = dir
|
||||
air_contents = new
|
||||
air_contents.volume = 200
|
||||
. = ..()
|
||||
|
||||
// Housekeeping and pipe network stuff below
|
||||
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
|
||||
|
||||
Destroy()
|
||||
QDEL_NULL(air_contents)
|
||||
|
||||
if(node)
|
||||
node.disconnect(src)
|
||||
QDEL_NULL(network)
|
||||
|
||||
node = null
|
||||
|
||||
return ..()
|
||||
|
||||
atmos_init()
|
||||
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 (check_connect_types(target,src))
|
||||
node = target
|
||||
break
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
build_network()
|
||||
if(!network && node)
|
||||
network = new /datum/pipe_network()
|
||||
network.normal_members += src
|
||||
network.build_network(node, src)
|
||||
|
||||
|
||||
return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node)
|
||||
return network
|
||||
|
||||
return null
|
||||
|
||||
reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network == old_network)
|
||||
network = new_network
|
||||
|
||||
return 1
|
||||
|
||||
return_network_air(datum/pipe_network/reference)
|
||||
var/list/results = list()
|
||||
|
||||
if(network == reference)
|
||||
results += air_contents
|
||||
|
||||
return results
|
||||
|
||||
disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node)
|
||||
qdel(network)
|
||||
node = null
|
||||
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/is_welded() // TODO: refactor welding into unary
|
||||
if (welded > 0)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/is_welded()
|
||||
if (welded > 0)
|
||||
return 1
|
||||
return 0
|
||||
@@ -0,0 +1,467 @@
|
||||
#define DEFAULT_PRESSURE_DELTA 10000
|
||||
|
||||
#define EXTERNAL_PRESSURE_BOUND ONE_ATMOSPHERE
|
||||
#define INTERNAL_PRESSURE_BOUND 0
|
||||
#define PRESSURE_CHECKS 1
|
||||
|
||||
#define PRESSURE_CHECK_EXTERNAL 1
|
||||
#define PRESSURE_CHECK_INTERNAL 2
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump
|
||||
name = "air vent"
|
||||
desc = "Has a valve and pump attached to it."
|
||||
desc_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
|
||||
icon = 'icons/atmos/vent_pump.dmi'
|
||||
icon_state = "map_vent"
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //7500 W ~ 10 HP
|
||||
|
||||
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY //connects to regular and supply pipes
|
||||
|
||||
var/area/initial_loc
|
||||
level = 1
|
||||
var/area_uid
|
||||
var/id_tag = null
|
||||
|
||||
var/hibernate = 0 //Do we even process?
|
||||
var/pump_direction = 1 //0 = siphoning, 1 = releasing
|
||||
|
||||
var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND
|
||||
var/internal_pressure_bound = INTERNAL_PRESSURE_BOUND
|
||||
|
||||
var/pressure_checks = PRESSURE_CHECKS
|
||||
//1: Do not pass external_pressure_bound
|
||||
//2: Do not pass internal_pressure_bound
|
||||
//3: Do not pass either
|
||||
|
||||
// Used when handling incoming radio signals requesting default settings
|
||||
var/external_pressure_bound_default = EXTERNAL_PRESSURE_BOUND
|
||||
var/internal_pressure_bound_default = INTERNAL_PRESSURE_BOUND
|
||||
var/pressure_checks_default = PRESSURE_CHECKS
|
||||
|
||||
var/welded = 0 // Added for aliens -- TLE
|
||||
|
||||
var/frequency = 1439
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on
|
||||
use_power = POWER_USE_IDLE
|
||||
icon_state = "map_vent_out"
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/siphon
|
||||
pump_direction = 0
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/siphon/atmos
|
||||
icon_state = "map_vent_in"
|
||||
external_pressure_bound = 0
|
||||
external_pressure_bound_default = 0
|
||||
internal_pressure_bound = 2000
|
||||
internal_pressure_bound_default = 2000
|
||||
pressure_checks = 2
|
||||
pressure_checks_default = 2
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/siphon/on
|
||||
use_power = POWER_USE_IDLE
|
||||
icon_state = "map_vent_in"
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/siphon/on/atmos
|
||||
use_power = POWER_USE_IDLE
|
||||
icon_state = "map_vent_in"
|
||||
external_pressure_bound = 0
|
||||
external_pressure_bound_default = 0
|
||||
internal_pressure_bound = 2000
|
||||
internal_pressure_bound_default = 2000
|
||||
pressure_checks = 2
|
||||
pressure_checks_default = 2
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/Initialize(mapload)
|
||||
if(mapload)
|
||||
var/turf/T = loc
|
||||
var/image/I = image(icon, T, icon_state, EFFECTS_ABOVE_LIGHTING_LAYER, dir, pixel_x, pixel_y)
|
||||
I.plane = 0
|
||||
I.color = color
|
||||
I.alpha = 125
|
||||
LAZYADD(T.blueprints, I)
|
||||
|
||||
. = ..()
|
||||
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP
|
||||
|
||||
initial_loc = loc.loc
|
||||
area_uid = initial_loc.uid
|
||||
if (!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
setup_radio()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/setup_radio()
|
||||
//some vents work his own special way
|
||||
radio_filter_in = frequency == 1439 ? (RADIO_FROM_AIRALARM) : null
|
||||
radio_filter_out = frequency == 1439 ? (RADIO_TO_AIRALARM) : null
|
||||
if(frequency)
|
||||
radio_connection = register_radio(src, frequency, frequency, radio_filter_in)
|
||||
|
||||
// Different from the above.
|
||||
/obj/machinery/atmospherics/unary/vent_pump/atmos_init()
|
||||
..()
|
||||
broadcast_status()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/Destroy()
|
||||
unregister_radio(src, frequency)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/high_volume
|
||||
name = "Large Air Vent"
|
||||
power_channel = EQUIP
|
||||
power_rating = 15000 //15 kW ~ 20 HP
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/high_volume/Initialize()
|
||||
. = ..()
|
||||
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 800
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/engine
|
||||
name = "Engine Core Vent"
|
||||
power_channel = ENVIRON
|
||||
power_rating = 30000 //15 kW ~ 20 HP
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/engine/Initialize()
|
||||
. = ..()
|
||||
air_contents.volume = ATMOS_DEFAULT_VOLUME_PUMP + 500 //meant to match air injector
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/update_icon(var/safety = 0)
|
||||
if (!node)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
var/vent_icon = ""
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
vent_icon += "h"
|
||||
|
||||
if(welded)
|
||||
vent_icon += "weld"
|
||||
else if(!powered())
|
||||
vent_icon += "off"
|
||||
else
|
||||
vent_icon += "[use_power ? "[pump_direction ? "out" : "in"]" : "off"]"
|
||||
|
||||
icon_state = vent_icon
|
||||
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if(node)
|
||||
add_underlay(T, node, dir, node.icon_connect_type)
|
||||
else
|
||||
add_underlay(T,, dir)
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/hide()
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/can_pump()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
if(!use_power)
|
||||
return 0
|
||||
if(welded)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/process()
|
||||
..()
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
if (hibernate > world.time)
|
||||
return 1
|
||||
|
||||
if (!node)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
if(!can_pump())
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/power_draw = -1
|
||||
|
||||
//Figure out the target pressure difference
|
||||
var/pressure_delta = get_pressure_delta(environment)
|
||||
//src.visible_message("DEBUG >>> [src]: pressure_delta = [pressure_delta]")
|
||||
|
||||
if((environment.temperature || air_contents.temperature) && pressure_delta > 0.5)
|
||||
if(pump_direction) //internal -> external
|
||||
var/transfer_moles = calculate_transfer_moles(air_contents, environment, pressure_delta)
|
||||
power_draw = pump_gas(src, air_contents, environment, transfer_moles, power_rating)
|
||||
else //external -> internal
|
||||
var/transfer_moles = calculate_transfer_moles(environment, air_contents, pressure_delta, (network)? network.volume : 0)
|
||||
|
||||
//limit flow rate from turfs
|
||||
transfer_moles = min(transfer_moles, environment.total_moles*air_contents.volume/environment.volume) //group_multiplier gets divided out here
|
||||
power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating)
|
||||
|
||||
else
|
||||
//If we're in an area that is fucking ideal, and we don't have to do anything, chances are we won't next tick either so why redo these calculations?
|
||||
//JESUS FUCK. THERE ARE LITERALLY 250 OF YOU MOTHERFUCKERS ON ZLEVEL ONE AND YOU DO THIS SHIT EVERY TICK WHEN VERY OFTEN THERE IS NO REASON TO
|
||||
if(pump_direction && pressure_checks == PRESSURE_CHECK_EXTERNAL) //99% of all vents
|
||||
hibernate = world.time + (rand(100,200))
|
||||
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/get_pressure_delta(datum/gas_mixture/environment)
|
||||
var/pressure_delta = DEFAULT_PRESSURE_DELTA
|
||||
var/environment_pressure = environment.return_pressure()
|
||||
|
||||
if(pump_direction) //internal -> external
|
||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||
pressure_delta = min(pressure_delta, external_pressure_bound - environment_pressure) //increasing the pressure here
|
||||
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
||||
pressure_delta = min(pressure_delta, air_contents.return_pressure() - internal_pressure_bound) //decreasing the pressure here
|
||||
else //external -> internal
|
||||
if(pressure_checks & PRESSURE_CHECK_EXTERNAL)
|
||||
pressure_delta = min(pressure_delta, environment_pressure - external_pressure_bound) //decreasing the pressure here
|
||||
if(pressure_checks & PRESSURE_CHECK_INTERNAL)
|
||||
pressure_delta = min(pressure_delta, internal_pressure_bound - air_contents.return_pressure()) //increasing the pressure here
|
||||
|
||||
return pressure_delta
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
|
||||
signal.data = list(
|
||||
"area" = src.area_uid,
|
||||
"tag" = src.id_tag,
|
||||
"device" = "AVP",
|
||||
"power" = use_power,
|
||||
"direction" = pump_direction?("release"):("siphon"),
|
||||
"checks" = pressure_checks,
|
||||
"internal" = internal_pressure_bound,
|
||||
"external" = external_pressure_bound,
|
||||
"timestamp" = world.time,
|
||||
"sigtype" = "status",
|
||||
"power_draw" = last_power_draw,
|
||||
"flow_rate" = last_flow_rate
|
||||
)
|
||||
|
||||
var/area/A = get_area(src)
|
||||
if(!A.air_vent_names[id_tag])
|
||||
var/new_name = "[A.name] Vent Pump #[A.air_vent_names.len+1]"
|
||||
A.air_vent_names[id_tag] = new_name
|
||||
src.name = new_name
|
||||
A.air_vent_info[id_tag] = signal.data
|
||||
|
||||
radio_connection.post_signal(src, signal, radio_filter_out)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
hibernate = 0
|
||||
|
||||
//log_debug("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/unary/vent_pump/receive_signal([signal.debug_print()])")
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if(signal.data["purge"] != null)
|
||||
pressure_checks &= ~1
|
||||
pump_direction = 0
|
||||
|
||||
if(signal.data["stabalize"] != null)
|
||||
pressure_checks |= 1
|
||||
pump_direction = 1
|
||||
|
||||
if(signal.data["power"] != null)
|
||||
update_use_power(text2num(signal.data["power"]))
|
||||
|
||||
if(signal.data["power_toggle"] != null)
|
||||
update_use_power(!use_power)
|
||||
|
||||
if(signal.data["checks"] != null)
|
||||
if (signal.data["checks"] == "default")
|
||||
pressure_checks = pressure_checks_default
|
||||
else
|
||||
pressure_checks = text2num(signal.data["checks"])
|
||||
|
||||
if(signal.data["checks_toggle"] != null)
|
||||
pressure_checks = (pressure_checks?0:3)
|
||||
|
||||
if(signal.data["direction"] != null)
|
||||
pump_direction = text2num(signal.data["direction"])
|
||||
|
||||
if(signal.data["set_internal_pressure"] != null)
|
||||
if (signal.data["set_internal_pressure"] == "default")
|
||||
internal_pressure_bound = internal_pressure_bound_default
|
||||
else
|
||||
internal_pressure_bound = between(
|
||||
0,
|
||||
text2num(signal.data["set_internal_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["set_external_pressure"] != null)
|
||||
if (signal.data["set_external_pressure"] == "default")
|
||||
external_pressure_bound = external_pressure_bound_default
|
||||
else
|
||||
external_pressure_bound = between(
|
||||
0,
|
||||
text2num(signal.data["set_external_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["adjust_internal_pressure"] != null)
|
||||
internal_pressure_bound = between(
|
||||
0,
|
||||
internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["adjust_external_pressure"] != null)
|
||||
|
||||
|
||||
external_pressure_bound = between(
|
||||
0,
|
||||
external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),
|
||||
ONE_ATMOSPHERE*50
|
||||
)
|
||||
|
||||
if(signal.data["init"] != null)
|
||||
name = signal.data["init"]
|
||||
return
|
||||
|
||||
if(signal.data["status"] != null)
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user)
|
||||
if(W.iswelder())
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if (!WT.welding)
|
||||
to_chat(user, SPAN_DANGER("\The [WT] must be turned on!"))
|
||||
else if (WT.remove_fuel(0,user))
|
||||
to_chat(user, SPAN_NOTICE("Now welding the vent."))
|
||||
if(do_after(user, 30/W.toolspeed))
|
||||
if(!src || !WT.isOn())
|
||||
return TRUE
|
||||
welded = !welded
|
||||
update_icon()
|
||||
playsound(src, 'sound/items/welder_pry.ogg', 50, 1)
|
||||
user.visible_message(SPAN_NOTICE("\The [user] [welded ? "welds \the [src] shut" : "unwelds \the [src]"]."), \
|
||||
SPAN_NOTICE("You [welded ? "weld \the [src] shut" : "unweld \the [src]"]."), \
|
||||
"You hear welding.")
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("You fail to complete the welding."))
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
|
||||
return TRUE
|
||||
else if(istype(W, /obj/item/melee/arm_blade))
|
||||
if(!welded)
|
||||
to_chat(user, SPAN_WARNING("\The [W] can only be used to tear open welded air vents!"))
|
||||
return TRUE
|
||||
user.visible_message(SPAN_WARNING("\The [user] starts using \the [W] to hack open \the [src]!"), SPAN_NOTICE("You start hacking open \the [src] with \the [W]..."))
|
||||
user.do_attack_animation(src, W)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 60, TRUE)
|
||||
var/cut_amount = 3
|
||||
for(var/i = 0; i <= cut_amount; i++)
|
||||
if(!W || !do_after(user, 30, src))
|
||||
return TRUE
|
||||
user.do_attack_animation(src, W)
|
||||
user.visible_message(SPAN_WARNING("\The [user] smashes \the [W] into \the [src]!"), SPAN_NOTICE("You smash \the [W] into \the [src]."))
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 60, TRUE)
|
||||
if(i == cut_amount)
|
||||
welded = FALSE
|
||||
spark(get_turf(src), 3, alldirs)
|
||||
playsound(loc, 'sound/items/welder_pry.ogg', 50, TRUE)
|
||||
update_icon()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
|
||||
else
|
||||
to_chat(user, "You are too far away to read the gauge.")
|
||||
if(welded)
|
||||
to_chat(user, "It seems welded shut.")
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
to_chat(user, SPAN_WARNING("You cannot unwrench \the [src], turn it off first."))
|
||||
return TRUE
|
||||
var/turf/T = src.loc
|
||||
if (node && node.level==1 && isturf(T) && !T.is_plating())
|
||||
to_chat(user, SPAN_WARNING("You must remove the plating first."))
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, SPAN_WARNING("You cannot unwrench \the [src], it is too exerted due to internal pressure."))
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, SPAN_NOTICE("You begin to unfasten \the [src]..."))
|
||||
if (do_after(user, 40/W.toolspeed))
|
||||
user.visible_message( \
|
||||
SPAN_NOTICE("\The [user] unfastens \the [src]."), \
|
||||
SPAN_NOTICE("You have unfastened \the [src]."), \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/Destroy()
|
||||
if(initial_loc)
|
||||
initial_loc.air_vent_info -= id_tag
|
||||
initial_loc.air_vent_names -= id_tag
|
||||
return ..()
|
||||
|
||||
#undef DEFAULT_PRESSURE_DELTA
|
||||
|
||||
#undef EXTERNAL_PRESSURE_BOUND
|
||||
#undef INTERNAL_PRESSURE_BOUND
|
||||
#undef PRESSURE_CHECKS
|
||||
|
||||
#undef PRESSURE_CHECK_EXTERNAL
|
||||
#undef PRESSURE_CHECK_INTERNAL
|
||||
@@ -0,0 +1,375 @@
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber
|
||||
name = "air scrubber"
|
||||
desc = "Has a valve and pump attached to it."
|
||||
desc_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \
|
||||
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
|
||||
icon = 'icons/atmos/vent_scrubber.dmi'
|
||||
icon_state = "map_scrubber_off"
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 150 //internal circuitry, friction losses and stuff
|
||||
power_rating = 7500 //7500 W ~ 10 HP
|
||||
|
||||
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SCRUBBER //connects to regular and scrubber pipes
|
||||
|
||||
level = 1
|
||||
|
||||
var/area/initial_loc
|
||||
var/id_tag = null
|
||||
var/frequency = 1439
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/hibernate = 0 //Do we even process?
|
||||
var/scrubbing = 1 //0 = siphoning, 1 = scrubbing
|
||||
var/list/scrubbing_gas
|
||||
|
||||
var/panic = 0 //is this scrubber panicked?
|
||||
|
||||
var/area_uid
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
|
||||
var/welded = 0
|
||||
|
||||
var/broadcast_status_next_process = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on
|
||||
use_power = POWER_USE_IDLE
|
||||
icon_state = "map_scrubber_on"
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/Initialize(mapload)
|
||||
if(mapload)
|
||||
var/turf/T = loc
|
||||
var/image/I = image(icon, T, icon_state, EFFECTS_ABOVE_LIGHTING_LAYER, dir, pixel_x, pixel_y)
|
||||
I.plane = 0
|
||||
I.color = color
|
||||
I.alpha = 125
|
||||
LAZYADD(T.blueprints, I)
|
||||
|
||||
. = ..()
|
||||
air_contents.volume = ATMOS_DEFAULT_VOLUME_FILTER
|
||||
|
||||
initial_loc = get_area(loc)
|
||||
area_uid = initial_loc.uid
|
||||
if (!id_tag)
|
||||
assign_uid()
|
||||
id_tag = num2text(uid)
|
||||
|
||||
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)
|
||||
|
||||
if (!scrubbing_gas)
|
||||
reset_scrubbing()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/reset_scrubbing()
|
||||
if (initial(scrubbing_gas))
|
||||
scrubbing_gas = initial(scrubbing_gas)
|
||||
else
|
||||
scrubbing_gas = list()
|
||||
for (var/g in gas_data.gases)
|
||||
if (g != GAS_OXYGEN && g != GAS_NITROGEN)
|
||||
add_to_scrubbing(g)
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/add_to_scrubbing(new_gas)
|
||||
scrubbing_gas |= new_gas
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/proc/remove_from_scrubbing(old_gas)
|
||||
scrubbing_gas -= old_gas
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/atmos_init()
|
||||
..()
|
||||
broadcast_status()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
|
||||
unregister_radio(src, frequency)
|
||||
if(initial_loc)
|
||||
initial_loc.air_scrub_info -= id_tag
|
||||
initial_loc.air_scrub_names -= id_tag
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/update_icon(var/safety = 0)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if (welded)
|
||||
icon_state = "weld"
|
||||
return
|
||||
|
||||
if (!powered() || !use_power)
|
||||
icon_state = "off"
|
||||
else if (scrubbing)
|
||||
icon_state = "on"
|
||||
else
|
||||
icon_state = "in"
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!T.is_plating() && node && node.level == 1 && istype(node, /obj/machinery/atmospherics/pipe))
|
||||
return
|
||||
else
|
||||
if(node)
|
||||
add_underlay(T, node, dir, node.icon_connect_type)
|
||||
else
|
||||
add_underlay(T,, dir)
|
||||
|
||||
/obj/machinery/atmospherics/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/unary/vent_scrubber/proc/broadcast_status()
|
||||
if(!radio_connection)
|
||||
return 0
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.transmission_method = TRANSMISSION_RADIO
|
||||
signal.source = src
|
||||
signal.data = list(
|
||||
"area" = area_uid,
|
||||
"tag" = id_tag,
|
||||
"device" = "AScr",
|
||||
"timestamp" = world.time,
|
||||
"power" = use_power,
|
||||
"scrubbing" = scrubbing,
|
||||
"panic" = panic,
|
||||
"filter_o2" = (GAS_OXYGEN in scrubbing_gas),
|
||||
"filter_n2" = (GAS_NITROGEN in scrubbing_gas),
|
||||
"filter_co2" = (GAS_CO2 in scrubbing_gas),
|
||||
"filter_phoron" = (GAS_PHORON in scrubbing_gas),
|
||||
"filter_n2o" = (GAS_N2O in scrubbing_gas),
|
||||
"filter_h2" = (GAS_HYDROGEN in scrubbing_gas),
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
var/area/A = get_area(src)
|
||||
if(!A.air_scrub_names[id_tag])
|
||||
var/new_name = "[A.name] Air Scrubber #[A.air_scrub_names.len+1]"
|
||||
A.air_scrub_names[id_tag] = new_name
|
||||
src.name = new_name
|
||||
A.air_scrub_info[id_tag] = signal.data
|
||||
radio_connection.post_signal(src, signal, radio_filter_out)
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/process()
|
||||
..()
|
||||
|
||||
if (hibernate > world.time)
|
||||
return 1
|
||||
|
||||
if (!node)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
if (broadcast_status_next_process)
|
||||
broadcast_status()
|
||||
broadcast_status_next_process = FALSE
|
||||
|
||||
if(!use_power || (stat & (NOPOWER|BROKEN)))
|
||||
return 0
|
||||
if(welded)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/power_draw = -1
|
||||
if(scrubbing)
|
||||
//limit flow rate from turfs
|
||||
var/transfer_moles = min(environment.total_moles, environment.total_moles*MAX_SCRUBBER_FLOWRATE/environment.volume) //group_multiplier gets divided out here
|
||||
|
||||
power_draw = scrub_gas(src, scrubbing_gas, environment, air_contents, transfer_moles, power_rating)
|
||||
else //Just siphon all air
|
||||
//limit flow rate from turfs
|
||||
var/transfer_moles = min(environment.total_moles, environment.total_moles*MAX_SIPHON_FLOWRATE/environment.volume) //group_multiplier gets divided out here
|
||||
|
||||
power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating)
|
||||
|
||||
if(scrubbing && power_draw <= 0) //99% of all scrubbers
|
||||
//Fucking hibernate because you ain't doing shit.
|
||||
hibernate = world.time + (rand(100,200))
|
||||
|
||||
if (power_draw >= 0)
|
||||
last_power_draw = power_draw
|
||||
use_power_oneoff(power_draw)
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/hide(var/i) //to make the little pipe section invisible, the icon changes.
|
||||
update_icon()
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/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(signal.data["power"] != null)
|
||||
update_use_power(text2num(signal.data["power"]))
|
||||
if(signal.data["power_toggle"] != null)
|
||||
update_use_power(!use_power)
|
||||
|
||||
if(signal.data["panic_siphon"]) //must be before if("scrubbing") thing
|
||||
panic = text2num(signal.data["panic_siphon"])
|
||||
if(panic)
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
scrubbing = 0
|
||||
else
|
||||
scrubbing = 1
|
||||
if(signal.data["toggle_panic_siphon"] != null)
|
||||
panic = !panic
|
||||
if(panic)
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
scrubbing = 0
|
||||
else
|
||||
scrubbing = 1
|
||||
|
||||
if(signal.data["scrubbing"] != null)
|
||||
scrubbing = text2num(signal.data["scrubbing"])
|
||||
if(scrubbing)
|
||||
panic = 0
|
||||
if(signal.data["toggle_scrubbing"])
|
||||
scrubbing = !scrubbing
|
||||
if(scrubbing)
|
||||
panic = 0
|
||||
|
||||
var/list/toggle = list()
|
||||
|
||||
if(!isnull(signal.data["o2_scrub"]) && text2num(signal.data["o2_scrub"]) != (GAS_OXYGEN in scrubbing_gas))
|
||||
toggle += GAS_OXYGEN
|
||||
else if(signal.data["toggle_o2_scrub"])
|
||||
toggle += GAS_OXYGEN
|
||||
|
||||
if(!isnull(signal.data["n2_scrub"]) && text2num(signal.data["n2_scrub"]) != (GAS_NITROGEN in scrubbing_gas))
|
||||
toggle += GAS_NITROGEN
|
||||
else if(signal.data["toggle_n2_scrub"])
|
||||
toggle += GAS_NITROGEN
|
||||
|
||||
if(!isnull(signal.data["co2_scrub"]) && text2num(signal.data["co2_scrub"]) != (GAS_CO2 in scrubbing_gas))
|
||||
toggle += GAS_CO2
|
||||
else if(signal.data["toggle_co2_scrub"])
|
||||
toggle += GAS_CO2
|
||||
|
||||
if(!isnull(signal.data["tox_scrub"]) && text2num(signal.data["tox_scrub"]) != (GAS_PHORON in scrubbing_gas))
|
||||
toggle += GAS_PHORON
|
||||
else if(signal.data["toggle_tox_scrub"])
|
||||
toggle += GAS_PHORON
|
||||
|
||||
if(!isnull(signal.data["n2o_scrub"]) && text2num(signal.data["n2o_scrub"]) != (GAS_N2O in scrubbing_gas))
|
||||
toggle += GAS_N2O
|
||||
else if(signal.data["toggle_n2o_scrub"])
|
||||
toggle += GAS_N2O
|
||||
|
||||
if(!isnull(signal.data["h2_scrub"]) && text2num(signal.data["h2_scrub"]) != (GAS_HYDROGEN in scrubbing_gas))
|
||||
toggle += GAS_HYDROGEN
|
||||
else if(signal.data["toggle_h2_scrub"])
|
||||
toggle += GAS_HYDROGEN
|
||||
|
||||
scrubbing_gas ^= toggle
|
||||
|
||||
if(signal.data["init"] != null)
|
||||
name = signal.data["init"]
|
||||
return
|
||||
|
||||
if(signal.data["status"] != null)
|
||||
broadcast_status_next_process = TRUE
|
||||
return //do not update_icon
|
||||
|
||||
broadcast_status_next_process = TRUE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (W.iswrench())
|
||||
if (!(stat & NOPOWER) && use_power)
|
||||
to_chat(user, SPAN_WARNING("You cannot unwrench \the [src], turn it off first."))
|
||||
return TRUE
|
||||
var/turf/T = src.loc
|
||||
if (node && node.level==1 && isturf(T) && !T.is_plating())
|
||||
to_chat(user, SPAN_WARNING("You must remove the plating first."))
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, SPAN_WARNING("You cannot unwrench \the [src], it is too exerted due to internal pressure."))
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, SPAN_NOTICE("You begin to unfasten \the [src]..."))
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
SPAN_NOTICE("\The [user] unfastens \the [src]."), \
|
||||
SPAN_NOTICE("You have unfastened \the [src]."), \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
if(W.iswelder())
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if (!WT.welding)
|
||||
to_chat(user, SPAN_DANGER("\The [WT] must be turned on!"))
|
||||
else if (WT.remove_fuel(0,user))
|
||||
to_chat(user, SPAN_NOTICE("Now welding \the [src]."))
|
||||
playsound(src, 'sound/items/welder.ogg', 50, 1)
|
||||
if(do_after(user, 20/W.toolspeed, act_target = src))
|
||||
if(!src || !WT.isOn())
|
||||
return TRUE
|
||||
welded = !welded
|
||||
update_icon()
|
||||
playsound(src, 'sound/items/welder_pry.ogg', 50, 1)
|
||||
user.visible_message(SPAN_NOTICE("\The [user] [welded ? "welds \the [src] shut" : "unwelds \the [src]"]."), \
|
||||
SPAN_NOTICE("You [welded ? "weld \the [src] shut" : "unweld \the [src]"]."), \
|
||||
"You hear welding.")
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("You fail to complete the welding."))
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("You need more welding fuel to complete this task."))
|
||||
return TRUE
|
||||
|
||||
if(istype(W, /obj/item/melee/arm_blade))
|
||||
if(!welded)
|
||||
to_chat(user, SPAN_WARNING("\The [W] can only be used to tear open welded scrubbers!"))
|
||||
return TRUE
|
||||
user.visible_message(SPAN_WARNING("\The [user] starts using \the [W] to hack open \the [src]!"), SPAN_NOTICE("You start hacking open \the [src] with \the [W]..."))
|
||||
user.do_attack_animation(src, W)
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 60, TRUE)
|
||||
var/cut_amount = 3
|
||||
for(var/i = 0; i <= cut_amount; i++)
|
||||
if(!W || !do_after(user, 30, src))
|
||||
return TRUE
|
||||
user.do_attack_animation(src, W)
|
||||
user.visible_message(SPAN_WARNING("\The [user] smashes \the [W] into \the [src]!"), SPAN_NOTICE("You smash \the [W] into \the [src]."))
|
||||
playsound(loc, 'sound/weapons/smash.ogg', 60, TRUE)
|
||||
if(i == cut_amount)
|
||||
welded = FALSE
|
||||
spark(get_turf(src), 3, alldirs)
|
||||
playsound(loc, 'sound/items/welder_pry.ogg', 50, TRUE)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
to_chat(user, "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W")
|
||||
else
|
||||
to_chat(user, "You are too far away to read the gauge.")
|
||||
if(welded)
|
||||
to_chat(user, "It seems welded shut.")
|
||||
@@ -0,0 +1,329 @@
|
||||
/obj/machinery/atmospherics/valve
|
||||
name = "manual valve"
|
||||
desc = "A pipe valve."
|
||||
desc_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
|
||||
icon = 'icons/atmos/valve.dmi'
|
||||
icon_state = "map_valve0"
|
||||
|
||||
level = 1
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH|NORTH
|
||||
|
||||
var/open = 0
|
||||
var/openDuringInit = 0
|
||||
|
||||
var/datum/pipe_network/network_node1
|
||||
var/datum/pipe_network/network_node2
|
||||
|
||||
/obj/machinery/atmospherics/valve/open
|
||||
open = 1
|
||||
icon_state = "map_valve1"
|
||||
|
||||
/obj/machinery/atmospherics/valve/update_icon(animation)
|
||||
if(animation)
|
||||
flick("valve[src.open][!src.open]",src)
|
||||
else
|
||||
icon_state = "valve[open]"
|
||||
|
||||
/obj/machinery/atmospherics/valve/update_underlays()
|
||||
if(..())
|
||||
underlays.Cut()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
add_underlay(T, node1, get_dir(src, node1))
|
||||
add_underlay(T, node2, get_dir(src, node2))
|
||||
|
||||
/obj/machinery/atmospherics/valve/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/valve/Initialize()
|
||||
switch(dir)
|
||||
if(NORTH || SOUTH)
|
||||
initialize_directions = NORTH|SOUTH
|
||||
if(EAST || WEST)
|
||||
initialize_directions = EAST|WEST
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/valve/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
if(reference == node1)
|
||||
network_node1 = new_network
|
||||
if(open)
|
||||
network_node2 = new_network
|
||||
else if(reference == node2)
|
||||
network_node2 = new_network
|
||||
if(open)
|
||||
network_node1 = new_network
|
||||
|
||||
if(new_network.normal_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.normal_members += src
|
||||
|
||||
if(open)
|
||||
if(reference == node1)
|
||||
if(node2)
|
||||
return node2.network_expand(new_network, src)
|
||||
else if(reference == node2)
|
||||
if(node1)
|
||||
return node1.network_expand(new_network, src)
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/valve/Destroy()
|
||||
loc = null
|
||||
|
||||
if(node1)
|
||||
node1.disconnect(src)
|
||||
qdel(network_node1)
|
||||
if(node2)
|
||||
node2.disconnect(src)
|
||||
qdel(network_node2)
|
||||
|
||||
node1 = null
|
||||
node2 = null
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/valve/proc/open()
|
||||
if(open) return 0
|
||||
|
||||
open = 1
|
||||
update_icon()
|
||||
|
||||
if(network_node1&&network_node2)
|
||||
network_node1.merge(network_node2)
|
||||
network_node2 = network_node1
|
||||
|
||||
if(network_node1)
|
||||
network_node1.update = 1
|
||||
else if(network_node2)
|
||||
network_node2.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/valve/proc/close()
|
||||
if(!open)
|
||||
return 0
|
||||
|
||||
open = 0
|
||||
update_icon()
|
||||
|
||||
if(network_node1)
|
||||
qdel(network_node1)
|
||||
if(network_node2)
|
||||
qdel(network_node2)
|
||||
|
||||
build_network()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/valve/proc/normalize_dir()
|
||||
if(dir==3)
|
||||
set_dir(1)
|
||||
else if(dir==12)
|
||||
set_dir(4)
|
||||
|
||||
/obj/machinery/atmospherics/valve/attack_ai(mob/user as mob)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/valve/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(usr)
|
||||
update_icon(1)
|
||||
sleep(10)
|
||||
if (src.open)
|
||||
src.close()
|
||||
else
|
||||
src.open()
|
||||
|
||||
/obj/machinery/atmospherics/valve/process()
|
||||
..()
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/atmospherics/valve/atmos_init()
|
||||
normalize_dir()
|
||||
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_directions)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node1 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node2_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
if (check_connect_types(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
build_network()
|
||||
|
||||
queue_icon_update()
|
||||
update_underlays()
|
||||
|
||||
if(openDuringInit)
|
||||
close()
|
||||
open()
|
||||
openDuringInit = 0
|
||||
|
||||
/obj/machinery/atmospherics/valve/build_network()
|
||||
if(!network_node1 && node1)
|
||||
network_node1 = new /datum/pipe_network()
|
||||
network_node1.normal_members += src
|
||||
network_node1.build_network(node1, src)
|
||||
|
||||
if(!network_node2 && node2)
|
||||
network_node2 = new /datum/pipe_network()
|
||||
network_node2.normal_members += src
|
||||
network_node2.build_network(node2, src)
|
||||
|
||||
/obj/machinery/atmospherics/valve/return_network(obj/machinery/atmospherics/reference)
|
||||
build_network()
|
||||
|
||||
if(reference==node1)
|
||||
return network_node1
|
||||
|
||||
if(reference==node2)
|
||||
return network_node2
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/valve/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network)
|
||||
if(network_node1 == old_network)
|
||||
network_node1 = new_network
|
||||
if(network_node2 == old_network)
|
||||
network_node2 = new_network
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/valve/return_network_air(datum/pipe_network/reference)
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/valve/disconnect(obj/machinery/atmospherics/reference)
|
||||
if(reference==node1)
|
||||
qdel(network_node1)
|
||||
node1 = null
|
||||
|
||||
else if(reference==node2)
|
||||
qdel(network_node2)
|
||||
node2 = null
|
||||
|
||||
update_underlays()
|
||||
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital // can be controlled by AI
|
||||
name = "digital valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon = 'icons/atmos/digital_valve.dmi'
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/attack_ai(mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/attack_hand(mob/user as mob)
|
||||
if(!powered())
|
||||
return
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
log_and_message_admins("has [open ? "<span class='warning'>OPENED</span>" : "closed"] [name].", user)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/AltClick(var/mob/abstract/observer/admin)
|
||||
if (istype(admin))
|
||||
if (admin.client && admin.client.holder && ((R_MOD|R_ADMIN) & admin.client.holder.rights))
|
||||
if (open)
|
||||
close()
|
||||
else
|
||||
if (alert(admin, "The valve is currently closed. Do you want to open it?", "Open the valve?", "Yes", "No") == "No")
|
||||
return
|
||||
open()
|
||||
|
||||
log_and_message_admins("has [open ? "opened" : "closed"] [name].", admin)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/open
|
||||
open = 1
|
||||
icon_state = "map_valve1"
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/update_icon()
|
||||
..()
|
||||
if(!powered())
|
||||
icon_state = "valve[open]nopower"
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/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/valve/digital/atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/machinery/atmospherics/valve/digital/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id))
|
||||
return 0
|
||||
|
||||
switch(signal.data["command"])
|
||||
if("valve_open")
|
||||
if(!open)
|
||||
open()
|
||||
|
||||
if("valve_close")
|
||||
if(open)
|
||||
close()
|
||||
|
||||
if("valve_toggle")
|
||||
if(open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
|
||||
/obj/machinery/atmospherics/valve/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
||||
if (!W.iswrench())
|
||||
return ..()
|
||||
if (istype(src, /obj/machinery/atmospherics/valve/digital))
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it's too complicated.</span>")
|
||||
return TRUE
|
||||
var/datum/gas_mixture/int_air = return_air()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if ((int_air.return_pressure()-env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
playsound(src.loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if (do_after(user, 40/W.toolspeed, act_target = src))
|
||||
user.visible_message( \
|
||||
"<span class='notice'>\The [user] unfastens \the [src].</span>", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/valve/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "It is [open ? "open" : "closed"].")
|
||||
@@ -0,0 +1,91 @@
|
||||
/datum/pipe_network
|
||||
var/list/datum/gas_mixture/gases = list() //All of the gas_mixtures continuously connected in this network
|
||||
var/volume = 0 //caches the total volume for atmos machines to use in gas calculations
|
||||
|
||||
var/list/obj/machinery/atmospherics/normal_members = list()
|
||||
var/list/datum/pipeline/line_members = list()
|
||||
//membership roster to go through for updates and what not
|
||||
|
||||
var/update = 1
|
||||
//var/datum/gas_mixture/air_transient = null
|
||||
|
||||
/*
|
||||
/datum/pipe_network/New()
|
||||
//air_transient = new()
|
||||
|
||||
..()*/
|
||||
|
||||
/datum/pipe_network/process()
|
||||
//Equalize gases amongst pipe if called for
|
||||
if(update)
|
||||
update = 0
|
||||
reconcile_air() //equalize_gases(gases)
|
||||
|
||||
//Give pipelines their process call for pressure checking and what not. Have to remove pressure checks for the time being as pipes dont radiate heat - Mport
|
||||
//for(var/datum/pipeline/line_member in line_members)
|
||||
// line_member.process()
|
||||
|
||||
/datum/pipe_network/proc/build_network(obj/machinery/atmospherics/start_normal, obj/machinery/atmospherics/reference)
|
||||
//Purpose: Generate membership roster
|
||||
//Notes: Assuming that members will add themselves to appropriate roster in network_expand()
|
||||
|
||||
if(!start_normal)
|
||||
qdel(src)
|
||||
|
||||
start_normal.network_expand(src, reference)
|
||||
|
||||
update_network_gases()
|
||||
|
||||
if((normal_members.len>0)||(line_members.len>0))
|
||||
START_PROCESSING_PIPENET(src)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/datum/pipe_network/proc/merge(datum/pipe_network/giver)
|
||||
if(giver==src) return 0
|
||||
|
||||
normal_members |= giver.normal_members
|
||||
|
||||
line_members |= giver.line_members
|
||||
|
||||
for(var/obj/machinery/atmospherics/normal_member in giver.normal_members)
|
||||
normal_member.reassign_network(giver, src)
|
||||
|
||||
for(var/datum/pipeline/line_member in giver.line_members)
|
||||
line_member.network = src
|
||||
|
||||
update_network_gases()
|
||||
return 1
|
||||
|
||||
/datum/pipe_network/proc/update_network_gases()
|
||||
//Go through membership roster and make sure gases is up to date
|
||||
|
||||
gases = list()
|
||||
volume = 0
|
||||
|
||||
for(var/obj/machinery/atmospherics/normal_member in normal_members)
|
||||
var/result = normal_member.return_network_air(src)
|
||||
if(result) gases += result
|
||||
|
||||
for(var/datum/pipeline/line_member in line_members)
|
||||
gases += line_member.air
|
||||
|
||||
for(var/datum/gas_mixture/air in gases)
|
||||
volume += air.volume
|
||||
|
||||
/datum/pipe_network/proc/reconcile_air()
|
||||
equalize_gases(gases)
|
||||
|
||||
/datum/pipe_network/Destroy(force = FALSE)
|
||||
STOP_PROCESSING_PIPENET(src)
|
||||
for (var/datum/pipeline/pipeline in line_members)
|
||||
pipeline.network = null
|
||||
|
||||
line_members = null
|
||||
|
||||
for (var/obj/machinery/atmospherics/thing in normal_members)
|
||||
thing.reassign_network(src, null)
|
||||
|
||||
normal_members = null
|
||||
|
||||
return ..()
|
||||
@@ -0,0 +1,220 @@
|
||||
|
||||
/datum/pipeline
|
||||
var/datum/gas_mixture/air
|
||||
|
||||
var/list/obj/machinery/atmospherics/pipe/members
|
||||
var/list/obj/machinery/atmospherics/pipe/edges //Used for building networks
|
||||
|
||||
var/datum/pipe_network/network
|
||||
|
||||
var/alert_pressure = 0
|
||||
|
||||
/datum/pipeline/Destroy()
|
||||
if(network)
|
||||
QDEL_NULL(network)
|
||||
|
||||
if(air && air.volume)
|
||||
temporarily_store_air()
|
||||
QDEL_NULL(air)
|
||||
|
||||
for (var/obj/machinery/atmospherics/pipe/thing in members)
|
||||
thing.parent = null
|
||||
|
||||
members = null
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/pipeline/process()//This use to be called called from the pipe networks
|
||||
//Check to see if pressure is within acceptable limits
|
||||
var/pressure = air.return_pressure()
|
||||
if(pressure > alert_pressure)
|
||||
for(var/obj/machinery/atmospherics/pipe/member in members)
|
||||
if(!member.check_pressure(pressure))
|
||||
break //Only delete 1 pipe per process
|
||||
|
||||
/datum/pipeline/proc/temporarily_store_air()
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/member in members)
|
||||
member.air_temporary = new
|
||||
member.air_temporary.copy_from(air)
|
||||
member.air_temporary.volume = member.volume
|
||||
member.air_temporary.multiply(member.volume / air.volume)
|
||||
|
||||
/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/pipe/base)
|
||||
air = new
|
||||
|
||||
var/list/possible_expansions = list(base)
|
||||
members = list(base)
|
||||
edges = list()
|
||||
|
||||
var/volume = base.volume
|
||||
base.parent = src
|
||||
alert_pressure = base.alert_pressure
|
||||
|
||||
if(base.air_temporary)
|
||||
air = base.air_temporary
|
||||
base.air_temporary = null
|
||||
else
|
||||
air = new
|
||||
|
||||
while(possible_expansions.len>0)
|
||||
for(var/obj/machinery/atmospherics/pipe/borderline in possible_expansions)
|
||||
|
||||
var/list/result = borderline.pipeline_expansion()
|
||||
var/edge_check = result.len
|
||||
|
||||
if(result.len>0)
|
||||
for(var/obj/machinery/atmospherics/pipe/item in result)
|
||||
if(!members.Find(item))
|
||||
members += item
|
||||
possible_expansions += item
|
||||
|
||||
volume += item.volume
|
||||
item.parent = src
|
||||
|
||||
alert_pressure = min(alert_pressure, item.alert_pressure)
|
||||
|
||||
if(item.air_temporary)
|
||||
air.merge(item.air_temporary)
|
||||
|
||||
edge_check--
|
||||
|
||||
if(edge_check>0)
|
||||
edges += borderline
|
||||
|
||||
possible_expansions -= borderline
|
||||
|
||||
air.volume = volume
|
||||
|
||||
/datum/pipeline/proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
|
||||
|
||||
if(new_network.line_members.Find(src))
|
||||
return 0
|
||||
|
||||
new_network.line_members += src
|
||||
|
||||
network = new_network
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/edge in edges)
|
||||
for(var/obj/machinery/atmospherics/result in edge.pipeline_expansion())
|
||||
if(!istype(result,/obj/machinery/atmospherics/pipe) && (result!=reference))
|
||||
result.network_expand(new_network, edge)
|
||||
|
||||
return 1
|
||||
|
||||
/datum/pipeline/proc/return_network(obj/machinery/atmospherics/reference)
|
||||
if(!network)
|
||||
network = new /datum/pipe_network
|
||||
network.build_network(src, null)
|
||||
//technically passing these parameters should not be allowed
|
||||
//however pipe_network.build_network(..) and pipeline.network_extend(...)
|
||||
// were setup to properly handle this case
|
||||
|
||||
return network
|
||||
|
||||
/datum/pipeline/proc/mingle_with_turf(turf/simulated/target, mingle_volume)
|
||||
var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume)
|
||||
air_sample.volume = mingle_volume
|
||||
|
||||
if(istype(target) && target.zone)
|
||||
//Have to consider preservation of group statuses
|
||||
var/datum/gas_mixture/turf_copy = new
|
||||
|
||||
turf_copy.copy_from(target.zone.air)
|
||||
turf_copy.volume = target.zone.air.volume //Copy a good representation of the turf from parent group
|
||||
|
||||
equalize_gases(list(air_sample, turf_copy))
|
||||
air.merge(air_sample)
|
||||
|
||||
turf_copy.subtract(target.zone.air)
|
||||
|
||||
target.zone.air.merge(turf_copy)
|
||||
|
||||
else
|
||||
var/datum/gas_mixture/turf_air = target.return_air()
|
||||
|
||||
equalize_gases(list(air_sample, turf_air))
|
||||
air.merge(air_sample)
|
||||
//turf_air already modified by equalize_gases()
|
||||
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
|
||||
var/total_heat_capacity = air.heat_capacity()
|
||||
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
|
||||
|
||||
if(istype(target, /turf/simulated))
|
||||
var/turf/simulated/modeled_location = target
|
||||
|
||||
if(modeled_location.blocks_air)
|
||||
|
||||
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
var/delta_temperature = air.temperature - modeled_location.temperature
|
||||
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(partial_heat_capacity*modeled_location.heat_capacity/(partial_heat_capacity+modeled_location.heat_capacity))
|
||||
|
||||
air.temperature -= heat/total_heat_capacity
|
||||
modeled_location.temperature += heat/modeled_location.heat_capacity
|
||||
|
||||
else
|
||||
var/delta_temperature = 0
|
||||
var/sharer_heat_capacity = 0
|
||||
|
||||
if(modeled_location.zone)
|
||||
delta_temperature = (air.temperature - modeled_location.zone.air.temperature)
|
||||
sharer_heat_capacity = modeled_location.zone.air.heat_capacity()
|
||||
else
|
||||
delta_temperature = (air.temperature - modeled_location.air.temperature)
|
||||
sharer_heat_capacity = modeled_location.air.heat_capacity()
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/total_heat_capacity
|
||||
sharer_temperature_delta = heat/sharer_heat_capacity
|
||||
else
|
||||
return 1
|
||||
|
||||
air.temperature += self_temperature_delta
|
||||
|
||||
if(modeled_location.zone)
|
||||
modeled_location.zone.air.temperature += sharer_temperature_delta/modeled_location.zone.air.group_multiplier
|
||||
else
|
||||
modeled_location.air.temperature += sharer_temperature_delta
|
||||
|
||||
|
||||
else
|
||||
if((target.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
var/delta_temperature = air.temperature - target.temperature
|
||||
|
||||
var/heat = thermal_conductivity*delta_temperature* \
|
||||
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
|
||||
|
||||
air.temperature -= heat/total_heat_capacity
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
//surface must be the surface area in m^2
|
||||
/datum/pipeline/proc/radiate_heat_to_space(surface, thermal_conductivity)
|
||||
var/gas_density = air.total_moles/air.volume
|
||||
thermal_conductivity *= min(gas_density / ( RADIATOR_OPTIMUM_PRESSURE/(R_IDEAL_GAS_EQUATION*GAS_CRITICAL_TEMPERATURE) ), 1) //mult by density ratio
|
||||
|
||||
// We only get heat from the star on the exposed surface area.
|
||||
// If the HE pipes gain more energy from AVERAGE_SOLAR_RADIATION than they can radiate, then they have a net heat increase.
|
||||
var/heat_gain = AVERAGE_SOLAR_RADIATION * (RADIATOR_EXPOSED_SURFACE_AREA_RATIO * surface) * thermal_conductivity
|
||||
|
||||
// Previously, the temperature would enter equilibrium at 26C or 294K.
|
||||
// Only would happen if both sides (all 2 square meters of surface area) were exposed to sunlight. We now assume it aligned edge on.
|
||||
// It currently should stabilise at 129.6K or -143.6C
|
||||
heat_gain -= surface * STEFAN_BOLTZMANN_CONSTANT * thermal_conductivity * (air.temperature - COSMIC_RADIATION_TEMPERATURE) ** 4
|
||||
|
||||
air.add_thermal_energy(heat_gain)
|
||||
if(network)
|
||||
network.update = 1
|
||||
@@ -0,0 +1,156 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
|
||||
desc_info = "This radiates heat from the pipe's gas to space, cooling it down."
|
||||
icon = 'icons/atmos/heat.dmi'
|
||||
icon_state = "intact"
|
||||
pipe_icon = "hepipe"
|
||||
color = "#404040"
|
||||
level = 2
|
||||
connect_types = CONNECT_TYPE_HE
|
||||
layer = 2.41
|
||||
var/initialize_directions_he
|
||||
var/surface = 2 //surface area in m^2
|
||||
var/icon_temperature = T20C //stop small changes in temperature causing an icon refresh
|
||||
appearance_flags = KEEP_TOGETHER
|
||||
|
||||
minimum_temperature_difference = 20
|
||||
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
|
||||
|
||||
buckle_lying = 1
|
||||
|
||||
volume = ATMOS_DEFAULT_VOLUME_HE_PIPE
|
||||
|
||||
// BubbleWrap
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/Initialize()
|
||||
. = ..()
|
||||
initialize_directions_he = initialize_directions // The auto-detection from /pipe is good enough for a simple HE pipe
|
||||
// BubbleWrap END
|
||||
color = "#404040" //we don't make use of the fancy overlay system for colours, use this to set the default.
|
||||
add_filter("glow", 1, list(type="drop_shadow", x = 0, y = 0, offset = 0, size = 4))
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init()
|
||||
normalize_dir()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_directions_he)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir))
|
||||
if(target.initialize_directions_he & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node2_dir))
|
||||
if(target.initialize_directions_he & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
if(!node1 && !node2)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process()
|
||||
if(!parent)
|
||||
..()
|
||||
else
|
||||
var/datum/gas_mixture/pipe_air = return_air()
|
||||
if(istype(loc, /turf/simulated/))
|
||||
var/environment_temperature = 0
|
||||
if(loc:blocks_air)
|
||||
environment_temperature = loc:temperature
|
||||
else
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
environment_temperature = environment.temperature
|
||||
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
|
||||
parent.temperature_interact(loc, volume, thermal_conductivity)
|
||||
else if(istype(loc, /turf/space/))
|
||||
parent.radiate_heat_to_space(surface, 1)
|
||||
|
||||
if(istype(buckled, /mob/living))
|
||||
var/mob/living/M = buckled
|
||||
var/hc = pipe_air.heat_capacity()
|
||||
var/avg_temp = (pipe_air.temperature * hc + M.bodytemperature * 3500) / (hc + 3500)
|
||||
pipe_air.temperature = avg_temp
|
||||
M.bodytemperature = avg_temp
|
||||
|
||||
var/heat_limit = 1000
|
||||
|
||||
var/mob/living/carbon/human/H = buckled
|
||||
if(istype(H) && H.species)
|
||||
heat_limit = H.species.heat_level_3
|
||||
|
||||
if(pipe_air.temperature > heat_limit + 1)
|
||||
M.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, BP_CHEST, used_weapon = "Excessive Heat")
|
||||
|
||||
//fancy radiation glowing
|
||||
if(pipe_air.temperature && (icon_temperature > 500 || pipe_air.temperature > 500)) //start glowing at 500K
|
||||
if(abs(pipe_air.temperature - icon_temperature) > 10)
|
||||
icon_temperature = pipe_air.temperature
|
||||
var/scale = max((icon_temperature - 500) / 1500, 0)
|
||||
|
||||
var/h_r = heat2color_r(icon_temperature)
|
||||
var/h_g = heat2color_g(icon_temperature)
|
||||
var/h_b = heat2color_b(icon_temperature)
|
||||
|
||||
if(icon_temperature < 2000) //scale up overlay until 2000K
|
||||
h_r = 64 + (h_r - 64)*scale
|
||||
h_g = 64 + (h_g - 64)*scale
|
||||
h_b = 64 + (h_b - 64)*scale
|
||||
var/scale_color = rgb(h_r, h_g, h_b)
|
||||
var/list/animate_targets = get_above_oo() + src
|
||||
for (var/thing in animate_targets)
|
||||
var/atom/movable/AM = thing
|
||||
animate(AM, color = scale_color, time = 2 SECONDS, easing = SINE_EASING)
|
||||
animate_filter("glow", list(color = scale_color, time = 2 SECONDS, easing = LINEAR_EASING))
|
||||
set_light(min(3, scale*2.5), min(3, scale*2.5), scale_color)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
|
||||
icon = 'icons/atmos/junction.dmi'
|
||||
icon_state = "intact"
|
||||
pipe_icon = "hejunction"
|
||||
level = 2
|
||||
connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_HE
|
||||
minimum_temperature_difference = 300
|
||||
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
|
||||
|
||||
// BubbleWrap
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/Initialize()
|
||||
. = ..()
|
||||
switch (dir)
|
||||
if (SOUTH)
|
||||
initialize_directions = NORTH
|
||||
initialize_directions_he = SOUTH
|
||||
if (NORTH)
|
||||
initialize_directions = SOUTH
|
||||
initialize_directions_he = NORTH
|
||||
if (EAST)
|
||||
initialize_directions = WEST
|
||||
initialize_directions_he = EAST
|
||||
if (WEST)
|
||||
initialize_directions = EAST
|
||||
initialize_directions_he = WEST
|
||||
// BubbleWrap END
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/atmos_init()
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,initialize_directions))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node1 = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,initialize_directions_he))
|
||||
if(target.initialize_directions_he & get_dir(target,src))
|
||||
node2 = target
|
||||
break
|
||||
|
||||
if(!node1 && !node2)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
queue_icon_update()
|
||||
@@ -0,0 +1,706 @@
|
||||
// internal pipe, don't actually place or use these
|
||||
obj/machinery/atmospherics/pipe/mains_component
|
||||
var/obj/machinery/atmospherics/mains_pipe/parent_pipe
|
||||
var/list/obj/machinery/atmospherics/pipe/mains_component/nodes = new()
|
||||
|
||||
New(loc)
|
||||
..(loc)
|
||||
parent_pipe = loc
|
||||
|
||||
check_pressure(pressure)
|
||||
var/datum/gas_mixture/environment = loc.loc.return_air()
|
||||
|
||||
var/pressure_difference = pressure - environment.return_pressure()
|
||||
|
||||
if(pressure_difference > parent_pipe.maximum_pressure)
|
||||
mains_burst()
|
||||
|
||||
else if(pressure_difference > parent_pipe.fatigue_pressure)
|
||||
//TODO: leak to turf, doing pfshhhhh
|
||||
if(prob(5))
|
||||
mains_burst()
|
||||
|
||||
else return 1
|
||||
|
||||
pipeline_expansion()
|
||||
return nodes
|
||||
|
||||
disconnect(obj/machinery/atmospherics/reference)
|
||||
if(nodes.Find(reference))
|
||||
nodes.Remove(reference)
|
||||
|
||||
proc/mains_burst()
|
||||
parent_pipe.burst()
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe
|
||||
icon = 'icons/obj/atmospherics/mainspipe.dmi'
|
||||
layer = 2.4 //under wires with their 2.5
|
||||
|
||||
force = 20
|
||||
|
||||
var/volume = 0
|
||||
|
||||
var/alert_pressure = 80*ONE_ATMOSPHERE
|
||||
|
||||
var/initialize_mains_directions = 0
|
||||
|
||||
var/list/obj/machinery/atmospherics/mains_pipe/nodes = new()
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/supply
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/scrubbers
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/aux
|
||||
|
||||
var/minimum_temperature_difference = 300
|
||||
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
|
||||
|
||||
var/maximum_pressure = 70*ONE_ATMOSPHERE
|
||||
var/fatigue_pressure = 55*ONE_ATMOSPHERE
|
||||
alert_pressure = 55*ONE_ATMOSPHERE
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
supply = new(src)
|
||||
supply.volume = volume
|
||||
supply.nodes.len = nodes.len
|
||||
scrubbers = new(src)
|
||||
scrubbers.volume = volume
|
||||
scrubbers.nodes.len = nodes.len
|
||||
aux = new(src)
|
||||
aux.volume = volume
|
||||
aux.nodes.len = nodes.len
|
||||
|
||||
hide(var/i)
|
||||
if(level == 1 && istype(loc, /turf/simulated))
|
||||
invisibility = i ? 101 : 0
|
||||
update_icon()
|
||||
|
||||
proc/burst()
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/pipe in contents)
|
||||
burst()
|
||||
|
||||
proc/check_pressure(pressure)
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
var/pressure_difference = pressure - environment.return_pressure()
|
||||
|
||||
if(pressure_difference > maximum_pressure)
|
||||
burst()
|
||||
|
||||
else if(pressure_difference > fatigue_pressure)
|
||||
//TODO: leak to turf, doing pfshhhhh
|
||||
if(prob(5))
|
||||
burst()
|
||||
|
||||
else return 1
|
||||
|
||||
disconnect()
|
||||
..()
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/node in nodes)
|
||||
node.disconnect()
|
||||
|
||||
Destroy()
|
||||
disconnect()
|
||||
return ..()
|
||||
|
||||
atmos_init()
|
||||
for(var/i = 1 to nodes.len)
|
||||
var/obj/machinery/atmospherics/mains_pipe/node = nodes[i]
|
||||
if(node)
|
||||
supply.nodes[i] = node.supply
|
||||
scrubbers.nodes[i] = node.scrubbers
|
||||
aux.nodes[i] = node.aux
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/simple
|
||||
name = "mains pipe"
|
||||
desc = "A one meter section of 3-line mains pipe"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
switch(dir)
|
||||
if(SOUTH || NORTH)
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
if(EAST || WEST)
|
||||
initialize_mains_directions = EAST|WEST
|
||||
if(NORTHEAST)
|
||||
initialize_mains_directions = NORTH|EAST
|
||||
if(NORTHWEST)
|
||||
initialize_mains_directions = NORTH|WEST
|
||||
if(SOUTHEAST)
|
||||
initialize_mains_directions = SOUTH|EAST
|
||||
if(SOUTHWEST)
|
||||
initialize_mains_directions = SOUTH|WEST
|
||||
|
||||
proc/normalize_dir()
|
||||
if(dir==3)
|
||||
set_dir(1)
|
||||
else if(dir==12)
|
||||
set_dir(4)
|
||||
|
||||
update_icon()
|
||||
if(nodes[1] && nodes[2])
|
||||
icon_state = "intact[invisibility ? "-f" : "" ]"
|
||||
|
||||
//var/node1_direction = get_dir(src, node1)
|
||||
//var/node2_direction = get_dir(src, node2)
|
||||
|
||||
//set_dir(node1_direction|node2_direction)
|
||||
|
||||
else
|
||||
if(!nodes[1]&&!nodes[2])
|
||||
qdel(src) //TODO: silent deleting looks weird
|
||||
var/have_node1 = nodes[1]?1:0
|
||||
var/have_node2 = nodes[2]?1:0
|
||||
icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]"
|
||||
|
||||
atmos_init()
|
||||
normalize_dir()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_mains_directions)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "intact-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "intact"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/manifold
|
||||
name = "manifold pipe"
|
||||
desc = "A manifold composed of mains pipes"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = EAST|NORTH|WEST
|
||||
volume = 105
|
||||
|
||||
New()
|
||||
nodes.len = 3
|
||||
..()
|
||||
initialize_mains_directions = (NORTH|SOUTH|EAST|WEST) & ~dir
|
||||
|
||||
atmos_init()
|
||||
var/connect_directions = initialize_mains_directions
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[1])
|
||||
break
|
||||
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[2])
|
||||
break
|
||||
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&connect_directions)
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,direction))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
connect_directions &= ~direction
|
||||
break
|
||||
if (nodes[3])
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "manifold[invisibility ? "-f" : "" ]"
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "manifold-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "manifold"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/manifold4w
|
||||
name = "manifold pipe"
|
||||
desc = "A manifold composed of mains pipes"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = EAST|NORTH|WEST|SOUTH
|
||||
volume = 105
|
||||
|
||||
New()
|
||||
nodes.len = 4
|
||||
..()
|
||||
|
||||
atmos_init()
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,NORTH))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,SOUTH))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,EAST))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,WEST))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[3] = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "manifold4w[invisibility ? "-f" : "" ]"
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "manifold4w-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "manifold4w"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/split
|
||||
name = "mains splitter"
|
||||
desc = "A splitter for connecting to a single pipe off a mains."
|
||||
|
||||
var/obj/machinery/atmospherics/pipe/mains_component/split_node
|
||||
var/obj/machinery/atmospherics/node3
|
||||
var/icon_type
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
initialize_mains_directions = turn(dir, 90) | turn(dir, -90)
|
||||
initialize_directions = dir // actually have a normal connection too
|
||||
|
||||
atmos_init()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
var/node3_dir
|
||||
|
||||
node1_dir = turn(dir, 90)
|
||||
node2_dir = turn(dir, -90)
|
||||
node3_dir = dir
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,node3_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node3 = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
// bind them
|
||||
spawn(5)
|
||||
if(node3 && split_node)
|
||||
var/datum/pipe_network/N1 = node3.return_network(src)
|
||||
var/datum/pipe_network/N2 = split_node.return_network(split_node)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "split-[icon_type][invisibility ? "-f" : "" ]"
|
||||
|
||||
return_network(A)
|
||||
return split_node.return_network(A)
|
||||
|
||||
supply
|
||||
icon_type = "supply"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = supply
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-supply-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-supply"
|
||||
|
||||
scrubbers
|
||||
icon_type = "scrubbers"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = scrubbers
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-scrubbers-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-scrubbers"
|
||||
|
||||
aux
|
||||
icon_type = "aux"
|
||||
|
||||
New()
|
||||
..()
|
||||
split_node = aux
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-aux-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-aux"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/split3
|
||||
name = "triple mains splitter"
|
||||
desc = "A splitter for connecting to the 3 pipes on a mainline."
|
||||
|
||||
var/obj/machinery/atmospherics/supply_node
|
||||
var/obj/machinery/atmospherics/scrubbers_node
|
||||
var/obj/machinery/atmospherics/aux_node
|
||||
|
||||
New()
|
||||
nodes.len = 1
|
||||
..()
|
||||
initialize_mains_directions = dir
|
||||
initialize_directions = cardinal & ~dir // actually have a normal connection too
|
||||
|
||||
atmos_init()
|
||||
var/node1_dir
|
||||
var/supply_node_dir
|
||||
var/scrubbers_node_dir
|
||||
var/aux_node_dir
|
||||
|
||||
node1_dir = dir
|
||||
aux_node_dir = turn(dir, 180)
|
||||
if(dir & (NORTH|SOUTH))
|
||||
supply_node_dir = EAST
|
||||
scrubbers_node_dir = WEST
|
||||
else
|
||||
supply_node_dir = SOUTH
|
||||
scrubbers_node_dir = NORTH
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src, node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,supply_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
supply_node = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,scrubbers_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
scrubbers_node = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src,aux_node_dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
aux_node = target
|
||||
break
|
||||
|
||||
..() // initialize internal pipes
|
||||
|
||||
// bind them
|
||||
spawn(5)
|
||||
if(supply_node)
|
||||
var/datum/pipe_network/N1 = supply_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = supply.return_network(supply)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
if(scrubbers_node)
|
||||
var/datum/pipe_network/N1 = scrubbers_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = scrubbers.return_network(scrubbers)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
if(aux_node)
|
||||
var/datum/pipe_network/N1 = aux_node.return_network(src)
|
||||
var/datum/pipe_network/N2 = aux.return_network(aux)
|
||||
if(N1 && N2)
|
||||
N1.merge(N2)
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
icon_state = "split-t[invisibility ? "-f" : "" ]"
|
||||
|
||||
return_network(obj/machinery/atmospherics/reference)
|
||||
var/obj/machinery/atmospherics/A
|
||||
|
||||
A = supply_node.return_network(reference)
|
||||
if(!A)
|
||||
A = scrubbers_node.return_network(reference)
|
||||
if(!A)
|
||||
A = aux_node.return_network(reference)
|
||||
|
||||
return A
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "split-t-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "split-t"
|
||||
|
||||
obj/machinery/atmospherics/mains_pipe/cap
|
||||
name = "pipe cap"
|
||||
desc = "A cap for the end of a mains pipe"
|
||||
|
||||
dir = SOUTH
|
||||
initialize_directions = SOUTH
|
||||
volume = 35
|
||||
|
||||
New()
|
||||
nodes.len = 1
|
||||
..()
|
||||
initialize_mains_directions = dir
|
||||
|
||||
update_icon()
|
||||
icon_state = "cap[invisibility ? "-f" : ""]"
|
||||
|
||||
atmos_init()
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
|
||||
..()
|
||||
|
||||
var/turf/T = src.loc // hide if turf is not intact
|
||||
if(level == 1 && !T.is_plating()) hide(1)
|
||||
update_icon()
|
||||
|
||||
hidden
|
||||
level = 1
|
||||
icon_state = "cap-f"
|
||||
|
||||
visible
|
||||
level = 2
|
||||
icon_state = "cap"
|
||||
|
||||
//TODO: Get Mains valves working!
|
||||
/*
|
||||
obj/machinery/atmospherics/mains_pipe/valve
|
||||
icon_state = "mvalve0"
|
||||
|
||||
name = "mains shutoff valve"
|
||||
desc = "A mains pipe valve"
|
||||
|
||||
var/open = 1
|
||||
|
||||
dir = SOUTH
|
||||
initialize_mains_directions = SOUTH|NORTH
|
||||
|
||||
New()
|
||||
nodes.len = 2
|
||||
..()
|
||||
initialize_mains_directions = dir | turn(dir, 180)
|
||||
|
||||
update_icon(animation)
|
||||
var/turf/simulated/floor = loc
|
||||
var/hide = istype(floor) ? floor.intact : 0
|
||||
level = 1
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/node in nodes)
|
||||
if(node.level == 2)
|
||||
hide = 0
|
||||
level = 2
|
||||
break
|
||||
|
||||
if(animation)
|
||||
flick("[hide?"h":""]mvalve[src.open][!src.open]",src)
|
||||
else
|
||||
icon_state = "[hide?"h":""]mvalve[open]"
|
||||
|
||||
atmos_init()
|
||||
normalize_dir()
|
||||
var/node1_dir
|
||||
var/node2_dir
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(direction&initialize_mains_directions)
|
||||
if (!node1_dir)
|
||||
node1_dir = direction
|
||||
else if (!node2_dir)
|
||||
node2_dir = direction
|
||||
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node1_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[1] = target
|
||||
break
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/target in get_step(src,node2_dir))
|
||||
if(target.initialize_mains_directions & get_dir(target,src))
|
||||
nodes[2] = target
|
||||
break
|
||||
|
||||
if(open)
|
||||
..() // initialize internal pipes
|
||||
|
||||
update_icon()
|
||||
|
||||
proc/normalize_dir()
|
||||
if(dir==3)
|
||||
set_dir(1)
|
||||
else if(dir==12)
|
||||
set_dir(4)
|
||||
|
||||
proc/open()
|
||||
if(open) return 0
|
||||
|
||||
open = 1
|
||||
update_icon()
|
||||
|
||||
atmos_init()
|
||||
|
||||
return 1
|
||||
|
||||
proc/close()
|
||||
if(!open) return 0
|
||||
|
||||
open = 0
|
||||
update_icon()
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/node in src)
|
||||
for(var/obj/machinery/atmospherics/pipe/mains_component/o in node.nodes)
|
||||
o.disconnect(node)
|
||||
o.build_network()
|
||||
|
||||
return 1
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return
|
||||
|
||||
attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(usr)
|
||||
update_icon(1)
|
||||
sleep(10)
|
||||
if (open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
|
||||
digital // can be controlled by AI
|
||||
name = "digital mains valve"
|
||||
desc = "A digitally controlled valve."
|
||||
icon_state = "dvalve0"
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(!src.allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
//Radio remote control
|
||||
|
||||
proc
|
||||
set_frequency(new_frequency)
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
if(frequency)
|
||||
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
|
||||
|
||||
var/frequency = 0
|
||||
var/id = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
atmos_init()
|
||||
..()
|
||||
if(frequency)
|
||||
set_frequency(frequency)
|
||||
|
||||
update_icon(animation)
|
||||
var/turf/simulated/floor = loc
|
||||
var/hide = istype(floor) ? floor.intact : 0
|
||||
level = 1
|
||||
for(var/obj/machinery/atmospherics/mains_pipe/node in nodes)
|
||||
if(node.level == 2)
|
||||
hide = 0
|
||||
level = 2
|
||||
break
|
||||
|
||||
if(animation)
|
||||
flick("[hide?"h":""]dvalve[src.open][!src.open]",src)
|
||||
else
|
||||
icon_state = "[hide?"h":""]dvalve[open]"
|
||||
|
||||
receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id))
|
||||
return 0
|
||||
|
||||
switch(signal.data["command"])
|
||||
if("valve_open")
|
||||
if(!open)
|
||||
open()
|
||||
|
||||
if("valve_close")
|
||||
if(open)
|
||||
close()
|
||||
|
||||
if("valve_toggle")
|
||||
if(open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
/obj/machinery/computer/artillerycontrol/machinery_process()
|
||||
/obj/machinery/computer/artillerycontrol/process()
|
||||
if(src.reload<180)
|
||||
src.reload++
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
/obj/machinery/gateway/centerstation
|
||||
density = 1
|
||||
icon_state = "offcenter"
|
||||
use_power = 1
|
||||
|
||||
//warping vars
|
||||
var/list/linked_gateways = list()
|
||||
@@ -56,7 +55,7 @@ obj/machinery/gateway/centerstation/process()
|
||||
return
|
||||
|
||||
if(active)
|
||||
use_power(5000)
|
||||
use_power_oneoff(5000)
|
||||
|
||||
|
||||
/obj/machinery/gateway/centerstation/proc/detect()
|
||||
@@ -129,7 +128,7 @@ obj/machinery/gateway/centerstation/process()
|
||||
if(dest)
|
||||
M.forceMove(dest.loc)
|
||||
M.set_dir(SOUTH)
|
||||
use_power(5000)
|
||||
use_power_oneoff(5000)
|
||||
return
|
||||
|
||||
|
||||
@@ -144,7 +143,7 @@ obj/machinery/gateway/centerstation/process()
|
||||
/obj/machinery/gateway/centeraway
|
||||
density = 1
|
||||
icon_state = "offcenter"
|
||||
use_power = 0
|
||||
use_power = POWER_USE_OFF
|
||||
var/calibrated = 1
|
||||
var/list/linked_gateways = list() //a list of the connected gateway chunks
|
||||
var/ready = 0
|
||||
|
||||
@@ -107,6 +107,7 @@ STOCK_ITEM_LARGE(dispenser, 2.5)
|
||||
var/type = pickweight(dispensers)
|
||||
var/obj/machinery/chemical_dispenser/CD = new type(L)
|
||||
CD.anchored = FALSE
|
||||
CD.update_use_power(POWER_USE_OFF)
|
||||
for (var/cart in CD.cartridges)
|
||||
if (prob(90))
|
||||
CD.cartridges -= cart
|
||||
@@ -145,4 +146,4 @@ STOCK_ITEM_LARGE(exosuit, 1.2) //A randomly generated exosuit in a very variable
|
||||
new /mob/living/heavy_vehicle/premade/random/extra(L)
|
||||
|
||||
STOCK_ITEM_LARGE(unusualcrate, 0.1) //Like from the unknown object random event
|
||||
new /obj/structure/closet/crate/loot(L)
|
||||
new /obj/structure/closet/crate/loot(L)
|
||||
|
||||
@@ -294,6 +294,7 @@ STOCK_ITEM_COMMON(charger, 2)
|
||||
var/newtype = pick(/obj/machinery/cell_charger, /obj/machinery/recharger)
|
||||
var/obj/machinery/ma = new newtype(L)
|
||||
ma.anchored = FALSE
|
||||
ma.update_use_power(POWER_USE_OFF)
|
||||
|
||||
STOCK_ITEM_COMMON(spacesuit, 2)
|
||||
new /obj/item/clothing/suit/space(L)
|
||||
@@ -525,4 +526,4 @@ STOCK_ITEM_COMMON(camera, 1)
|
||||
new /obj/item/device/camera_film(L)
|
||||
|
||||
STOCK_ITEM_COMMON(nothing, 0)
|
||||
// do nothing
|
||||
// do nothing
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
use_power = 0
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 5 // Power used when turned on, but not processing anything
|
||||
active_power_usage = 1000 // Power used when turned on and actively cooking something
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
return
|
||||
|
||||
stat ^= POWEROFF // Toggles power
|
||||
use_power = (stat & POWEROFF) ? 0 : 2 // If on, use active power, else use no power
|
||||
update_use_power(stat & POWEROFF ? POWER_USE_OFF : POWER_USE_ACTIVE)
|
||||
if(user)
|
||||
user.visible_message("[user] turns [src] [use_power ? "on" : "off"].", "You turn [use_power ? "on" : "off"] [src].")
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
@@ -317,7 +317,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/appliance/machinery_process()
|
||||
/obj/machinery/appliance/process()
|
||||
if (cooking_power > 0 && cooking)
|
||||
for (var/i in cooking_objs)
|
||||
do_cooking_tick(i)
|
||||
@@ -639,6 +639,6 @@
|
||||
if(isscanner(P))
|
||||
scan_rating += P.rating - 1
|
||||
|
||||
active_power_usage = initial(active_power_usage) - scan_rating * 25 // 25W less per tier
|
||||
change_power_consumption(initial(active_power_usage) - scan_rating * 25, POWER_USE_ACTIVE)
|
||||
heating_power = initial(heating_power) + cap_rating * 50 // + 50W per tier
|
||||
cooking_coeff = (1 + (scan_rating + cap_rating) / 20) // +20% per tier
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
set_temp = text2num(desired_temp) + T0C
|
||||
to_chat(user, SPAN_NOTICE("You set [src] to [round(set_temp-T0C)]C."))
|
||||
stat &= ~POWEROFF
|
||||
use_power = !(stat & POWEROFF) // will be updated again after heat_up
|
||||
update_use_power(stat & POWEROFF ? POWER_USE_OFF : POWER_USE_IDLE)
|
||||
if(wasoff != (stat & POWEROFF))
|
||||
activation_message(user)
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
@@ -121,7 +121,7 @@
|
||||
/obj/machinery/appliance/cooker/update_icon()
|
||||
overlays.Cut()
|
||||
var/image/light
|
||||
if (use_power == 2 && !stat)
|
||||
if (use_power == POWER_USE_ACTIVE && !stat)
|
||||
light = image(icon, "light_on")
|
||||
else
|
||||
light = image(icon, "light_off")
|
||||
@@ -129,7 +129,7 @@
|
||||
light.pixel_y = light_y
|
||||
overlays += light
|
||||
|
||||
/obj/machinery/appliance/cooker/machinery_process()
|
||||
/obj/machinery/appliance/cooker/process()
|
||||
var/datum/gas_mixture/loc_air = loc.return_air()
|
||||
if (stat || (use_power != 2)) // if we're not actively heating
|
||||
temperature -= min(loss, temperature - loc_air.temperature)
|
||||
@@ -160,15 +160,15 @@
|
||||
|
||||
/obj/machinery/appliance/cooker/proc/heat_up()
|
||||
if (temperature < set_temp)
|
||||
if (use_power == 1 && ((set_temp - temperature) > 5))
|
||||
if (use_power == POWER_USE_IDLE && ((set_temp - temperature) > 5))
|
||||
playsound(src, 'sound/machines/click.ogg', 20, 1)
|
||||
use_power = 2 //If we're heating we use the active power
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
update_icon()
|
||||
temperature += heating_power / resistance
|
||||
update_cooking_power()
|
||||
return TRUE
|
||||
if (use_power == 2)
|
||||
use_power = 1
|
||||
if (use_power == POWER_USE_ACTIVE)
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
playsound(src, 'sound/machines/click.ogg', 20, 1)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ fundamental differences
|
||||
..()
|
||||
stat |= POWEROFF
|
||||
playsound(src, 'sound/machines/click.ogg', 40, 1)
|
||||
use_power = 0
|
||||
update_use_power(POWER_USE_OFF)
|
||||
CI.reset()
|
||||
update_icon()
|
||||
|
||||
@@ -118,7 +118,7 @@ fundamental differences
|
||||
icon_state = off_icon
|
||||
|
||||
|
||||
/obj/machinery/appliance/mixer/machinery_process()
|
||||
/obj/machinery/appliance/mixer/process()
|
||||
if (!stat)
|
||||
for (var/i in cooking_objs)
|
||||
do_cooking_tick(i)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
//Set temperature of oil
|
||||
oil.set_temperature(temperature)
|
||||
|
||||
/obj/machinery/appliance/cooker/fryer/machinery_process()
|
||||
/obj/machinery/appliance/cooker/fryer/process()
|
||||
. = ..()
|
||||
//Set temperature of oil
|
||||
oil.set_temperature(temperature)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
var/gib_time = 40 // Time from starting until meat appears
|
||||
var/gib_throw_dir = WEST // Direction to spit meat and gibs in.
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 500
|
||||
|
||||
@@ -174,7 +173,7 @@
|
||||
if(!occupant)
|
||||
visible_message(SPAN_DANGER("You hear a loud metallic grinding sound."))
|
||||
return
|
||||
use_power(1000)
|
||||
use_power_oneoff(1000)
|
||||
visible_message(SPAN_DANGER("You hear a loud [occupant.isSynthetic() ? "metallic" : "squelchy"] grinding sound."))
|
||||
operating = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
icon_state = "icecream_vat"
|
||||
density = 1
|
||||
anchored = 0
|
||||
use_power = 0
|
||||
use_power = POWER_USE_OFF
|
||||
flags = OPENCONTAINER | NOREACT
|
||||
|
||||
var/list/product_types = list()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
layer = 2.9
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
flags = NOREACT
|
||||
@@ -194,7 +193,7 @@
|
||||
if (S.dried_type)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/machinery_process()
|
||||
/obj/machinery/smartfridge/drying_rack/process()
|
||||
..()
|
||||
if(length(contents))
|
||||
dry()
|
||||
@@ -209,7 +208,7 @@
|
||||
SSvueui.check_uis_for_change(src)
|
||||
return
|
||||
|
||||
/obj/machinery/smartfridge/machinery_process()
|
||||
/obj/machinery/smartfridge/process()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
seconds_electrified = 0
|
||||
return
|
||||
@@ -234,7 +233,7 @@
|
||||
else if (mod == -1) //GOING DOWN
|
||||
thermal_energy_change = max(-active_power_usage,I.reagents.get_thermal_energy_change(r_temperature,cooling_temperature))
|
||||
I.reagents.add_thermal_energy(thermal_energy_change)
|
||||
use_power(active_power_usage)
|
||||
use_power_oneoff(active_power_usage)
|
||||
|
||||
/obj/machinery/smartfridge/power_change()
|
||||
..()
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/dnaforensics/machinery_process()
|
||||
/obj/machinery/dnaforensics/process()
|
||||
if(scanning)
|
||||
if(!bloodsamp || bloodsamp.loc != src)
|
||||
bloodsamp = null
|
||||
|
||||
@@ -20,7 +20,6 @@ log transactions
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "atm"
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
var/datum/money_account/authenticated_account
|
||||
var/number_incorrect_tries = 0
|
||||
@@ -64,7 +63,7 @@ log transactions
|
||||
var/mutable_appearance/card_overlay = mutable_appearance(icon, "atm-cardin", EFFECTS_ABOVE_LIGHTING_LAYER)
|
||||
add_overlay(card_overlay)
|
||||
|
||||
/obj/machinery/atm/machinery_process()
|
||||
/obj/machinery/atm/process()
|
||||
if(stat & NOPOWER)
|
||||
cut_overlays()
|
||||
set_light(FALSE)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "kitchenterminal"
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
var/machine_id = ""
|
||||
var/list/items = list()
|
||||
@@ -39,7 +38,7 @@
|
||||
add_overlay(screen_overlay)
|
||||
set_light(1.4, 1, COLOR_CYAN)
|
||||
|
||||
/obj/machinery/orderterminal/machinery_process()
|
||||
/obj/machinery/orderterminal/process()
|
||||
if(stat & NOPOWER)
|
||||
cut_overlays()
|
||||
set_light(FALSE)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
|
||||
/datum/event/brand_intelligence/start()
|
||||
for(var/obj/machinery/vending/V in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/vending/V in SSmachinery.processing)
|
||||
if(isNotStationLevel(V.z)) continue
|
||||
vendingMachines.Add(V)
|
||||
|
||||
@@ -52,4 +52,4 @@
|
||||
/datum/event/brand_intelligence/end(var/faked)
|
||||
for(var/obj/machinery/vending/infectedMachine in infectedVendingMachines)
|
||||
infectedMachine.shut_up = 1
|
||||
infectedMachine.shoot_inventory = 0
|
||||
infectedMachine.shoot_inventory = 0
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
/datum/event/electrical_storm/start()
|
||||
..()
|
||||
valid_apcs = list()
|
||||
for(var/obj/machinery/power/apc/A in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/power/apc/A in SSmachinery.machinery)
|
||||
if(A.z in affecting_z)
|
||||
valid_apcs.Add(A)
|
||||
endWhen = (severity * 60) + startWhen
|
||||
@@ -29,7 +29,7 @@
|
||||
/datum/event/electrical_storm/start()
|
||||
..()
|
||||
valid_apcs = list()
|
||||
for(var/obj/machinery/power/apc/A in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/power/apc/A in SSmachinery.machinery)
|
||||
if(A.z in affecting_z)
|
||||
valid_apcs.Add(A)
|
||||
endWhen = (severity * 60) + startWhen
|
||||
@@ -71,4 +71,4 @@
|
||||
for (var/zlevel in affecting_z)
|
||||
if(zlevel in current_map.station_levels)
|
||||
command_announcement.Announce("The [location_name()] has cleared the electrical storm. Please repair any electrical overloads.", "Electrical Storm Alert")
|
||||
break
|
||||
break
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
/datum/event/ionstorm/tick()
|
||||
if(botEmagChance)
|
||||
for(var/obj/machinery/bot/bot in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/bot/bot in SSmachinery.machinery)
|
||||
if(prob(botEmagChance))
|
||||
bot.emag_act(1)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
Notifications will be sent as updates occur.<br>"
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing)
|
||||
if(!MS.active) continue
|
||||
MS.send_rc_message("Executive Officer's Desk", my_department, message, "", "", 2)
|
||||
|
||||
@@ -61,6 +61,6 @@
|
||||
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing)
|
||||
if(!MS.active) continue
|
||||
MS.send_rc_message("Executive Officer's Desk", my_department, message, "", "", 2)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
if(areas && areas.len > 0)
|
||||
var/my_department = "[station_name()] firewall subroutines"
|
||||
var/rc_message = "An unknown malicious program has been detected in the [english_list(areaName)] lighting and airlock control systems at [worldtime2text()]. Systems will be fully compromised within approximately three minutes. Direct intervention is required immediately.<br>"
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/message_server/MS in SSmachinery.processing)
|
||||
MS.send_rc_message("Engineering", my_department, rc_message, "", "", 2)
|
||||
for(var/mob/living/silicon/ai/A in player_list)
|
||||
to_chat(A, "<span class='danger'>Malicious program detected in the [english_list(areaName)] lighting and airlock control systems by [my_department].</span>")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/datum/event/spider_infestation/start()
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in SSmachinery.processing)
|
||||
if(!temp_vent.welded && temp_vent.network && isStationLevel(temp_vent.loc.z))
|
||||
if(temp_vent.network.normal_members.len > 50)
|
||||
vents += temp_vent
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/datum/event/vent_clog/setup()
|
||||
endWhen = rand(25, 100)
|
||||
for(var/obj/machinery/atmospherics/unary/vent_scrubber/temp_vent in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/atmospherics/unary/vent_scrubber/temp_vent in SSmachinery.processing)
|
||||
if(!temp_vent)
|
||||
continue
|
||||
if(isStationLevel(temp_vent.z))
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(count_drones() >= config.max_maint_drones)
|
||||
return "The maximum number of active drones has been reached"
|
||||
var/has_active_fabricator = FALSE
|
||||
for(var/obj/machinery/drone_fabricator/DF in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/drone_fabricator/DF in SSmachinery.machinery)
|
||||
if((DF.stat & NOPOWER) || !DF.produce_drones || DF.drone_progress < 100)
|
||||
continue
|
||||
has_active_fabricator = TRUE
|
||||
@@ -40,7 +40,7 @@
|
||||
/datum/ghostspawner/simplemob/maintdrone/spawn_mob(mob/user)
|
||||
var/obj/machinery/drone_fabricator/fabricator
|
||||
var/list/all_fabricators = list()
|
||||
for(var/obj/machinery/drone_fabricator/DF in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/drone_fabricator/DF in SSmachinery.machinery)
|
||||
if((DF.stat & NOPOWER) || !DF.produce_drones || DF.drone_progress < 100)
|
||||
continue
|
||||
all_fabricators[DF.fabricator_tag] = DF
|
||||
@@ -84,4 +84,4 @@
|
||||
to_chat(user, SPAN_WARNING("The fabricator isn't ready to produce another drone, try again."))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -207,7 +207,7 @@
|
||||
radio = new(src)
|
||||
|
||||
if(!camera)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera = new /obj/machinery/camera(src, 0, TRUE, TRUE)
|
||||
camera.c_tag = name
|
||||
camera.replace_networks(list(NETWORK_MECHS))
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
icon_screen = "holocontrolw"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
use_power = 1
|
||||
active_power_usage = 8000 //8kW for the scenery + 500W per holoitem
|
||||
|
||||
circuit = /obj/item/circuitboard/holodeckcontrol
|
||||
@@ -186,7 +185,7 @@
|
||||
if (stat != oldstat && active && (stat & NOPOWER))
|
||||
emergencyShutdown()
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/machinery_process()
|
||||
/obj/machinery/computer/HolodeckControl/process()
|
||||
for(var/item in holographic_objs) // do this first, to make sure people don't take items out when power is down.
|
||||
if(!(get_turf(item) in linkedholodeck))
|
||||
derez(item, 0)
|
||||
@@ -204,13 +203,13 @@
|
||||
if(inoperable())
|
||||
return
|
||||
if(active)
|
||||
use_power(item_power_usage * (holographic_objs.len + holographic_mobs.len))
|
||||
use_power_oneoff(item_power_usage * (holographic_objs.len + holographic_mobs.len))
|
||||
|
||||
if(!checkInteg(linkedholodeck))
|
||||
damaged = 1
|
||||
loadProgram(current_map.holodeck_programs["turnoff"], 0)
|
||||
active = 0
|
||||
use_power = 1
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
for(var/mob/M in range(10,src))
|
||||
M.show_message("The holodeck overloads!")
|
||||
|
||||
@@ -256,7 +255,7 @@
|
||||
linkedholodeck.gravitychange(TRUE)
|
||||
|
||||
active = 0
|
||||
use_power = 1
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/proc/loadProgram(var/datum/holodeck_program/HP, var/check_delay = 1)
|
||||
@@ -277,7 +276,7 @@
|
||||
|
||||
last_change = world.time
|
||||
active = 1
|
||||
use_power = 2
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
|
||||
for(var/item in holographic_objs)
|
||||
derez(item)
|
||||
@@ -347,7 +346,7 @@
|
||||
|
||||
last_gravity_change = world.time
|
||||
active = 1
|
||||
use_power = 1
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
if(A.has_gravity())
|
||||
A.gravitychange(FALSE)
|
||||
@@ -362,7 +361,7 @@
|
||||
linkedholodeck.gravitychange(TRUE)
|
||||
|
||||
active = 0
|
||||
use_power = 1
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/proc/togglelock(var/mob/user)
|
||||
if(allowed(user))
|
||||
|
||||
@@ -367,7 +367,7 @@
|
||||
var/eventstarted = 0
|
||||
|
||||
anchored = 1.0
|
||||
use_power = 0 // reason is because the holodeck already takes power so this can be powered as a result.
|
||||
use_power = POWER_USE_OFF // reason is because the holodeck already takes power so this can be powered as a result.
|
||||
|
||||
/obj/machinery/readybutton/attack_ai(mob/user as mob)
|
||||
to_chat(user, "The station AI is not to interact with these devices!")
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
to_chat(user, SPAN_NOTICE("You take all filled honeycombs out."))
|
||||
return
|
||||
|
||||
/obj/machinery/beehive/machinery_process()
|
||||
/obj/machinery/beehive/process()
|
||||
if(closed && !smoked && bee_count)
|
||||
pollinate_flowers()
|
||||
update_icon()
|
||||
@@ -211,4 +211,4 @@
|
||||
user.visible_message(SPAN_NOTICE("\The [user] constructs a beehive."), SPAN_NOTICE("You construct a beehive."))
|
||||
new /obj/machinery/beehive(get_turf(user))
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
icon_state = "hydrotray3"
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
|
||||
var/obj/item/seeds/seed // Currently loaded seed packet.
|
||||
var/obj/item/disk/botany/loaded_disk //Currently loaded data disk.
|
||||
@@ -50,7 +49,7 @@
|
||||
var/failed_task = 0
|
||||
var/disk_needs_genes = 0
|
||||
|
||||
/obj/machinery/botany/machinery_process()
|
||||
/obj/machinery/botany/process()
|
||||
|
||||
..()
|
||||
if(!active) return
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
icon_state = SEED_NOUN_SEEDS
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 100
|
||||
|
||||
var/list/datum/seed_pile/piles = list()
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/apiary/machinery_process()
|
||||
/obj/machinery/apiary/process()
|
||||
|
||||
if(swarming > 0)
|
||||
swarming -= 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/machinery/portable_atmospherics/hydroponics/machinery_process()
|
||||
/obj/machinery/portable_atmospherics/hydroponics/process()
|
||||
|
||||
// Handle nearby smoke if any.
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
desc = "A mound of earth. You could plant some seeds here."
|
||||
icon_state = "soil"
|
||||
density = 0
|
||||
use_power = 0
|
||||
use_power = POWER_USE_OFF
|
||||
mechanical = 0
|
||||
tray_light = 0
|
||||
waterlevel = 0
|
||||
@@ -74,7 +74,7 @@
|
||||
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/die()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/machinery_process()
|
||||
/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/process()
|
||||
if(!seed)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
if(A.powered(EQUIP) && assembly.give_power(power_amount))
|
||||
A.use_power(power_amount, EQUIP)
|
||||
A.use_power_oneoff(power_amount, EQUIP)
|
||||
// give_power() handles CELLRATE on its own.
|
||||
|
||||
// For implants.
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Initialize()
|
||||
. = ..()
|
||||
camera = new(src)
|
||||
camera = new(src, 0, TRUE, TRUE)
|
||||
on_data_written()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Destroy()
|
||||
@@ -405,4 +405,4 @@
|
||||
audible_message("<span class='notice'>\The [src] beeps, out of paper.</span>")
|
||||
return
|
||||
else
|
||||
audible_message("<span class='notice'>\The [src] beeps, out of paper.</span>")
|
||||
audible_message("<span class='notice'>\The [src] beeps, out of paper.</span>")
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
|
||||
// If an opaque movable atom moves around we need to potentially update visibility.
|
||||
/turf/Entered(atom/movable/Obj, atom/OldLoc)
|
||||
. = ..()
|
||||
. = ..(Obj, OldLoc)
|
||||
|
||||
if (Obj && Obj.opacity && !has_opaque_atom)
|
||||
has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case.
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
SSatoms.InitializeAtoms(atoms) // The atoms should have been getting queued there. This flushes the queue.
|
||||
|
||||
SSmachinery.setup_template_powernets(cables)
|
||||
SSmachinery.setup_powernets_for_cables(cables)
|
||||
SSmachinery.setup_atmos_machinery(atmos_machines)
|
||||
if(notsuspended)
|
||||
SSmachinery.wake()
|
||||
@@ -181,4 +181,4 @@
|
||||
var/datum/map_template/M = new template()
|
||||
M.load(get_turf(mark), TRUE)
|
||||
qdel(mark)
|
||||
LAZYCLEARLIST(subtemplates_to_spawn)
|
||||
LAZYCLEARLIST(subtemplates_to_spawn)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/obj/machinery/mining
|
||||
icon = 'icons/obj/mining_drill.dmi'
|
||||
anchored = FALSE
|
||||
use_power = 0 //The drill takes power directly from a cell.
|
||||
use_power = POWER_USE_OFF //The drill takes power directly from a cell.
|
||||
density = TRUE
|
||||
layer = MOB_LAYER + 0.1 //So it draws over mobs in the tile north of it.
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
QDEL_NULL(spark_system)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mining/drill/machinery_process()
|
||||
/obj/machinery/mining/drill/process()
|
||||
if(need_player_check)
|
||||
return
|
||||
|
||||
@@ -570,4 +570,4 @@
|
||||
|
||||
connected.supports -= src
|
||||
connected.check_supports()
|
||||
connected = null
|
||||
connected = null
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
icon_state = "production_console"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 50
|
||||
|
||||
@@ -47,7 +46,7 @@
|
||||
if(!machine)
|
||||
var/area/A = get_area(src)
|
||||
var/best_distance = INFINITY
|
||||
for(var/obj/machinery/mineral/processing_unit/checked_machine in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/mineral/processing_unit/checked_machine in SSmachinery.machinery)
|
||||
if(id)
|
||||
if(checked_machine.id == id)
|
||||
machine = checked_machine
|
||||
@@ -327,7 +326,6 @@
|
||||
var/list/ores_stored[0]
|
||||
var/static/list/alloy_data
|
||||
var/active = 0
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 150
|
||||
|
||||
@@ -384,7 +382,7 @@
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/machinery/mineral/processing_unit/machinery_process()
|
||||
/obj/machinery/mineral/processing_unit/process()
|
||||
..()
|
||||
|
||||
if(!src.output || !src.input)
|
||||
@@ -444,7 +442,7 @@
|
||||
if(console)
|
||||
var/ore/Ore = ore_data[needs_metal]
|
||||
console.points += Ore.worth
|
||||
use_power(100)
|
||||
use_power_oneoff(100)
|
||||
ores_stored[needs_metal] -= A.requires[needs_metal]
|
||||
total += A.requires[needs_metal]
|
||||
total = max(1, round(total * A.product_mod)) //Always get at least one sheet.
|
||||
@@ -468,7 +466,7 @@
|
||||
for(var/i = 0, i < can_make, i += 2)
|
||||
if(console)
|
||||
console.points += O.worth * 2
|
||||
use_power(100)
|
||||
use_power_oneoff(100)
|
||||
ores_stored[metal] -= 2
|
||||
sheets += 2
|
||||
console.output_mats[M] += 1
|
||||
@@ -484,7 +482,7 @@
|
||||
for(var/i = 0, i < can_make, i++)
|
||||
if(console)
|
||||
console.points += O.worth
|
||||
use_power(100)
|
||||
use_power_oneoff(100)
|
||||
ores_stored[metal] -= 1
|
||||
sheets++
|
||||
if(console)
|
||||
@@ -493,7 +491,7 @@
|
||||
else
|
||||
if(console)
|
||||
console.points -= O.worth * 3 //reee wasting our materials!
|
||||
use_power(500)
|
||||
use_power_oneoff(500)
|
||||
ores_stored[metal] -= 1
|
||||
sheets++
|
||||
if(console)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
icon_state = "coinpress0"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 50
|
||||
var/pressing
|
||||
@@ -50,14 +49,14 @@
|
||||
src.visible_message(SPAN_NOTICE("\The [src] begins to print out a modsuit."))
|
||||
pressing = TRUE
|
||||
update_icon()
|
||||
use_power(500)
|
||||
use_power_oneoff(500)
|
||||
qdel(W)
|
||||
spawn(300)
|
||||
ping("\The [src] pings, \"Module successfuly produced!\"")
|
||||
|
||||
new outcome_path(get_turf(src))
|
||||
|
||||
use_power(500)
|
||||
use_power_oneoff(500)
|
||||
pressing = FALSE
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
var/obj/machinery/mineral/stacking_machine/machine
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 50
|
||||
|
||||
@@ -37,7 +36,7 @@
|
||||
if(!machine)
|
||||
var/area/A = get_area(src)
|
||||
var/best_distance = INFINITY
|
||||
for(var/obj/machinery/mineral/stacking_machine/checked_machine in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/mineral/stacking_machine/checked_machine in SSmachinery.machinery)
|
||||
if(id)
|
||||
if(checked_machine.id == id)
|
||||
machine = checked_machine
|
||||
@@ -127,7 +126,6 @@
|
||||
var/list/stack_storage = list()
|
||||
var/list/stack_paths = list()
|
||||
var/stack_amt = 50 // Amount to stack before releasing
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 50
|
||||
|
||||
@@ -175,7 +173,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mineral/stacking_machine/machinery_process()
|
||||
/obj/machinery/mineral/stacking_machine/process()
|
||||
if(!console)
|
||||
return
|
||||
if(stat & BROKEN)
|
||||
@@ -199,4 +197,4 @@
|
||||
if(stack_storage[sheet] >= stack_amt)
|
||||
new sheet(output, stack_amt)
|
||||
stack_storage[sheet] -= stack_amt
|
||||
intent_message(MACHINE_SOUND)
|
||||
intent_message(MACHINE_SOUND)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
icon_state = "unloader"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 50
|
||||
var/turf/input
|
||||
@@ -48,7 +47,7 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mineral/unloading_machine/machinery_process()
|
||||
/obj/machinery/mineral/unloading_machine/process()
|
||||
..()
|
||||
if(src.output && src.input)
|
||||
if(locate(/obj/structure/ore_box, input))
|
||||
|
||||
@@ -978,7 +978,7 @@ var/list/total_extraction_beacons = list()
|
||||
var/obj/machinery/anti_bluespace/AB = found_inhibitor
|
||||
if(T.z != AB.z || get_dist(T, AB) > 8 || (AB.stat & (NOPOWER | BROKEN)))
|
||||
continue
|
||||
AB.use_power(AB.active_power_usage)
|
||||
AB.use_power_oneoff(AB.active_power_usage)
|
||||
to_chat(user, SPAN_WARNING("A nearby bluespace inhibitor interferes with \the [src]!"))
|
||||
return
|
||||
to_chat(user, SPAN_NOTICE("You start attaching the pack to \the [A]..."))
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
break
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/machinery/mineral/mint/machinery_process()
|
||||
/obj/machinery/mineral/mint/process()
|
||||
if(input)
|
||||
var/obj/item/stack/O
|
||||
O = locate(/obj/item/stack, get_turf(input))
|
||||
@@ -204,4 +204,4 @@
|
||||
processing = FALSE
|
||||
coinsToProduce = temp_coins
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -518,7 +518,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
//If we hit the limit without finding a valid one, then the best one we found is selected
|
||||
|
||||
var/list/found_vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in SSmachinery.processing)
|
||||
if(!v.welded && v.z == ZLevel)
|
||||
found_vents.Add(v)
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ var/list/ai_verbs_default = list(
|
||||
/obj/machinery/ai_powersupply
|
||||
name = "power supply"
|
||||
active_power_usage = 50000 // Station AIs use significant amounts of power. This, when combined with charged SMES should mean AI lasts for 1hr without external power.
|
||||
use_power = 2
|
||||
use_power = POWER_USE_ACTIVE
|
||||
power_channel = EQUIP
|
||||
var/mob/living/silicon/ai/powered_ai
|
||||
invisibility = 100
|
||||
@@ -317,13 +317,13 @@ var/list/ai_verbs_default = list(
|
||||
forceMove(powered_ai.loc)
|
||||
|
||||
..()
|
||||
use_power(1) // Just incase we need to wake up the power system.
|
||||
use_power_oneoff(1) // Just incase we need to wake up the power system.
|
||||
|
||||
/obj/machinery/ai_powersupply/Destroy()
|
||||
. = ..()
|
||||
powered_ai = null
|
||||
|
||||
/obj/machinery/ai_powersupply/machinery_process()
|
||||
/obj/machinery/ai_powersupply/process()
|
||||
if(!powered_ai || powered_ai.stat == DEAD)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -331,14 +331,14 @@ var/list/ai_verbs_default = list(
|
||||
qdel(src)
|
||||
return
|
||||
if(powered_ai.APU_power)
|
||||
use_power = 0
|
||||
update_use_power(POWER_USE_OFF)
|
||||
return
|
||||
if(!powered_ai.anchored)
|
||||
loc = powered_ai.loc
|
||||
use_power = 0
|
||||
use_power(50000) // Less optimalised but only called if AI is unwrenched. This prevents usage of wrenching as method to keep AI operational without power. Intellicard is for that.
|
||||
update_use_power(POWER_USE_OFF)
|
||||
use_power_oneoff(50000) // Less optimalised but only called if AI is unwrenched. This prevents usage of wrenching as method to keep AI operational without power. Intellicard is for that.
|
||||
if(powered_ai.anchored)
|
||||
use_power = 2
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
return // TODO: Implement AI rejuvination
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
use_power = TRUE
|
||||
use_power = POWER_USE_IDLE
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
if(stat & NOPOWER)
|
||||
icon_state = "drone_fab_nopower"
|
||||
|
||||
/obj/machinery/drone_fabricator/machinery_process()
|
||||
/obj/machinery/drone_fabricator/process()
|
||||
if(!ROUND_IS_STARTED)
|
||||
return
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
to_chat(user, SPAN_WARNING("\The [src] is empty. Put something inside it first."))
|
||||
if(response == "Sync")
|
||||
var/success = FALSE
|
||||
for(var/obj/machinery/r_n_d/server/S in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/r_n_d/server/S in SSmachinery.machinery)
|
||||
for(var/id in files.known_tech) //Uploading
|
||||
var/datum/tech/T = files.known_tech[id]
|
||||
S.files.AddTech2Known(T)
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
common_radio = radio
|
||||
|
||||
if(!camera)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera = new /obj/machinery/camera(src, 0, TRUE, TRUE)
|
||||
camera.c_tag = real_name
|
||||
if(!scrambled_codes)
|
||||
camera.replace_networks(list(NETWORK_STATION, NETWORK_ROBOTS))
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
. = ..()
|
||||
|
||||
radio = new radio_type(src)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera = new /obj/machinery/camera(src, 0, TRUE, TRUE)
|
||||
camera.c_tag = "spiderbot-[real_name]"
|
||||
camera.replace_networks(list("SS13"))
|
||||
|
||||
|
||||
@@ -98,10 +98,10 @@
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "pad-idle"
|
||||
anchored = TRUE
|
||||
use_power = TRUE
|
||||
use_power = POWER_USE_IDLE
|
||||
|
||||
/obj/machinery/vannatusk_spawner/power_change()
|
||||
..()
|
||||
spark(src, 3, alldirs)
|
||||
new /mob/living/simple_animal/hostile/vannatusk(get_turf(src))
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -32,7 +32,7 @@ var/global/datum/ntnet/ntnet_global = new()
|
||||
/datum/ntnet/New()
|
||||
if(ntnet_global && (ntnet_global != src))
|
||||
ntnet_global = src // There can be only one.
|
||||
for(var/obj/machinery/ntnet_relay/R in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/ntnet_relay/R in SSmachinery.machinery)
|
||||
relays.Add(R)
|
||||
R.NTNet = src
|
||||
build_software_lists()
|
||||
@@ -163,4 +163,4 @@ var/global/datum/ntnet/ntnet_global = new()
|
||||
add_log("Configuration Updated. Wireless network firewall now [setting_communication ? "allows" : "disallows"] instant messaging and similar communication services.")
|
||||
if(NTNET_SYSTEMCONTROL)
|
||||
setting_systemcontrol = !setting_systemcontrol
|
||||
add_log("Configuration Updated. Wireless network firewall now [setting_systemcontrol ? "allows" : "disallows"] remote control of station's systems.")
|
||||
add_log("Configuration Updated. Wireless network firewall now [setting_systemcontrol ? "allows" : "disallows"] remote control of station's systems.")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/obj/machinery/ntnet_relay
|
||||
name = "NTNet Quantum Relay"
|
||||
desc = "A very complex router and transmitter capable of connecting electronic devices together. Looks fragile."
|
||||
use_power = 2
|
||||
use_power = POWER_USE_ACTIVE
|
||||
active_power_usage = 20000 //20kW, appropriate for machine that keeps massive cross-Zlevel wireless network operational.
|
||||
idle_power_usage = 100
|
||||
icon_state = "ntnet"
|
||||
@@ -48,11 +48,11 @@
|
||||
else
|
||||
add_overlay("ntnet_o_ok")
|
||||
|
||||
/obj/machinery/ntnet_relay/machinery_process()
|
||||
/obj/machinery/ntnet_relay/process()
|
||||
if(operable())
|
||||
use_power = 2
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
else
|
||||
use_power = 1
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
|
||||
if(dos_overload)
|
||||
dos_overload = max(0, dos_overload - dos_dissipate)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
power_usage += tesla_link.passive_charging_rate
|
||||
battery_module.battery.give(tesla_link.passive_charging_rate * CELLRATE)
|
||||
|
||||
A.use_power(power_usage, EQUIP)
|
||||
A.use_power_oneoff(power_usage, EQUIP)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -62,4 +62,4 @@
|
||||
power_has_failed = FALSE
|
||||
update_icon()
|
||||
return
|
||||
power_failure()
|
||||
power_failure()
|
||||
|
||||
@@ -385,7 +385,7 @@ Command action procs
|
||||
|
||||
|
||||
/proc/is_relay_online()
|
||||
for(var/obj/machinery/bluespacerelay/M in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/bluespacerelay/M in SSmachinery.machinery)
|
||||
if(M.stat == 0)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
return TRUE
|
||||
|
||||
else if(href_list["toggledoor"])
|
||||
for(var/obj/machinery/door/blast/M in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/door/blast/M in SSmachinery.machinery)
|
||||
if(M.id == href_list["toggledoor"])
|
||||
if(M.density)
|
||||
M.open()
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
invisibility = i ? 101 : 0
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/atmospherics/pipe/zpipe/machinery_process()
|
||||
/obj/machinery/atmospherics/pipe/zpipe/process()
|
||||
if(!parent) //This should cut back on the overhead calling build_network thousands of times per cycle
|
||||
..()
|
||||
else
|
||||
@@ -291,4 +291,4 @@
|
||||
/obj/machinery/atmospherics/pipe/zpipe/up/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
/obj/machinery/atmospherics/pipe/zpipe/down/purple
|
||||
color = PIPE_COLOR_PURPLE
|
||||
color = PIPE_COLOR_PURPLE
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/tmp/atom/movable/openspace/multiplier/shadower // Overlay used to multiply color of all OO overlays at once.
|
||||
|
||||
/turf/Entered(atom/movable/thing, turf/oldLoc)
|
||||
. = ..()
|
||||
. = ..(thing, oldLoc)
|
||||
if (thing.bound_overlay || thing.no_z_overlay || !TURF_IS_MIMICING(above))
|
||||
return
|
||||
above.update_mimic()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
log_debug("\The [src] given an unepxected req_one_access: [req_one_access]")
|
||||
|
||||
if(monitored_alarm_ids)
|
||||
for(var/obj/machinery/alarm/alarm in SSmachinery.processing_machines)
|
||||
for(var/obj/machinery/alarm/alarm in SSmachinery.processing)
|
||||
if(alarm.alarm_id && (alarm.alarm_id in monitored_alarm_ids))
|
||||
monitored_alarms += alarm
|
||||
// machines may not yet be ordered at this point
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
if(href_list["alarm"])
|
||||
if(ui_ref)
|
||||
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : SSmachinery.processing_machines)
|
||||
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : SSmachinery.processing)
|
||||
if(alarm)
|
||||
var/datum/topic_state/TS = generate_state(alarm)
|
||||
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
|
||||
@@ -42,7 +42,7 @@
|
||||
var/alarms[0]
|
||||
|
||||
// TODO: Move these to a cache, similar to cameras
|
||||
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : SSmachinery.processing_machines))
|
||||
for(var/obj/machinery/alarm/alarm in (monitored_alarms.len ? monitored_alarms : SSmachinery.processing))
|
||||
alarms[++alarms.len] = list("name" = sanitize(alarm.name), "ref"= "\ref[alarm]", "danger" = max(alarm.danger_level, alarm.alarm_area.atmosalm))
|
||||
data["alarms"] = alarms
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
var/turf/T = get_turf(ui_host())
|
||||
if(!T) // Safety check
|
||||
return
|
||||
for(var/obj/machinery/power/sensor/S in SSpower.all_sensors)
|
||||
for(var/obj/machinery/power/sensor/S in SSmachinery.all_sensors)
|
||||
if((T && S.loc.z == T.z) || (S.long_range)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
|
||||
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
|
||||
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
// SMES DATA (simplified view)
|
||||
var/list/smeslist[0]
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in SSpower.rcon_smes_units)
|
||||
for(var/obj/machinery/power/smes/buildable/SMES in SSmachinery.rcon_smes_units)
|
||||
smeslist.Add(list(list(
|
||||
"charge" = round(SMES.Percentage()),
|
||||
"input_set" = SMES.input_attempt,
|
||||
@@ -25,7 +25,7 @@
|
||||
data["smes_info"] = smeslist
|
||||
// BREAKER DATA (simplified view)
|
||||
var/list/breakerlist[0]
|
||||
for(var/obj/machinery/power/breakerbox/BR in SSpower.rcon_breaker_units)
|
||||
for(var/obj/machinery/power/breakerbox/BR in SSmachinery.rcon_breaker_units)
|
||||
breakerlist.Add(list(list(
|
||||
"RCON_tag" = BR.RCon_tag,
|
||||
"enabled" = BR.on
|
||||
@@ -79,7 +79,7 @@
|
||||
SMES.set_output(SMES.output_level_max)
|
||||
|
||||
if(href_list["toggle_breaker"])
|
||||
var/obj/machinery/power/breakerbox/toggle = SSpower.rcon_breaker_units_by_tag[href_list["toggle_breaker"]]
|
||||
var/obj/machinery/power/breakerbox/toggle = SSmachinery.rcon_breaker_units_by_tag[href_list["toggle_breaker"]]
|
||||
if(toggle)
|
||||
if(toggle.update_locked)
|
||||
to_chat(usr, "The breaker box was recently toggled. Please wait before toggling it again.")
|
||||
@@ -100,4 +100,4 @@
|
||||
if(!tag)
|
||||
return
|
||||
|
||||
return SSpower.rcon_smes_units_by_tag[tag]
|
||||
return SSmachinery.rcon_smes_units_by_tag[tag]
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
if(known)
|
||||
layer = EFFECTS_ABOVE_LIGHTING_LAYER
|
||||
for(var/obj/machinery/computer/ship/helm/H in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/computer/ship/helm/H in SSmachinery.machinery)
|
||||
H.get_known_sectors()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/obj/machinery/computer/ship/sensors/proc/find_sensors()
|
||||
if(!linked)
|
||||
return
|
||||
for(var/obj/machinery/shipsensors/S in SSmachinery.all_machines)
|
||||
for(var/obj/machinery/shipsensors/S in SSmachinery.machinery)
|
||||
if(linked.check_ownership(S))
|
||||
sensors = S
|
||||
break
|
||||
@@ -102,7 +102,7 @@
|
||||
new/obj/item/paper/(get_turf(src), O.get_scan_data(usr), "paper (Sensor Scan - [O])")
|
||||
return TOPIC_HANDLED
|
||||
|
||||
/obj/machinery/computer/ship/sensors/machinery_process()
|
||||
/obj/machinery/computer/ship/sensors/process()
|
||||
..()
|
||||
if(!linked)
|
||||
return
|
||||
@@ -180,11 +180,11 @@
|
||||
if(!use_power && (health == 0 || !in_vacuum()))
|
||||
return // No turning on if broken or misplaced.
|
||||
if(!use_power) //need some juice to kickstart
|
||||
use_power(idle_power_usage*5)
|
||||
use_power_oneoff(idle_power_usage*5)
|
||||
update_use_power(!use_power)
|
||||
queue_icon_update()
|
||||
|
||||
/obj/machinery/shipsensors/machinery_process()
|
||||
/obj/machinery/shipsensors/process()
|
||||
..()
|
||||
if(use_power) //can't run in non-vacuum
|
||||
if(!in_vacuum())
|
||||
@@ -207,7 +207,7 @@
|
||||
|
||||
/obj/machinery/shipsensors/proc/set_range(nrange)
|
||||
range = nrange
|
||||
active_power_usage = (1500 * (range**2)) //Exponential increase, also affects speed of overheating
|
||||
change_power_consumption(1500 * (range**2), POWER_USE_ACTIVE)
|
||||
|
||||
/obj/machinery/shipsensors/emp_act(severity)
|
||||
if(!use_power)
|
||||
|
||||
@@ -36,12 +36,12 @@
|
||||
|
||||
/datum/ship_engine/gas_thruster/toggle()
|
||||
if(nozzle.use_power)
|
||||
nozzle.update_use_power(0)
|
||||
nozzle.update_use_power(POWER_USE_OFF)
|
||||
else
|
||||
if(nozzle.blockage)
|
||||
if(nozzle.check_blockage())
|
||||
return
|
||||
nozzle.update_use_power(1)
|
||||
nozzle.update_use_power(POWER_USE_IDLE)
|
||||
if(nozzle.stat & NOPOWER)//try again
|
||||
nozzle.power_change()
|
||||
if(nozzle.is_on())//if everything is in working order, start booting!
|
||||
@@ -61,7 +61,7 @@
|
||||
density = 1
|
||||
atmos_canpass = CANPASS_NEVER
|
||||
|
||||
use_power = 0
|
||||
use_power = POWER_USE_OFF
|
||||
power_channel = EQUIP
|
||||
idle_power_usage = 21600 //6 Wh per tick for default 2 capacitor. Gives them a reason to turn it off, really to nerf backup battery
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
/obj/machinery/atmospherics/unary/engine/power_change()
|
||||
. = ..()
|
||||
if(stat & NOPOWER)
|
||||
update_use_power(0)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
|
||||
/obj/machinery/atmospherics/unary/engine/update_use_power()
|
||||
. = ..()
|
||||
@@ -185,9 +185,9 @@
|
||||
/obj/machinery/atmospherics/unary/engine/proc/burn()
|
||||
if(!is_on())
|
||||
return 0
|
||||
if(!check_fuel() || (0 < use_power(charge_per_burn)) || check_blockage())
|
||||
if(!check_fuel() || (0 < use_power_oneoff(charge_per_burn)) || check_blockage())
|
||||
audible_message(src,"<span class='warning'>[src] coughs once and goes silent!</span>")
|
||||
update_use_power(0)
|
||||
update_use_power(POWER_USE_OFF)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove_ratio(volume_per_burn * thrust_limit / air_contents.volume)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user