[MIRROR] Atmospheric Device Changes, Added Volume Pump (#11515)

Co-authored-by: Muted Kobold <tangletail@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-08-28 06:38:03 -07:00
committed by GitHub
parent 5e1d57e076
commit aef42000c2
14 changed files with 765 additions and 32 deletions

View File

@@ -255,8 +255,6 @@ Thus, the two variables affect pump operation are set in New():
"You hear ratchet.")
deconstruct()
//CHOMPEdit Start - Adds TGStation keybinds to save our engineers some time.
/obj/machinery/atmospherics/binary/pump/AltClick(mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -281,3 +279,26 @@ Thus, the two variables affect pump operation are set in New():
else
to_chat(user, span_warning("Access denied."))
//CHOMPEdit End
/obj/machinery/atmospherics/binary/pump/high_power
icon = 'icons/atmos/volume_pump.dmi'
icon_state = "map_off"
construction_type = /obj/item/pipe/directional
pipe_state = "volumepump"
level = 1
name = "high power gas pump"
desc = "A pump that moves gas from one place to another. 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 = USE_POWER_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"]"

View File

@@ -1,21 +1,307 @@
/obj/machinery/atmospherics/binary/pump/high_power
/*
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 = "high power gas pump"
desc = "A pump that moves gas from one place to another. Has double the power rating of the standard gas pump."
name = "volumetric gas pump"
desc = "A pump that moves gas by volume"
power_rating = 15000 //15000 W ~ 20 HP
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 15000 //15000 W ~ 20.4 HP
/obj/machinery/atmospherics/binary/pump/high_power/on
use_power = USE_POWER_IDLE
var/max_transfer_rate = ATMOS_DEFAULT_VOLUME_PUMP // Ls
var/transfer_rate = 20 // L
var/frequency = 0
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/pump/high_power/update_icon()
/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

View File

@@ -162,6 +162,32 @@
update_icon()
/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/W as obj, var/mob/user as mob)
if (W.has_tool_quality(TOOL_MULTITOOL))
var/list/options = list("Frequency", "ID Tag", "-SAVE TO BUFFER-", "Cancel")
var/answer = tgui_alert(user, "[src] has an ID of \"[id]\" and a frequency of [frequency]. What would you like to change?", "Options!", options)
if(!answer || answer == "Cancel" || !Adjacent(user))
return
switch(answer)
if("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
to_chat(user, span_notice("You set the [src]'s frequency to [frequency]."))
if("ID Tag")
id = tgui_input_text(user, "Please insert an ID tag for [src], example 'exhaust_port'.", "Set ID Tag", id, MAX_NAME_LEN)
if(id)
to_chat(user, span_notice("You set the [src]'s ID Tag to \"[id]\"."))
if("-SAVE TO BUFFER-")
var/obj/item/multitool/tool = W
tool.connectable = src
to_chat(user, span_notice("You copied the [src] into the [tool]'s buffer!"))
return ..()
if (!W.has_tool_quality(TOOL_WRENCH))
return ..()
@@ -173,3 +199,11 @@
span_notice("You have unfastened \the [src]."), \
"You hear a ratchet.")
deconstruct()
/obj/machinery/atmospherics/unary/outlet_injector/CtrlClick(mob/user)
if (volume_rate == ATMOS_DEFAULT_VOLUME_PUMP + 500 || use_power == USE_POWER_OFF)
return ..()
volume_rate = ATMOS_DEFAULT_VOLUME_PUMP + 500
to_chat(user, span_notice("You have set \the [src] to [volume_rate]"))
update_icon()

View File

@@ -298,13 +298,13 @@
/obj/machinery/atmospherics/unary/vent_pump/atmos_init()
..()
//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)
set_frequency(frequency)
/obj/machinery/atmospherics/unary/vent_pump/proc/set_frequency(new_frequency)
//some vents work his own special way
radio_filter_in = new_frequency==1439?(RADIO_FROM_AIRALARM):null
radio_filter_out = new_frequency==1439?(RADIO_TO_AIRALARM):null
radio_connection = register_radio(src, frequency, new_frequency, radio_filter_in)
frequency = new_frequency
broadcast_status()
@@ -404,18 +404,7 @@
to_chat(user, span_warning("You need more welding fuel to complete this task."))
return 1
if(W.has_tool_quality(TOOL_MULTITOOL))
var/choice = tgui_alert(user, "[src] has an ID of \"[id_tag]\" and a frequency of [frequency]. What would you like to change?", "[src] ID", list("ID Tag", "Frequency", "Nothing"))
switch(choice)
if("ID Tag")
var/new_id = tgui_input_text(user, "[src] has an ID of \"[id_tag]\". What would you like it to be?", "[src] ID", id_tag, 30, FALSE, TRUE)
if(new_id)
id_tag = new_id
if("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
multitool_act(W, user)
return TRUE
else
..()
@@ -458,6 +447,31 @@
"You hear a ratchet.")
deconstruct()
/obj/machinery/atmospherics/unary/vent_pump/proc/multitool_act(obj/item/W, mob/user)
var/list/options = list(
"ID Tag", "Frequency", "Direction", "-SAVE TO BUFFER-")
var/choice = tgui_input_list(user, "[src] has an ID of \"[id_tag]\" and a frequency of [frequency]. What would you like to change?", "[src] Config", options)
switch(choice)
if("ID Tag")
var/new_id = tgui_input_text(user, "[src] has an ID of \"[id_tag]\". What would you like it to be?", "[src] ID", id_tag, 30)
if(new_id)
id_tag = new_id
if("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be? Note, 1439 will only hail Air Alarms for this device.", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if("-SAVE TO BUFFER-")
var/obj/item/multitool/tool = W
tool.connectable = src
if("Direction")
pump_direction = !pump_direction
to_chat(user, span_notice("[src] is now [pump_direction ? "pumping in" : "siphoning out"]."))
update_icon()
#undef DEFAULT_PRESSURE_DELTA
#undef EXTERNAL_PRESSURE_BOUND

View File

@@ -8,7 +8,7 @@
var/list/leaks = list()
var/update = 1
var/update = TRUE
//var/datum/gas_mixture/air_transient = null
/datum/pipe_network/Destroy()

View File

@@ -1,3 +1,11 @@
#define SENSOR_PRESSURE (1<<0)
#define SENSOR_TEMPERATURE (1<<1)
#define SENSOR_O2 (1<<2)
#define SENSOR_PLASMA (1<<3)
#define SENSOR_N2 (1<<4)
#define SENSOR_CO2 (1<<5)
#define SENSOR_N2O (1<<6)
/obj/machinery/air_sensor
icon = 'icons/obj/stationobjs.dmi'
icon_state = "gsensor1"
@@ -74,6 +82,75 @@
SSradio.remove_object(src,frequency)
. = ..()
/obj/machinery/air_sensor/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
return wrench_act(user, W)
if(W.has_tool_quality(TOOL_MULTITOOL))
return multitool_act(user, W)
return ..()
/obj/machinery/air_sensor/proc/wrench_act(var/mob/living/user, var/obj/item/tool/wrench/W)
playsound(src, W.usesound, 50, 1)
user.visible_message("[user] unfastens \the [src].", span_notice("You have unfastened \the [src]."), "You hear ratcheting.")
var/obj/item/pipe_gsensor/gsensor = new /obj/item/pipe_gsensor(loc)
gsensor.id_tag = id_tag
gsensor.output = output
qdel(src)
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
#define ONOFF_TOGGLE(flag) "\[[(output & flag) ? "YES" : "NO"]]"
/obj/machinery/air_sensor/proc/multitool_act(mob/living/user, obj/item/multitool/tool)
var/list/options = list(
"Pressure: [ONOFF_TOGGLE(SENSOR_PRESSURE)]" = SENSOR_PRESSURE,
"Temperature: [ONOFF_TOGGLE(SENSOR_TEMPERATURE)]" = SENSOR_TEMPERATURE,
"Oxygen: [ONOFF_TOGGLE(SENSOR_O2)]" = SENSOR_O2,
"Toxins: [ONOFF_TOGGLE(SENSOR_PLASMA)]" = SENSOR_PLASMA,
"Nitrogen: [ONOFF_TOGGLE(SENSOR_N2)]" = SENSOR_N2,
"Carbon Dioxide: [ONOFF_TOGGLE(SENSOR_CO2)]" = SENSOR_CO2,
"Nitrous Oxide: [ONOFF_TOGGLE(SENSOR_N2O)]" = SENSOR_N2O,
"-SAVE TO BUFFER-" = "multitool"
)
var/answer = tgui_input_list(user, "[src] has an ID of \"[id_tag]\" and a frequency of [frequency]. What would you like to change?", "Options!", options)
if(!(src in view(5, user)))
return TRUE
if(answer in options) // Null will break us out
switch(options[answer])
if(SENSOR_PRESSURE)
output ^= SENSOR_PRESSURE
if(SENSOR_TEMPERATURE)
output ^= SENSOR_TEMPERATURE
if(SENSOR_O2)
output ^= SENSOR_O2
if(SENSOR_PLASMA)
output ^= SENSOR_PLASMA
if(SENSOR_N2)
output ^= SENSOR_N2
if(SENSOR_CO2)
output ^= SENSOR_CO2
if(SENSOR_N2O)
output ^= SENSOR_N2O
if("frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
if("multitool")
id_tag = tgui_input_text(user, "Please insert an ID tag for [src], example 'burn_chamber'.", "Set ID Tag", id_tag, MAX_NAME_LEN, FALSE)
if(!id_tag || !Adjacent(user))
return
var/obj/item/multitool/M = tool
M.connectable = src
to_chat(user, span_notice("You save [src] into [M]'s buffer."))
return TRUE
#undef ONOFF_TOGGLE
/obj/machinery/computer/general_air_control
icon_keyboard = "atmos_key"
icon_screen = "tank"
@@ -96,6 +173,12 @@
tgui_interact(user)
/obj/machinery/computer/general_air_control/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_MULTITOOL))
return multitool_act(W, user)
. = ..(W, user)
/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -130,6 +213,70 @@
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
/obj/machinery/computer/general_air_control/proc/multitool_act(obj/item/W, mob/user)
var/list/options = list("Sensors", "Frequency", "Cancel")
var/answer = tgui_input_list(user, "[src] has a frequency of [frequency]. What would you like to change?", "Options!", options)
. = TRUE
if(!answer || answer == "Cancel" || !Adjacent(user))
return
switch(answer)
if("Sensors")
configure_sensors(user, W)
if("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
return
/obj/machinery/computer/general_air_control/proc/configure_sensors(mob/living/user, obj/item/multitool/tool)
to_chat(user, "CONFIGURE SENSOR FUNC")
var/choice = tgui_input_list(user, "Would you like to add or remove a sensor/meter?", "Configuration", list("Add", "Remove","Cancel"))
if( !choice || choice == "Cancel" || !Adjacent(user))
return
switch(choice)
if("Add")
// Device must be a meter or gas sensor.
var/obj/machinery/device = tool.connectable
if(!device || !(istype(device, /obj/machinery/meter)) && !(istype(device, /obj/machinery/air_sensor)))
to_chat(user, span_warning("Error: No device in multitool buffer, or incompatible device is not a sensor or meter."))
return
var/device_name = tgui_input_text(user, "Enter a name for the Sensor/Meter.", "Name")
if (!device_name || !Adjacent(user))
to_chat(user, span_warning("Error: No name was given for [tool.connectable]."))
return
if(istype(device, /obj/machinery/air_sensor))
var/obj/machinery/air_sensor/AS = device
sensors[AS.id_tag] = device_name
else
var/obj/machinery/meter/M = device
sensors[M.id] = device_name
to_chat(user, span_notice("You have added the [tool.connectable] to the [src] under the name [device_name]!"))
if("Remove")
// Creates an associative mapping of Names to Tags, from Tags to Names.
var/list/sensor_names = list()
for(tag in sensors)
sensor_names[sensors[tag]] = sensors[tag]
var/to_remove = tgui_input_list(user, "Select a sensor/meter to remove", "Sensor/Meter Removal", sensor_names)
if(!to_remove)
return
var/confirm = tgui_alert(user, "Are you sure you want to remove the sensor/meter '[to_remove]'?", "Warning", list("Yes", "No"))
if(confirm != "Yes" || !Adjacent(user))
return
sensors -= sensor_names[to_remove]
to_chat(user, span_notice("Successfully removed sensor/meter with name [to_remove]"))
/obj/machinery/computer/general_air_control/Initialize(mapload)
. = ..()
if(frequency)
@@ -138,6 +285,8 @@
/obj/machinery/computer/general_air_control/large_tank_control
icon = 'icons/obj/computer.dmi'
frequency = 1441
name = "Large Tank Computer"
desc = "Controls various devices for managing a gas tank."
var/input_tag
var/output_tag
var/list/input_info
@@ -234,6 +383,75 @@
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
/obj/machinery/computer/general_air_control/large_tank_control/multitool_act(obj/item/W, mob/user)
var/list/options = list("Inlet", "Outlet", "Sensors", "Frequency", "Cancel")
var/choice = tgui_input_list(user, "[src] has a frequency of [frequency]. What would you like to change?", "Configuration", options)
if(!choice || choice == "Cancel" || !Adjacent(user))
return
switch(choice)
if ("Inlet")
configure_inlet(user, W)
if ("Outlet")
configure_outlet(user, W)
if ("Sensors")
configure_sensors(user, W)
if ("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
return TRUE
/obj/machinery/computer/general_air_control/large_tank_control/proc/configure_outlet(mob/living/user, obj/item/multitool/tool)
var/choice = tgui_alert(user, "Would you like to set an outlet or clear it?", "Configuration", list("Set", "Clear", "Cancel"))
if(!choice || !Adjacent(user) || choice == "Cancel")
return
switch(choice)
if ("Set")
to_chat(user, span_notice("The buffer is [tool.connectable]"))
if (!istype(tool.connectable, /obj/machinery/atmospherics/unary/vent_pump))
to_chat(user, span_notice("Error: Buffer is either empty, or object in buffer is invalid. Device should be a Unary Vent."))
return
var/obj/machinery/atmospherics/unary/vent_pump/pump = tool.connectable
output_tag = pump.id_tag
pump.external_pressure_bound = 0
pump.external_pressure_bound_default = 0
to_chat(user, span_notice("You have set the outlet!"))
return
if ("Clear")
output_tag = null
to_chat(user, span_notice("You have cleared the outlet!"))
return
/obj/machinery/computer/general_air_control/large_tank_control/proc/configure_inlet(mob/living/user, obj/item/multitool/tool)
var/choice = tgui_alert(user, "Would you like to set an inlet or clear it?", "Configuration", list("Set", "Clear", "Cancel"))
if(!choice || !Adjacent(user) || choice == "Cancel")
return
switch(choice)
if ("Set")
if (!istype(tool.connectable, /obj/machinery/atmospherics/unary/outlet_injector))
to_chat(user, span_notice("Error: Buffer is either empty, or object in buffer is invalid. Device should be Injector"))
return
var/obj/machinery/atmospherics/unary/outlet_injector/injector = tool.connectable
input_tag = injector.id
to_chat(user, span_notice("You have set the inlet"))
return
if ("Clear")
input_tag = null
to_chat(user, span_notice("You have cleared the inlet!"))
return
/obj/machinery/computer/general_air_control/supermatter_core
icon = 'icons/obj/computer.dmi'
frequency = 1433
@@ -335,6 +553,75 @@
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
/obj/machinery/computer/general_air_control/supermatter_core/multitool_act(obj/item/W, mob/user)
var/list/options = list("Inlet", "Outlet", "Sensors", "Frequency")
var/choice = tgui_input_list(user, "[src] has a frequency of [frequency]. What would you like to change?", "Configuration", options)
if(!choice || choice == "Cancel" || !Adjacent(user))
return
switch(choice)
if ("Inlet")
configure_inlet(user, W)
if ("Outlet")
configure_outlet(user, W)
if ("Sensors")
configure_sensors(user, W)
if ("Frequency")
var/new_frequency = tgui_input_number(user, "[src] has a frequency of [frequency]. What would you like it to be?", "[src] frequency", frequency, RADIO_HIGH_FREQ, RADIO_LOW_FREQ)
if(new_frequency)
new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
set_frequency(new_frequency)
return TRUE
/obj/machinery/computer/general_air_control/supermatter_core/proc/configure_outlet(mob/living/user, obj/item/multitool/tool)
var/choice = tgui_alert(user, "Would you like to set an outlet or clear it?", "Configuration", list("Set", "Clear", "Cancel"))
if(!choice || !Adjacent(user) || choice == "Cancel")
return
switch(choice)
if ("Set")
if (!istype(tool.connectable, /obj/machinery/atmospherics/unary/vent_pump))
to_chat(user, span_warning("Error: Buffer is either empty, or object in buffer is invalid. Device should be Air Vent"))
return
var/obj/machinery/atmospherics/unary/vent_pump/pump = tool.connectable
output_tag = pump.id_tag
pump.external_pressure_bound = 0
pump.external_pressure_bound_default = 0
to_chat(user, span_notice("You have set the outlet!"))
return
if ("Clear")
output_tag = null
to_chat(user, span_notice("You have cleared the outlet!"))
return
/obj/machinery/computer/general_air_control/supermatter_core/proc/configure_inlet(mob/living/user, obj/item/multitool/tool)
var/choice = tgui_alert(user, "Would you like to set an inlet or clear it?", "Configuration", list("Set", "Clear", "Cancel"))
if(!choice || !Adjacent(user) || choice == "Cancel")
return
switch(choice)
if ("Set")
to_chat(user, span_notice("The buffer is [tool.connectable]"))
if (!istype(tool.connectable, /obj/machinery/atmospherics/unary/outlet_injector))
to_chat(user, span_warning("Error: Buffer is either empty, or object in buffer is invalid. Device should be Injector"))
return
var/obj/machinery/atmospherics/unary/outlet_injector/injector = tool.connectable
input_tag = injector.id
to_chat(user, span_notice("You have set the inlet!"))
return
if ("Clear")
input_tag = null
to_chat(user, span_notice("You have cleared the inlet!"))
return
/obj/machinery/computer/general_air_control/fuel_injection
icon = 'icons/obj/computer.dmi'
icon_screen = "alert:0"
@@ -453,3 +740,11 @@
radio_connection.post_signal(src, signal, radio_filter = RADIO_ATMOSIA)
. = TRUE
#undef SENSOR_PRESSURE
#undef SENSOR_TEMPERATURE
#undef SENSOR_O2
#undef SENSOR_PLASMA
#undef SENSOR_N2
#undef SENSOR_CO2
#undef SENSOR_N2O

View File

@@ -9,6 +9,7 @@
power_channel = ENVIRON
var/frequency = 0
var/id
var/open = FALSE
use_power = USE_POWER_IDLE
idle_power_usage = 15
@@ -117,7 +118,19 @@
qdel(src)
return
if(istype(W, /obj/item/multitool))
if(W.has_tool_quality(TOOL_SCREWDRIVER))
playsound(src, W.usesound, 50, 1)
to_chat(user, span_notice("You have [open ? "closed" : "opened"] the maintenance panel for [src]."))
open = !open
return
if(W.has_tool_quality(TOOL_MULTITOOL))
if(open) // For setting up the meter to be used by other devices over radio.
id = tgui_input_text(user, "Please insert an ID tag for [src], example 'exhaust_pipe'.", "Set ID Tag", id, MAX_NAME_LEN)
var/obj/item/multitool/tool = W
tool.connectable = src
return
for(var/obj/machinery/atmospherics/pipe/P in loc)
pipes_on_turf |= P
if(!pipes_on_turf.len)

View File

@@ -293,3 +293,30 @@ Buildable meters
/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
piping_layer = new_layer
/obj/item/pipe_gsensor
name = "gas sensor"
desc = "A sensor that can be hooked to a computer."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "gsensor0"
item_state = "buildpipe"
w_class = ITEMSIZE_LARGE
var/label = null
var/id_tag
var/output = 3
/obj/item/pipe_gsensor/attackby(obj/item/W, mob/user)
if(W.has_tool_quality(TOOL_WRENCH))
return wrench_act(user, W)
return ..()
/obj/item/pipe_gsensor/proc/wrench_act(mob/living/user, obj/item/tool/wrench/W)
var/obj/machinery/air_sensor/air_sensor = new /obj/machinery/air_sensor(loc)
air_sensor.id_tag = id_tag
air_sensor.output = output
playsound(src, W.usesound, 50, 1)
to_chat(user, span_notice("You fasten the meter to the pipe."))
qdel(src)
/obj/item/pipe_gsensor/dropped(mob/user)
. = ..()

View File

@@ -27,6 +27,7 @@ GLOBAL_LIST_INIT(atmos_pipe_recipes, list(
new /datum/pipe_recipe/pipe("Aux Pump", /obj/machinery/atmospherics/binary/pump/aux),
new /datum/pipe_recipe/pipe("Pressure Regulator", /obj/machinery/atmospherics/binary/passive_gate),
new /datum/pipe_recipe/pipe("High Power Gas Pump", /obj/machinery/atmospherics/binary/pump/high_power),
new /datum/pipe_recipe/pipe("Volumetric Gas Pump", /obj/machinery/atmospherics/binary/volume_pump),
new /datum/pipe_recipe/pipe("Automatic Shutoff Valve",/obj/machinery/atmospherics/valve/shutoff),
new /datum/pipe_recipe/pipe("Scrubber", /obj/machinery/atmospherics/unary/vent_scrubber),
new /datum/pipe_recipe/meter("Meter"),
@@ -35,6 +36,7 @@ GLOBAL_LIST_INIT(atmos_pipe_recipes, list(
new /datum/pipe_recipe/pipe("Gas Mixer 'T'", /obj/machinery/atmospherics/trinary/mixer/t_mixer),
new /datum/pipe_recipe/pipe("Omni Gas Mixer", /obj/machinery/atmospherics/omni/mixer),
new /datum/pipe_recipe/pipe("Omni Gas Filter", /obj/machinery/atmospherics/omni/atmos_filter),
new /datum/pipe_recipe/air_sensor("Gas Sensor"),
),
"Heat Exchange" = list(
new /datum/pipe_recipe/pipe("Pipe", /obj/machinery/atmospherics/pipe/simple/heat_exchanging),
@@ -147,6 +149,15 @@ GLOBAL_LIST_INIT(disposal_pipe_recipes, list(
/datum/pipe_recipe/meter/New(label)
name = label
//
// Subtype for gas sensor
//
/datum/pipe_recipe/air_sensor
pipe_type = /obj/item/pipe_gsensor
/datum/pipe_recipe/air_sensor/New(label)
name = label
//
// Subtype for disposal pipes
//

View File

@@ -174,7 +174,7 @@
make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe))
var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist))
var/can_destroy_pipe = istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct)
var/can_destroy_pipe = istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/item/pipe_gsensor)
. = TRUE
if((mode & DESTROY_MODE) && can_destroy_pipe)
@@ -207,6 +207,13 @@
PM.setAttachLayer(queued_piping_layer)
if(mode & WRENCH_MODE)
do_wrench(PM, user)
else if(istype(recipe, /datum/pipe_recipe/air_sensor))
to_chat(user, span_notice("You start building an air sensor..."))
if(do_after(user, 2, target = A))
activate()
var/obj/item/pipe_gsensor/GS = new /obj/item/pipe_gsensor(get_turf(A))
if(mode & WRENCH_MODE)
do_wrench(GS, user)
else if(istype(recipe, /datum/pipe_recipe/pipe))
var/datum/pipe_recipe/pipe/R = recipe
to_chat(user, span_notice("You start building a pipe..."))

View File

@@ -16,6 +16,15 @@
)
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE
/datum/design_techweb/board/tank_management
name = "tank monitoring console circuit"
id = "tank_management"
build_path = /obj/item/circuitboard/air_management/tank_control
category = list(
RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_ENGINEERING
)
departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING | DEPARTMENT_BITFLAG_SCIENCE
/datum/design_techweb/board/shutoff_monitor
name = "Automatic shutoff valve monitor circuit"
id = "shutoff_monitor"

View File

@@ -8,6 +8,7 @@
"atmosanalyzer",
"atmosalerts",
"air_management",
"tank_management",
"shutoff_monitor",
// "thermomachine",
// "space_heater",

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

View File

@@ -12,6 +12,8 @@ import type { BooleanLike } from 'tgui-core/react';
type Data = {
on: BooleanLike;
max_rate: number;
rate: number;
pressure_set: number;
last_flow_rate: number;
last_power_draw: number;
@@ -21,8 +23,15 @@ type Data = {
export const GasPump = (props) => {
const { act, data } = useBackend<Data>();
const { on, pressure_set, last_flow_rate, last_power_draw, max_power_draw } =
data;
const {
on,
max_rate,
rate,
pressure_set,
last_flow_rate,
last_power_draw,
max_power_draw,
} = data;
return (
<Window width={470} height={290}>
@@ -78,9 +87,15 @@ export const GasPump = (props) => {
SET
</Button>
</LabeledControls.Item>
<LabeledControls.Item label="Desired Output Pressure">
{(pressure_set / 100).toFixed(2)} kPa
</LabeledControls.Item>
{max_rate ? (
<LabeledControls.Item label="Desired Transfer Rate">
{`${(rate / 100).toFixed(2)} L/s`}
</LabeledControls.Item>
) : (
<LabeledControls.Item label="Desired Output Pressure">
{`${(pressure_set / 100).toFixed(2)} kPa`}
</LabeledControls.Item>
)}
</LabeledControls>
</Section>
</Window.Content>