Files
CHOMPStation2/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
2025-08-31 03:56:12 +02:00

308 lines
9.4 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
var/base_icon = "pump"
name = "volumetric gas pump"
desc = "A pump that moves gas by volume"
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/pump/on
icon_state = "map_on"
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/volume_pump/fuel
icon_state = "map_off-fuel"
base_icon = "pump-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"
base_icon = "pump-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/update_icon()
if(!powered())
icon_state = "off"
else
icon_state = "[use_power ? "on" : "off"]"
overclock_overlay = mutable_appearance('icons/atmos/volume_pump_overclock.dmi', "vpumpoverclock")
if(powered() && use_power && overclocked)
add_overlay(overclock_overlay)
else
cut_overlay(overclock_overlay)
/obj/machinery/atmospherics/binary/volume_pump/update_underlays()
if(..())
underlays.Cut()
var/turf/T = get_turf(src)
if(!istype(T))
return
add_underlay(T, node1, turn(dir, -180), node1?.icon_connect_type)
add_underlay(T, node2, dir, node2?.icon_connect_type)
/obj/machinery/atmospherics/binary/volume_pump/hide(var/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(var/obj/item/W as obj, var/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(var/obj/item/W as obj, var/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))
user.visible_message( \
span_infoplain(span_bold("\The [user]") + " unfastens \the [src]."), \
span_notice("You have unfastened \the [src]."), \
"You hear ratchet.")
deconstruct()
/obj/machinery/atmospherics/binary/volume_pump/proc/multitool_act(var/obj/item/W as obj, var/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()
#undef VOLUME_PUMP_MAX_OUTPUT_PRESSURE
#undef VOLUME_PUMP_LEAK_AMOUNT