Files
Will 397d569b37 Atmos Pipe Improvements (#19478)
* pumps use their layer to connect pipes visually

* connectors for supply and scrubbers

* pump dmi stuff

* fixed volume pump dmi

* Vents support multiple connection types

* prevent multiple pipes attaching to the same side

* old code

* prioritize linking already connecting pipes

* constructable pressure tanks

* tank icon fix

* color fix

* fixes

* multiple connection universal pipes

* possible network fix

* buh buh

* tanks no longer go invisible
2026-05-21 20:22:25 -04:00

351 lines
11 KiB
Plaintext

/*
Every cycle, the pump uses the air in air_in to try and move a specific volume of gas into air_out.
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...
*/
#define VOLUME_PUMP_MAX_OUTPUT_PRESSURE 9000 // kpa
#define VOLUME_PUMP_LEAK_AMOUNT 0.04 // About 4% of the volume moved will leak.
/obj/machinery/atmospherics/binary/volume_pump
icon = 'icons/atmos/volume_pump.dmi'
icon_state = "map_off"
construction_type = /obj/item/pipe/directional
pipe_state = "volumepump"
level = 1
name = "volumetric gas pump"
desc = "A pump that moves gas by volume"
pipe_flags = NONE // Other pumps can be on other layers
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 15000 //15000 W ~ 20.4 HP
var/max_transfer_rate = ATMOS_DEFAULT_VOLUME_PUMP // Ls
var/transfer_rate = 20 // L
var/frequency = ZERO_FREQ
var/id = null
var/datum/radio_frequency/radio_connection
var/overclocked = FALSE
var/mutable_appearance/overclock_overlay
/obj/machinery/atmospherics/binary/volume_pump/Initialize(mapload)
. = ..()
air1.volume = ATMOS_DEFAULT_VOLUME_PUMP
air2.volume = ATMOS_DEFAULT_VOLUME_PUMP
if(frequency)
set_frequency(frequency)
/obj/machinery/atmospherics/binary/volume_pump/Destroy()
unregister_radio(src, frequency)
. = ..()
/obj/machinery/atmospherics/binary/volume_pump/on
icon_state = "map_on"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/fuel
icon_state = "map_off-fuel"
icon_connect_type = "-fuel"
connect_types = CONNECT_TYPE_FUEL
/obj/machinery/atmospherics/binary/volume_pump/fuel/on
icon_state = "map_on-fuel"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/aux
icon_state = "map_off-aux"
icon_connect_type = "-aux"
connect_types = CONNECT_TYPE_AUX
/obj/machinery/atmospherics/binary/volume_pump/aux/on
icon_state = "map_on-aux"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/scrubbers
icon_state = "map_off-scrubbers"
icon_connect_type = "-scrubbers"
connect_types = CONNECT_TYPE_SCRUBBER
/obj/machinery/atmospherics/binary/volume_pump/scrubbers/on
icon_state = "map_on-scrubbers"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/supply
icon_state = "map_off-supply"
icon_connect_type = "-supply"
connect_types = CONNECT_TYPE_SUPPLY
/obj/machinery/atmospherics/binary/volume_pump/supply/on
icon_state = "map_on-supply"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/update_icon()
var/base_icon = "pump[icon_connect_type]"
if(!powered())
icon_state = "[base_icon]-off"
else
icon_state = "[use_power ? "[base_icon]-on" : "[base_icon]-off"]"
overclock_overlay = mutable_appearance('icons/atmos/volume_pump_overclock.dmi', "vpumpoverclock[icon_connect_type]")
if(powered() && use_power && overclocked)
add_overlay(overclock_overlay)
else
cut_overlay(overclock_overlay)
/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
..()
underlays.Cut()
var/turf/T = get_turf(src)
if(!istype(T))
return
if(node1)
add_underlay(T, node1, turn(dir, -180), icon_connect_type)
if(node2)
add_underlay(T, node2, dir, icon_connect_type)
/obj/machinery/atmospherics/binary/volume_pump/hide(i)
update_underlays()
/obj/machinery/atmospherics/binary/volume_pump/process()
last_power_draw = 0
last_flow_rate = 0
var/power_draw = 0
if((stat & (NOPOWER|BROKEN)) || !use_power)
return
var/input_starting_moles = air1.total_moles
var/output_starting_pressure = air2.return_pressure()
// The pump will refuse to do anything if the pressure is too high or low, unless it is overclocked.
if((input_starting_moles < MINIMUM_MOLES_TO_PUMP || output_starting_pressure > VOLUME_PUMP_MAX_OUTPUT_PRESSURE) && !overclocked)
return
var/transfer_ratio = transfer_rate / air1.volume
if(!transfer_ratio)
return
var/datum/gas_mixture/removed = air1.remove_ratio(transfer_ratio)
var/transfer_moles = removed.total_moles
last_flow_rate = (transfer_moles/input_starting_moles)*air1.volume
// Some gases will leak if overclocked. Trade off for no pump limits.
if(overclocked)
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/leaked = removed.remove_ratio(VOLUME_PUMP_LEAK_AMOUNT)
environment.merge(leaked)
air2.merge(removed)
// This part is necessary, as the function pump_gas has limits that reduces the volume pump to just a glorified pressure pump.
// The gas pump does not care about trying to meet a specific pressure. It will keep moving gas till a pressure limit is reached.
power_draw = (transfer_moles/input_starting_moles)*power_rating
if (power_draw >= 0)
last_power_draw = power_draw
use_power(power_draw)
if(network1)
network1.update = TRUE
if(network2)
network2.update = TRUE
return TRUE
//Radio remote control
/obj/machinery/atmospherics/binary/volume_pump/proc/set_frequency(new_frequency)
SSradio.remove_object(src, frequency)
frequency = new_frequency
if(frequency)
radio_connection = SSradio.add_object(src, frequency, radio_filter = RADIO_ATMOSIA)
/obj/machinery/atmospherics/binary/volume_pump/proc/broadcast_status()
if(!radio_connection)
return FALSE
var/datum/signal/signal = new
signal.transmission_method = TRANSMISSION_RADIO //radio signal
signal.source = src
signal.data = list(
"tag" = id,
"device" = "AGP",
"power" = use_power,
"transfer_rate" = transfer_rate,
"sigtype" = "status"
)
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
return TRUE
/obj/machinery/atmospherics/binary/volume_pump/tgui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN|NOPOWER))
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GasPump", name)
ui.open()
/obj/machinery/atmospherics/binary/volume_pump/tgui_data(mob/user)
// this is the data which will be sent to the ui
var/list/data = list(
"on" = use_power,
"rate" = transfer_rate*100,
"max_rate" = max_transfer_rate,
"last_flow_rate" = last_flow_rate*10,
"last_power_draw" = last_power_draw,
"max_power_draw" = power_rating,
)
return data
/obj/machinery/atmospherics/binary/volume_pump/receive_signal(datum/signal/signal)
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
return FALSE
if(signal.data["power"])
if(text2num(signal.data["power"]))
update_use_power(USE_POWER_IDLE)
else
update_use_power(USE_POWER_OFF)
if("power_toggle" in signal.data)
update_use_power(!use_power)
if(signal.data["set_volume_rate"])
transfer_rate = between(0, text2num(signal.data["set_volume_rate"]), air1.volume)
if(signal.data["status"])
broadcast_status()
return //do not update_icon
broadcast_status()
update_icon()
return
/obj/machinery/atmospherics/binary/volume_pump/attack_ghost(mob/user)
tgui_interact(user)
/obj/machinery/atmospherics/binary/volume_pump/attack_hand(mob/user)
if(..())
return
add_fingerprint(user)
if(!allowed(user))
to_chat(user, span_warning("Access denied."))
return
tgui_interact(user)
/obj/machinery/atmospherics/binary/volume_pump/tgui_act(action, params, datum/tgui/ui)
if(..())
return TRUE
switch(action)
if("power")
update_use_power(!use_power)
. = TRUE
if("set_press")
var/press = params["press"]
switch(press)
if("min")
transfer_rate = 0
if("max")
transfer_rate = max_transfer_rate
if("set")
var/new_rate = tgui_input_number(ui.user,"Enter new transfer rate (0-[max_transfer_rate] L/s)","Flow Control",src.transfer_rate, max_transfer_rate, 0)
src.transfer_rate = between(0, new_rate, max_transfer_rate)
. = TRUE
add_fingerprint(ui.user)
update_icon()
/obj/machinery/atmospherics/binary/volume_pump/power_change()
var/old_stat = stat
..()
if(old_stat != stat)
update_icon()
/obj/machinery/atmospherics/binary/volume_pump/attackby(obj/item/W as obj, mob/user as mob)
if (W.has_tool_quality(TOOL_WRENCH))
wrench_act(W, user)
if (W.has_tool_quality(TOOL_MULTITOOL))
multitool_act(W, user)
/obj/machinery/atmospherics/binary/volume_pump/examine(mob/user)
. = ..()
. += "This device is designed to move large volumes of gasses quickly, but with no gurantee of exact pressures.\
Meaning that this can naievely over-pressurize pipes and devices past the device's designed limit."
. += span_bold("The [src]'s pressure limit is [VOLUME_PUMP_MAX_OUTPUT_PRESSURE].")
. += span_notice("Its pressure limits could be [overclocked ? "en" : "dis"]abled with a" + span_bold("multitool") + ".")
if(overclocked)
. += "Its warning light is on[use_power ? " and it's spewing gas!" : "."]"
/obj/machinery/atmospherics/binary/volume_pump/proc/wrench_act(obj/item/W as obj, mob/user as mob)
if (!(stat & NOPOWER) && use_power)
to_chat(user, span_warning("You cannot unwrench this [src], turn it off first."))
return TRUE
if(!can_unwrench())
to_chat(user, span_warning("You cannot unwrench this [src], it too exerted due to internal pressure."))
add_fingerprint(user)
return TRUE
playsound(src, W.usesound, 50, 1)
to_chat(user, span_notice("You begin to unfasten \the [src]..."))
if(do_after(user, 40 * W.toolspeed, src))
user.visible_message( \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
atom_deconstruct()
/obj/machinery/atmospherics/binary/volume_pump/proc/multitool_act(obj/item/W as obj, mob/user as mob)
if(!overclocked)
overclocked = TRUE
to_chat(user, span_notice("The pump makes a grinding noise and air starts to hiss out as you disable its pressure limits."))
else
overclocked = FALSE
to_chat(user, span_notice("The pump quiets down as you turn its limiters back on."))
update_icon()
/obj/machinery/atmospherics/binary/volume_pump/click_alt(mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(!allowed(user))
to_chat(user, span_warning("Access denied."))
return CLICK_ACTION_BLOCKING
to_chat(user, span_notice("You set the [name] to max output"))
transfer_rate = max_transfer_rate
add_fingerprint(user)
return CLICK_ACTION_SUCCESS
/obj/machinery/atmospherics/binary/volume_pump/click_ctrl(mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(!allowed(user))
to_chat(user, span_warning("Access denied."))
return CLICK_ACTION_BLOCKING
update_use_power(!use_power)
update_icon()
add_fingerprint(user)
to_chat(user, span_notice("You toggle the [name] [use_power ? "on" : "off"]."))
return CLICK_ACTION_SUCCESS
#undef VOLUME_PUMP_MAX_OUTPUT_PRESSURE
#undef VOLUME_PUMP_LEAK_AMOUNT