From e20acc3aafcf569877ee44c3f8b0ca1501acc200 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sun, 25 Dec 2022 06:50:03 +0100 Subject: [PATCH] [MIRROR] Build your own atmos chambers [MDB IGNORE] (#18269) * Build your own atmos chambers (#72019) ## About The Pull Request https://user-images.githubusercontent.com/110812394/208232089-a183fb95-9326-4514-986a-a2b1e21be40c.mp4 **Notes** - You can print atmos control circuit boards at the circuit printer after research - You can only build one sensor for each gas type for in the whole map. This is because each sensor is assigned a unique chamber id from a fixed set of constants. Once all those values are used up there will be duplicates so yeah only sensor per gas type for that round - Un wrenching or destroying the injector/vent will automatically disconnect them from the sensor. I forgot to show that in the video - Destroying the sensor via right click with RPD will also automatically disconnect everything. It should be obvious but i made it even more obvious now ## Why It's Good For The Game From #71232 ![Screenshot (66)](https://user-images.githubusercontent.com/110812394/207928807-bc6edfdd-26cc-48cd-8cb9-1b98f53ad1fe.png) That and also i heard somewhere in the forum that this was highly requested ## Changelog :cl: add: Gas sensors recipe to RPD code: linking all the stuff via multitool qol: make your own tank instead of moving around canisters /:cl: Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com> * Build your own atmos chambers Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com> --- .../computer/atmos_computers/__identifiers.dm | 5 ++ .../computer/atmos_computers/_air_sensor.dm | 59 ++++++++++++++++++ .../atmos_computers/_atmos_control.dm | 14 ++--- .../computer/atmos_computers/inlets.dm | 4 +- .../computer/atmos_computers/outlets.dm | 15 ++--- code/game/objects/items/RPD.dm | 61 +++++++++++++++++++ code/modules/asset_cache/assets/pipes.dm | 1 + .../unary_devices/outlet_injector.dm | 40 ++++++++++++ .../components/unary_devices/vent_pump.dm | 36 ++++++++++- .../tgui/interfaces/RapidPipeDispenser.js | 3 +- 10 files changed, 219 insertions(+), 19 deletions(-) diff --git a/code/game/machinery/computer/atmos_computers/__identifiers.dm b/code/game/machinery/computer/atmos_computers/__identifiers.dm index c8096472b8e..13d87b0b8ae 100644 --- a/code/game/machinery/computer/atmos_computers/__identifiers.dm +++ b/code/game/machinery/computer/atmos_computers/__identifiers.dm @@ -31,6 +31,11 @@ #define ATMOS_GAS_MONITOR_DISTRO "distro" #define ATMOS_GAS_MONITOR_WASTE "waste" +///maps an air sensor's chamber id to its input valve[ i.e. outlet_injector] id +#define CHAMBER_INPUT_FROM_ID(chamber_id) ((chamber_id) + "_in") +///maps an air sensor's chamber id to its output valve[i.e. vent pump] id +#define CHAMBER_OUTPUT_FROM_ID(chamber_id) ((chamber_id) + "_out") + // Human-readble names of these funny tags. GLOBAL_LIST_INIT(station_gas_chambers, list( ATMOS_GAS_MONITOR_O2 = "Oxygen Supply", diff --git a/code/game/machinery/computer/atmos_computers/_air_sensor.dm b/code/game/machinery/computer/atmos_computers/_air_sensor.dm index 5a49697c9ed..1dfe1bf396e 100644 --- a/code/game/machinery/computer/atmos_computers/_air_sensor.dm +++ b/code/game/machinery/computer/atmos_computers/_air_sensor.dm @@ -13,8 +13,67 @@ /obj/machinery/air_sensor/Initialize(mapload) id_tag = chamber_id + "_sensor" + var/static/list/multitool_tips = list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Link logged injectors/vents", + SCREENTIP_CONTEXT_RMB = "Reset all I/O ports", + ) + ) + AddElement(/datum/element/contextual_screentip_tools, multitool_tips) + + return ..() + +/obj/machinery/air_sensor/Destroy() + reset() return ..() /obj/machinery/air_sensor/update_icon_state() icon_state = "gsensor[on]" return ..() + +/obj/machinery/air_sensor/proc/reset() + var/input_id = CHAMBER_INPUT_FROM_ID(chamber_id) + if(GLOB.objects_by_id_tag[input_id] != null) + var/obj/machinery/atmospherics/components/unary/outlet_injector/injector = GLOB.objects_by_id_tag[input_id] + injector.disconnect_chamber() + + var/output_id = CHAMBER_OUTPUT_FROM_ID(chamber_id) + if(GLOB.objects_by_id_tag[output_id] != null) + var/obj/machinery/atmospherics/components/unary/vent_pump/pump = GLOB.objects_by_id_tag[output_id] + pump.disconnect_chamber() + + +///right click with multi tool to disconnect everything +/obj/machinery/air_sensor/multitool_act_secondary(mob/living/user, obj/item/tool) + balloon_alert(user, "reset ports") + reset() + return TRUE + +/obj/machinery/air_sensor/multitool_act(mob/living/user, obj/item/multitool/multi_tool) + .= ..() + + if (!istype(multi_tool)) + return . + + if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/outlet_injector)) + var/obj/machinery/atmospherics/components/unary/outlet_injector/input = multi_tool.buffer + input.chamber_id = chamber_id + GLOB.objects_by_id_tag[CHAMBER_INPUT_FROM_ID(chamber_id)] = input + balloon_alert(user, "connected to input") + + else if(istype(multi_tool.buffer, /obj/machinery/atmospherics/components/unary/vent_pump)) + var/obj/machinery/atmospherics/components/unary/vent_pump/output = multi_tool.buffer + + //so its no longer controlled by air alarm + output.disconnect_from_area() + //configuration copied from /obj/machinery/atmospherics/components/unary/vent_pump/siphon + output.pump_direction = ATMOS_DIRECTION_SIPHONING + output.pressure_checks = ATMOS_INTERNAL_BOUND + output.internal_pressure_bound = 4000 + output.external_pressure_bound = 0 + + output.chamber_id = chamber_id + GLOB.objects_by_id_tag[CHAMBER_OUTPUT_FROM_ID(chamber_id)] = output + balloon_alert(user, "connected to output") + + return TRUE diff --git a/code/game/machinery/computer/atmos_computers/_atmos_control.dm b/code/game/machinery/computer/atmos_computers/_atmos_control.dm index b1c5987c847..ab83a88a4cc 100644 --- a/code/game/machinery/computer/atmos_computers/_atmos_control.dm +++ b/code/game/machinery/computer/atmos_computers/_atmos_control.dm @@ -25,7 +25,7 @@ var/available_devices = list() for (var/chamber_identifier in GLOB.station_gas_chambers) - if (!("[chamber_identifier]_in" in GLOB.objects_by_id_tag) && !("[chamber_identifier]_out" in GLOB.objects_by_id_tag)) + if (!(CHAMBER_INPUT_FROM_ID(chamber_identifier) in GLOB.objects_by_id_tag) && !(CHAMBER_OUTPUT_FROM_ID(chamber_identifier) in GLOB.objects_by_id_tag)) continue available_devices[GLOB.station_gas_chambers[chamber_identifier]] = chamber_identifier @@ -73,14 +73,14 @@ if (!isnull(sensor)) chamber_info["gasmix"] = gas_mixture_parser(sensor.return_air()) - var/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/input = GLOB.objects_by_id_tag["[chamber_id]_in"] + var/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/input = GLOB.objects_by_id_tag[CHAMBER_INPUT_FROM_ID(chamber_id)] if (!isnull(input)) chamber_info["input_info"] = list( "active" = input.on, "amount" = input.volume_rate, ) - var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag["[chamber_id]_out"] + var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag[CHAMBER_OUTPUT_FROM_ID(chamber_id)] if (!isnull(output)) chamber_info["output_info"] = list( "active" = output.on, @@ -102,14 +102,14 @@ if (!(chamber in atmos_chambers)) return TRUE - var/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/input = GLOB.objects_by_id_tag["[chamber]_in"] + var/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/input = GLOB.objects_by_id_tag[CHAMBER_INPUT_FROM_ID(chamber)] input?.on = !input.on input.update_appearance(UPDATE_ICON) if("toggle_output") if (!(chamber in atmos_chambers)) return TRUE - var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag["[chamber]_out"] + var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag[CHAMBER_OUTPUT_FROM_ID(chamber)] output?.on = !output.on output.update_appearance(UPDATE_ICON) if("adjust_input") @@ -121,7 +121,7 @@ return TRUE target = clamp(target, 0, MAX_TRANSFER_RATE) - var/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/input = GLOB.objects_by_id_tag["[chamber]_in"] + var/obj/machinery/atmospherics/components/unary/outlet_injector/input = GLOB.objects_by_id_tag[CHAMBER_INPUT_FROM_ID(chamber)] input?.volume_rate = clamp(target, 0, min(input.airs[1].volume, MAX_TRANSFER_RATE)) if("adjust_output") if (!(chamber in atmos_chambers)) @@ -131,7 +131,7 @@ if(isnull(target)) return TRUE - var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag["[chamber]_out"] + var/obj/machinery/atmospherics/components/unary/vent_pump/output = GLOB.objects_by_id_tag[CHAMBER_OUTPUT_FROM_ID(chamber)] output?.internal_pressure_bound = clamp(target, 0, ATMOS_PUMP_MAX_PRESSURE) if("reconnect") reconnect(usr) diff --git a/code/game/machinery/computer/atmos_computers/inlets.dm b/code/game/machinery/computer/atmos_computers/inlets.dm index 2cb788acc0e..5379a15c725 100644 --- a/code/game/machinery/computer/atmos_computers/inlets.dm +++ b/code/game/machinery/computer/atmos_computers/inlets.dm @@ -1,11 +1,9 @@ /obj/machinery/atmospherics/components/unary/outlet_injector/monitored on = TRUE volume_rate = MAX_TRANSFER_RATE - /// The unique string that represents which atmos chamber to associate with. - var/chamber_id /obj/machinery/atmospherics/components/unary/outlet_injector/monitored/Initialize(mapload) - id_tag = chamber_id + "_in" + id_tag = CHAMBER_INPUT_FROM_ID(chamber_id) return ..() /obj/machinery/atmospherics/components/unary/outlet_injector/monitored/plasma_input diff --git a/code/game/machinery/computer/atmos_computers/outlets.dm b/code/game/machinery/computer/atmos_computers/outlets.dm index 34a57d271a3..529a83d7219 100644 --- a/code/game/machinery/computer/atmos_computers/outlets.dm +++ b/code/game/machinery/computer/atmos_computers/outlets.dm @@ -1,12 +1,12 @@ /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored on = TRUE icon_state = "vent_map_siphon_on-3" - /// The unique string that represents which atmos chamber to associate with. - var/chamber_id /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/Initialize(mapload) - id_tag = chamber_id + "_out" - return ..() + id_tag = CHAMBER_OUTPUT_FROM_ID(chamber_id) + . = ..() + //we dont want people messing with these special vents using the air alarm interface + disconnect_from_area() /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/plasma_output name = "plasma tank output inlet" @@ -107,12 +107,13 @@ /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored on = TRUE icon_state = "vent_map_siphon_on-3" - var/chamber_id // Same as the rest, but bigger volume. /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/Initialize(mapload) - id_tag = chamber_id + "_out" - return ..() + id_tag = CHAMBER_OUTPUT_FROM_ID(chamber_id) + . = ..() + //we dont want people messing with these special vents using the air alarm interface + disconnect_from_area() /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/air_output name = "air mix tank output inlet" diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index e03077849c7..cfdae9b80dc 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -44,6 +44,33 @@ GLOBAL_LIST_INIT(atmos_pipe_recipes, list( new /datum/pipe_info/pipe("4-Way Manifold", /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w, FALSE), new /datum/pipe_info/pipe("Junction", /obj/machinery/atmospherics/pipe/heat_exchanging/junction, FALSE), new /datum/pipe_info/pipe("Heat Exchanger", /obj/machinery/atmospherics/components/unary/heat_exchanger, FALSE), + ), + "Air Sensors" = list( + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/plasma_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/oxygen_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/nitrogen_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/mix_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/nitrous_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/air_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/carbon_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/bz_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/freon_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/halon_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/healium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/hydrogen_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/hypernoblium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/miasma_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/nitrium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/pluoxium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/proto_nitrate_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/tritium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/water_vapor_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/zauker_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/helium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/antinoblium_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/incinerator_tank), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/ordnance_burn_chamber), + new /datum/pipe_info/sensor(/obj/machinery/air_sensor/ordnance_freezer_chamber), ) )) @@ -127,6 +154,14 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( return rows +/datum/pipe_info/sensor + dirtype = PIPE_ONEDIR + +/datum/pipe_info/sensor/New(obj/machinery/air_sensor/sensor) + id = sensor + name = capitalize(replacetext(initial(sensor.name), "gas sensor", "")) + icon_state = "gsensor1" + /datum/pipe_info/pipe/New(label, obj/machinery/atmospherics/path, use_five_layers) name = label id = path @@ -275,6 +310,13 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( return ..() /obj/item/pipe_dispenser/pre_attack_secondary(obj/machinery/atmospherics/target, mob/user, params) + if(istype(target, /obj/machinery/air_sensor)) + if(!do_after(user, destroy_speed, target)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + qdel(target) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(!istype(target, /obj/machinery/atmospherics)) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(target.pipe_color && target.piping_layer) @@ -350,9 +392,19 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/list/r = list() for(var/i in 1 to cat.len) var/datum/pipe_info/info = cat[i] + + //skip sensors which are already in the world so we dont create duplicate ones + if(info.type == /datum/pipe_info/sensor) + var/datum/pipe_info/sensor/sensor_info = info + var/obj/machinery/air_sensor/sensor = sensor_info.id + if(GLOB.objects_by_id_tag[initial(sensor.chamber_id) + "_sensor"] != null) + continue + r += list(list("pipe_name" = info.name, "pipe_index" = i, "selected" = (info == recipe), "all_layers" = info.all_layers)) if(info == recipe) data["selected_category"] = c + if(r.len == 0) //when all air sensors are installed this list will become empty + continue data["categories"] += list(list("cat_name" = c, "recipes" = r)) var/list/init_directions = list("north" = FALSE, "south" = FALSE, "east" = FALSE, "west" = FALSE) @@ -538,6 +590,15 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( PM.setAttachLayer(piping_layer) if(mode & WRENCH_MODE) PM.wrench_act(user, src) + else if(recipe.type == /datum/pipe_info/sensor) + balloon_alert(user, "building air sensor...") + if(do_after(user, atmos_build_speed, target = attack_target)) + activate() + var/datum/pipe_info/sensor/sensor_recipe = recipe + var/obj/machinery/air_sensor/sensor_blueprint = sensor_recipe.id + new sensor_blueprint(get_turf(attack_target)) + //change the recipe as the current one becomes unavailable + recipe = first_atmos else if(recipe.all_layers == FALSE && (piping_layer == 1 || piping_layer == 5)) to_chat(user, span_notice("You can't build this object on the layer...")) diff --git a/code/modules/asset_cache/assets/pipes.dm b/code/modules/asset_cache/assets/pipes.dm index 66a37de9f86..f553051ba7e 100644 --- a/code/modules/asset_cache/assets/pipes.dm +++ b/code/modules/asset_cache/assets/pipes.dm @@ -4,3 +4,4 @@ /datum/asset/spritesheet/pipes/create_spritesheets() for (var/each in list('icons/obj/atmospherics/pipes/pipe_item.dmi', 'icons/obj/atmospherics/pipes/disposal.dmi', 'icons/obj/atmospherics/pipes/transit_tube.dmi', 'icons/obj/plumbing/fluid_ducts.dmi')) InsertAll("", each, GLOB.alldirs) + Insert(sprite_name = "gsensor1", I = 'icons/obj/stationobjs.dmi', icon_state = "gsensor1") diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 2b29c650fc3..ad8cf8fafdd 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -17,6 +17,46 @@ ///Rate of operation of the device var/volume_rate = 50 + ///id of air sensor its connected to + var/chamber_id + +/obj/machinery/atmospherics/components/unary/outlet_injector/Initialize(mapload) + . = ..() + var/static/list/tool_screentips = list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Log to link later with air sensor", + ) + ) + AddElement(/datum/element/contextual_screentip_tools, tool_screentips) + +/obj/machinery/atmospherics/components/unary/outlet_injector/examine(mob/user) + . = ..() + . += span_notice("You can link it with an air sensor using a multitool.") + +/obj/machinery/atmospherics/components/unary/outlet_injector/multitool_act(mob/living/user, obj/item/multitool/multi_tool) + . = ..() + if (!istype(multi_tool)) + return . + + balloon_alert(user, "saved in buffer") + multi_tool.buffer = src + return TRUE + +/obj/machinery/atmospherics/components/unary/outlet_injector/wrench_act(mob/living/user, obj/item/I) + . = ..() + if(.) + disconnect_chamber() + +///called when its either unwrenched or destroyed +/obj/machinery/atmospherics/components/unary/outlet_injector/proc/disconnect_chamber() + if(chamber_id != null) + GLOB.objects_by_id_tag -= CHAMBER_INPUT_FROM_ID(chamber_id) + chamber_id = null + +/obj/machinery/atmospherics/components/unary/outlet_injector/Destroy() + disconnect_chamber() + return ..() + /obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user) if(can_interact(user)) on = !on diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 1f9bdeb9eaf..3a0f277b914 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -28,16 +28,48 @@ // ATMOS_INTERNAL_BOUND: Do not pass internal_pressure_bound // NO_BOUND: Do not pass either + ///id of air sensor its connected to + var/chamber_id + /obj/machinery/atmospherics/components/unary/vent_pump/New() if(!id_tag) id_tag = SSnetworks.assign_random_name() + var/static/list/tool_screentips = list( + TOOL_MULTITOOL = list( + SCREENTIP_CONTEXT_LMB = "Log to link later with air sensor", + ) + ) + AddElement(/datum/element/contextual_screentip_tools, tool_screentips) . = ..() /obj/machinery/atmospherics/components/unary/vent_pump/Initialize(mapload) . = ..() - assign_to_area() +/obj/machinery/atmospherics/components/unary/vent_pump/examine(mob/user) + . = ..() + . += span_notice("You can link it with an air sensor using a multitool.") + +/obj/machinery/atmospherics/components/unary/vent_pump/multitool_act(mob/living/user, obj/item/multitool/multi_tool) + . = ..() + if (!istype(multi_tool)) + return . + + balloon_alert(user, "saved in buffer") + multi_tool.buffer = src + return TRUE + +/obj/machinery/atmospherics/components/unary/vent_pump/wrench_act(mob/living/user, obj/item/wrench) + . = ..() + if(.) + disconnect_chamber() + +///called when its either unwrenched or destroyed +/obj/machinery/atmospherics/components/unary/vent_pump/proc/disconnect_chamber() + if(chamber_id != null) + GLOB.objects_by_id_tag -= CHAMBER_OUTPUT_FROM_ID(chamber_id) + chamber_id = null + /obj/machinery/atmospherics/components/unary/vent_pump/Destroy() disconnect_from_area() @@ -45,6 +77,8 @@ if(vent_area) vent_area.air_vents -= src + disconnect_chamber() + return ..() /obj/machinery/atmospherics/components/unary/vent_pump/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) diff --git a/tgui/packages/tgui/interfaces/RapidPipeDispenser.js b/tgui/packages/tgui/interfaces/RapidPipeDispenser.js index 07cd09b64ad..9cccb960cdd 100644 --- a/tgui/packages/tgui/interfaces/RapidPipeDispenser.js +++ b/tgui/packages/tgui/interfaces/RapidPipeDispenser.js @@ -16,6 +16,7 @@ export const ICON_BY_CATEGORY_NAME = { 'Devices': 'microchip', 'Heat Exchange': 'thermometer-half', 'Station Equipment': 'microchip', + 'Air Sensors': 'microchip', }; const TOOLS = [ @@ -318,7 +319,7 @@ export const RapidPipeDispenser = (props, context) => { const { data } = useBackend(context); const { category: rootCategoryIndex } = data; return ( - +