From b116ec27895b8b72ee3a02b141528635145b2f2a Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 1 Dec 2022 16:31:31 +0100 Subject: [PATCH] [MIRROR] TGUI replaces Radial menu for Plumbing RCD [MDB IGNORE] (#17840) * TGUI replaces Radial menu for Plumbing RCD (#71569) **About the pull request** Radial menu's replaced with TGUI window for all plumbing RCD's https://user-images.githubusercontent.com/110812394/204481973-8f6d62c0-9288-4165-bce7-ee8bfec95bee.mp4 **Why it's good for the game** **1. Faster Navigation** - Old System: It had 3 radial menus' ->To select type of device to build ->To select the colour of fluid ducts ->To select the layer of devices 3 menus for one system makes navigation between them annoying for e.g.: to create a red fluid duct of layer 5 you have to open all these 3 menus & cycling through the radial menu by clicking the next button is time consuming when you have a large number of items - New System: with just one window open it's as simple as 3 clicks and your done just like the RPD **2. Always available** - Old System: When you select an option inside a radial menu the menu closes so you have to reopen it again to change a setting - New System: open the window drag it to the side and it will always be there for you **3. Just easier for our eyes** - Old System: Moving my eyes in a circle across the menu only to find out i have to click Next and circle my eyes again honestly makes my head spin - New System: The menu options are small enough to be viewed all at once & helps me see what I need more easily **4. Consistency** Both the RPD & plumbing all have similar concepts i.e., pipes, devices, layers & colours it only makes sense they should have similar interfaces. Also categorizing the items into tabs can help with explaining what each item does **Conclusion** Just because the radial menu looks attractive shouldn't mean it must be used everywhere, it only makes sense to use it when the number of options of an item is small enough to be displayed on the screen all at once for e.g., modules in a Mod suit. If the user has to click the next button to cycle through the item's, it defeats the purpose of the radial menu and makes the user work more to find his settings **Side Note :** removed unused code in RapidPipeDispenser.js **ChangeLog** :cl: add: plumbing constructor TGUI, just like Rapid Pipe Dispensers del: plumbing constructor radials code: categories for each item /:cl: Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com> Co-authored-by: Jeremiah <42397676+jlsnow301@ users.noreply.github.com> Co-authored-by: Time-Green * TGUI replaces Radial menu for Plumbing RCD Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com> Co-authored-by: Jeremiah <42397676+jlsnow301@ users.noreply.github.com> Co-authored-by: Time-Green --- code/__DEFINES/plumbing.dm | 5 - code/game/objects/items/RCD.dm | 320 ++++++++++-------- code/game/objects/items/RPD.dm | 2 + code/modules/asset_cache/assets/plumbing.dm | 9 + code/modules/plumbing/ducts.dm | 1 - .../plumbing/plumbers/_plumb_machinery.dm | 14 + code/modules/plumbing/plumbers/acclimator.dm | 2 + code/modules/plumbing/plumbers/bottler.dm | 3 + code/modules/plumbing/plumbers/destroyer.dm | 3 + code/modules/plumbing/plumbers/fermenter.dm | 4 + code/modules/plumbing/plumbers/filter.dm | 6 +- .../plumbing/plumbers/grinder_chemical.dm | 2 + code/modules/plumbing/plumbers/pill_press.dm | 3 + .../plumbing/plumbers/plumbing_buffer.dm | 2 + code/modules/plumbing/plumbers/pumps.dm | 2 + .../plumbing/plumbers/reaction_chamber.dm | 3 + code/modules/plumbing/plumbers/splitters.dm | 4 +- code/modules/plumbing/plumbers/synthesizer.dm | 4 + code/modules/plumbing/plumbers/teleporter.dm | 3 +- .../xenobiology/vatgrowing/vatgrower.dm | 4 + tgstation.dme | 1 + .../tgui/interfaces/PlumbingService.tsx | 152 +++++++++ .../tgui/interfaces/RapidPipeDispenser.js | 12 +- 23 files changed, 405 insertions(+), 156 deletions(-) create mode 100644 code/modules/asset_cache/assets/plumbing.dm create mode 100644 tgui/packages/tgui/interfaces/PlumbingService.tsx diff --git a/code/__DEFINES/plumbing.dm b/code/__DEFINES/plumbing.dm index 39277fb1f73..002c2c7c1e3 100644 --- a/code/__DEFINES/plumbing.dm +++ b/code/__DEFINES/plumbing.dm @@ -28,8 +28,3 @@ GLOBAL_LIST_INIT(plumbing_layer_names, list( /// Name of omni color #define DUCT_COLOR_OMNI "omni" - -/// Cached radial menu options for plumbing RCD color picker -GLOBAL_LIST_EMPTY(plumbing_color_menu_options) -/// Cached radial menu options for plumbing RCD layer picker -GLOBAL_LIST_EMPTY(plumbing_layer_menu_options) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 1929b6b38f8..00a2c102c9d 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -1161,11 +1161,9 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) max_matter = 200 ///type of the plumbing machine - var/blueprint = null + var/obj/machinery/blueprint = null ///index, used in the attack self to get the type. stored here since it doesnt change var/list/choices = list() - ///index, used in the attack self to get the type. stored here since it doesnt change - var/list/name_to_type = list() ///All info for construction var/list/machinery_data = list("cost" = list()) ///This list that holds all the plumbing design types the plumberer can construct. Its purpose is to make it easy to make new plumberer subtypes with a different selection of machines. @@ -1174,14 +1172,54 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) var/current_layer = "Default Layer" ///Current selected color, for ducts var/current_color = "omni" + ///maps layer name to layer number value. didnt make this global cause only this class needs it + var/static/list/name_to_number = list( + "First Layer" = 1, + "Second Layer" = 2, + "Default Layer" = 3, + "Fourth Layer" = 4, + "Fifth Layer" = 5, + ) /obj/item/construction/plumbing/Initialize(mapload) . = ..() + + //design types supported for this plumbing rcd set_plumbing_designs() -/obj/item/construction/plumbing/examine(mob/user) - . = ..() - . += span_notice("Alt-Click to change layer and duct color.") + //set cost of each machine & initial blueprint + for(var/obj/machinery/plumbing/plumbing_type as anything in plumbing_design_types) + machinery_data["cost"][plumbing_type] = plumbing_design_types[plumbing_type] + blueprint = plumbing_design_types[1] + +/obj/item/construction/plumbing/proc/set_plumbing_designs() + plumbing_design_types = list( + //category 1 Synthesizers i.e devices which creates , reacts & destroys chemicals + /obj/machinery/plumbing/synthesizer = 15, + /obj/machinery/plumbing/reaction_chamber/chem = 15, + /obj/machinery/plumbing/grinder_chemical = 30, + /obj/machinery/plumbing/growing_vat = 20, + /obj/machinery/plumbing/fermenter = 30, + /obj/machinery/plumbing/liquid_pump = 35, //extracting chemicals from ground is one way of creation + /obj/machinery/plumbing/disposer = 10, + /obj/machinery/plumbing/buffer = 10, //creates chemicals as it waits for other buffers containing other chemicals and when mixed creates new chemicals + + //category 2 distributors i.e devices which inject , move around , remove chemicals from the network + /obj/machinery/duct = 1, + /obj/machinery/plumbing/layer_manifold = 5, + /obj/machinery/plumbing/input = 5, + /obj/machinery/plumbing/filter = 5, + /obj/machinery/plumbing/splitter = 5, + /obj/machinery/plumbing/sender = 20, + /obj/machinery/plumbing/output = 5, + + //category 3 Storage i.e devices which stores & makes the processed chemicals ready for consumption + /obj/machinery/plumbing/tank = 20, + /obj/machinery/plumbing/acclimator = 10, + /obj/machinery/plumbing/bottler = 50, + /obj/machinery/plumbing/pill_press = 20, + /obj/machinery/iv_drip/plumbing = 20 + ) /obj/item/construction/plumbing/equipped(mob/user, slot, initial) . = ..() @@ -1199,53 +1237,97 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) return ..() /obj/item/construction/plumbing/attack_self(mob/user) - ..() - if(!choices.len) - for(var/obj/machinery/plumbing/plumbing_type as anything in plumbing_design_types) - choices += list(initial(plumbing_type.name) = image(initial(plumbing_type.icon), icon_state = initial(plumbing_type.icon_state))) - name_to_type[initial(plumbing_type.name)] = plumbing_type - machinery_data["cost"][plumbing_type] = plumbing_design_types[plumbing_type] + ui_interact(user) - // Update duct icon - var/image/duct_image = choices["fluid duct"] - duct_image.color = current_color +/obj/item/construction/plumbing/examine(mob/user) + . = ..() + . += "You can scroll your mouse wheel to change the piping layer." + . += "You can right click a fluid duct to set the Plumbing RPD to its color and layer." - var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - if(!choice || !check_menu(user)) +/obj/item/construction/plumbing/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "PlumbingService", name) + ui.open() + +/obj/item/construction/plumbing/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/plumbing), + ) + +/obj/item/construction/plumbing/ui_static_data(mob/user) + return list("paint_colors" = GLOB.pipe_paint_colors) + + +///find which category this design belongs to +/obj/item/construction/plumbing/proc/get_category(obj/machinery/recipe) + if(ispath(recipe, /obj/machinery/plumbing)) + var/obj/machinery/plumbing/plumbing_design = recipe + return initial(plumbing_design.category) + else if(ispath(recipe , /obj/machinery/duct)) + return "Distribution" + else + return "Storage" + +/obj/item/construction/plumbing/ui_data(mob/user) + var/list/data = list() + data["piping_layer"] = name_to_number[current_layer] //maps layer name to layer number's 1,2,3,4,5 + data["selected_color"] = current_color + data["layer_icon"] = "plumbing_layer[GLOB.plumbing_layers[current_layer]]" + data["selected_category"] = get_category(blueprint) + + var/list/category_list = list() + var/category_name = "" + var/obj/machinery/recipe = null + + for(var/i in 1 to plumbing_design_types.len) + recipe = plumbing_design_types[i] + + category_name = get_category(recipe) //get category of design + if(!category_list[category_name]) + var/list/item_list = list() + item_list["cat_name"] = category_name //used by RapidPipeDispenser.js + item_list["recipes"] = list() //used by RapidPipeDispenser.js + category_list[category_name] = item_list + + //add item to category + category_list[category_name]["recipes"] += list(list( + "index" = i, + "icon" = initial(recipe.icon_state), + "name" = initial(recipe.name), + "selected" = (initial(blueprint.name) == initial(recipe.name)) + )) + + data["categories"] = list() + for(category_name in category_list) + data["categories"] += list(category_list[category_name]) + + return data + +/obj/item/construction/plumbing/ui_act(action, params) + . = ..() + if(.) return - blueprint = name_to_type[choice] - playsound(src, 'sound/effects/pop.ogg', 50, FALSE) - to_chat(user, span_notice("You change [name]s blueprint to '[choice]'.")) + switch(action) + if("color") + var/color = params["paint_color"] + if(GLOB.pipe_paint_colors[color] != null) //validate if the color is in the allowed list of values + current_color = color + if("piping_layer") + var/bitflag = text2num(params["piping_layer"]) //convert from layer number back to layer string + bitflag = 1 << (bitflag - 1) + var/layer = GLOB.plumbing_layer_names["[bitflag]"] + if(layer != null) //validate if this value exists in the list + current_layer = layer + if("recipe") + var/design = plumbing_design_types[text2num(params["id"])] + if(design != null) //validate if design is valid + blueprint = design + playsound(src, 'sound/effects/pop.ogg', 50, vary = FALSE) + + return TRUE -/** - * Set the list of designs this plumbing rcd can make - */ -/obj/item/construction/plumbing/proc/set_plumbing_designs() - plumbing_design_types = list( - // Note that the list MUST include fluid ducts. - /obj/machinery/duct = 1, - /obj/machinery/plumbing/input = 5, - /obj/machinery/plumbing/output = 5, - /obj/machinery/plumbing/tank = 20, - /obj/machinery/plumbing/synthesizer = 15, - /obj/machinery/plumbing/reaction_chamber/chem = 15, - /obj/machinery/plumbing/buffer = 10, - //Above are the most common machinery which is shown on the first cycle. Keep new additions below THIS line, unless they're probably gonna be needed alot - /obj/machinery/plumbing/layer_manifold = 5, - /obj/machinery/plumbing/pill_press = 20, - /obj/machinery/plumbing/acclimator = 10, - /obj/machinery/plumbing/bottler = 50, - /obj/machinery/plumbing/disposer = 10, - /obj/machinery/plumbing/fermenter = 30, - /obj/machinery/plumbing/filter = 5, - /obj/machinery/plumbing/grinder_chemical = 30, - /obj/machinery/plumbing/liquid_pump = 35, - /obj/machinery/plumbing/splitter = 5, - /obj/machinery/plumbing/sender = 20, - /obj/machinery/plumbing/growing_vat = 20, - /obj/machinery/iv_drip/plumbing = 20 -) ///pretty much rcd_create, but named differently to make myself feel less bad for copypasting from a sibling-type /obj/item/construction/plumbing/proc/create_machine(atom/destination, mob/user) @@ -1253,8 +1335,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) return FALSE if(!canPlace(destination)) - var/obj/blueprint_type = blueprint - to_chat(user, span_notice("There is something blocking you from placing a [initial(blueprint_type.name)] there.")) + to_chat(user, span_notice("There is something blocking you from placing a [initial(blueprint.name)] there.")) return if(checkResource(machinery_data["cost"][blueprint], user) && blueprint) //"cost" is relative to delay at a rate of 10 matter/second (1matter/decisecond) rather than playing with 2 different variables since everyone set it to this rate anyways. @@ -1275,12 +1356,11 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) return FALSE . = TRUE - var/obj/blueprint_template = blueprint var/layer_id = GLOB.plumbing_layers[current_layer] for(var/obj/content_obj in destination.contents) // Let's not built ontop of dense stuff, if this is also dense. - if(initial(blueprint_template.density) && content_obj.density) + if(initial(blueprint.density) && content_obj.density) return FALSE // Ducts can overlap other plumbing objects IF the layers are different @@ -1296,6 +1376,17 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) if(duct_machine.duct_layer & layer_id) return FALSE +/obj/item/construction/plumbing/pre_attack_secondary(obj/machinery/target, mob/user, params) + if(!istype(target, /obj/machinery/duct)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/obj/machinery/duct/duct = target + if(duct.duct_layer && duct.duct_color) + current_color = GLOB.pipe_color_name[duct.duct_color] + current_layer = GLOB.plumbing_layer_names["[duct.duct_layer]"] + balloon_alert(user, "using [current_color], layer [current_layer]") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/item/construction/plumbing/afterattack(atom/target, mob/user, proximity) . = ..() if(!prox_check(proximity)) @@ -1312,70 +1403,8 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) create_machine(target, user) /obj/item/construction/plumbing/AltClick(mob/user) - // give a menu to pick layers or colors - var/list/options_menu = list( - "Current Layer" = image('icons/hud/radial.dmi', icon_state = "plumbing_layer[GLOB.plumbing_layers[current_layer]]"), - "Current Color" = image('icons/hud/radial.dmi', icon_state = current_color), - ) + ui_interact(user) - playsound(loc, 'sound/effects/pop.ogg', 50, FALSE) - var/choice = show_radial_menu(user, src, options_menu, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - if(!check_menu(user)) - return - - switch(choice) - if("Current Layer") - choose_layer_menu(user) - if("Current Color") - choose_color_menu(user) - -/** - * Choose the current layer via radial menu. - * - * Arguments: - * * user - current user. - */ -/obj/item/construction/plumbing/proc/choose_layer_menu(mob/user) - if(!GLOB.plumbing_layer_menu_options.len) - for(var/layer_name in GLOB.plumbing_layers) - GLOB.plumbing_layer_menu_options += list((layer_name) = image('icons/hud/radial.dmi', icon_state = "plumbing_layer[GLOB.plumbing_layers[layer_name]]")) - - playsound(loc, 'sound/effects/pop.ogg', 50, FALSE) - var/new_layer = show_radial_menu(user, src, GLOB.plumbing_layer_menu_options, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - if(!new_layer || !check_menu(user)) - return - - current_layer = new_layer - to_chat(user, span_notice("You set the layer to [new_layer].")) - -/** - * Choose the current color via radial menu. - * - * Arguments: - * * user - current user. - */ -/obj/item/construction/plumbing/proc/choose_color_menu(mob/user) - if(!GLOB.plumbing_color_menu_options.len) - for(var/color_name in GLOB.pipe_paint_colors) - GLOB.plumbing_color_menu_options += list((color_name) = image('icons/hud/radial.dmi', icon_state = color_name)) - - playsound(loc, 'sound/effects/pop.ogg', 50, FALSE) - var/new_color = show_radial_menu(user, src, GLOB.plumbing_color_menu_options, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - if(!new_color || !check_menu(user)) - return - - current_color = new_color - to_chat(user, span_notice("You set the color to [new_color].")) - -/** - * Choose layer via mouse wheel, like an RPD - * - * Arguments: - * * source - the user - * * A - the atom being selected, unused. - * * delta_x - X scroll delta - * * delta_y - Y scroll delta - */ /obj/item/construction/plumbing/proc/mouse_wheeled(mob/source, atom/A, delta_x, delta_y, params) SIGNAL_HANDLER if(source.incapacitated(IGNORE_RESTRAINTS|IGNORE_STASIS)) @@ -1406,17 +1435,22 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) /obj/item/construction/plumbing/research/set_plumbing_designs() plumbing_design_types = list( - /obj/machinery/duct = 1, - /obj/machinery/plumbing/input = 5, - /obj/machinery/plumbing/output = 5, - /obj/machinery/plumbing/tank = 20, - /obj/machinery/plumbing/acclimator = 10, - /obj/machinery/plumbing/filter = 5, + //category 1 synthesizers /obj/machinery/plumbing/reaction_chamber = 15, /obj/machinery/plumbing/grinder_chemical = 30, - /obj/machinery/plumbing/splitter = 5, /obj/machinery/plumbing/disposer = 10, - /obj/machinery/plumbing/growing_vat = 20 + /obj/machinery/plumbing/growing_vat = 20, + + //category 2 Distributors + /obj/machinery/duct = 1, + /obj/machinery/plumbing/input = 5, + /obj/machinery/plumbing/filter = 5, + /obj/machinery/plumbing/splitter = 5, + /obj/machinery/plumbing/output = 5, + + //category 3 storage + /obj/machinery/plumbing/tank = 20, + /obj/machinery/plumbing/acclimator = 10, ) /obj/item/construction/plumbing/service @@ -1427,25 +1461,33 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) /obj/item/construction/plumbing/service/set_plumbing_designs() plumbing_design_types = list( - /obj/machinery/duct = 1, - /obj/machinery/plumbing/input = 5, - /obj/machinery/plumbing/output/tap = 5, - /obj/machinery/plumbing/synthesizer/soda = 15, - /obj/machinery/plumbing/synthesizer/beer = 15, - /obj/machinery/plumbing/reaction_chamber = 15, - /obj/machinery/plumbing/buffer = 10, - /obj/machinery/plumbing/bottler = 50, - /obj/machinery/plumbing/tank = 20, - /obj/machinery/plumbing/filter = 5, - /obj/machinery/plumbing/layer_manifold = 5, - /obj/machinery/plumbing/acclimator = 10, - /obj/machinery/plumbing/fermenter = 30, - /obj/machinery/plumbing/grinder_chemical = 30, - /obj/machinery/plumbing/disposer = 10, - /obj/machinery/plumbing/sender = 20, + //category 1 synthesizers + /obj/machinery/plumbing/synthesizer/soda = 15, + /obj/machinery/plumbing/synthesizer/beer = 15, + /obj/machinery/plumbing/reaction_chamber = 15, + /obj/machinery/plumbing/buffer = 10, + /obj/machinery/plumbing/fermenter = 30, + /obj/machinery/plumbing/grinder_chemical = 30, + /obj/machinery/plumbing/disposer = 10, + + + //category 2 distributors + /obj/machinery/duct = 1, + /obj/machinery/plumbing/layer_manifold = 5, + /obj/machinery/plumbing/input = 5, + /obj/machinery/plumbing/filter = 5, + /obj/machinery/plumbing/splitter = 5, + /obj/machinery/plumbing/output/tap = 5, + /obj/machinery/plumbing/sender = 20, + + //category 3 storage + /obj/machinery/plumbing/bottler = 50, + /obj/machinery/plumbing/tank = 20, + /obj/machinery/plumbing/acclimator = 10, ) + /obj/item/rcd_upgrade name = "RCD advanced design disk" desc = "It seems to be empty." diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index b92bbc0a163..5540ee3dfc8 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -351,6 +351,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( for(var/i in 1 to cat.len) var/datum/pipe_info/info = cat[i] 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 data["categories"] += list(list("cat_name" = c, "recipes" = r)) var/list/init_directions = list("north" = FALSE, "south" = FALSE, "east" = FALSE, "west" = FALSE) diff --git a/code/modules/asset_cache/assets/plumbing.dm b/code/modules/asset_cache/assets/plumbing.dm new file mode 100644 index 00000000000..18e6801806c --- /dev/null +++ b/code/modules/asset_cache/assets/plumbing.dm @@ -0,0 +1,9 @@ +/datum/asset/spritesheet/plumbing + name = "plumbing-tgui" + +/datum/asset/spritesheet/plumbing/create_spritesheets() + InsertAll("", 'icons/obj/medical/iv_drip.dmi') + InsertAll("", 'icons/obj/plumbing/plumbers.dmi') + InsertAll("", 'icons/obj/plumbing/fluid_ducts.dmi') + InsertAll("", 'icons/hud/radial.dmi') + diff --git a/code/modules/plumbing/ducts.dm b/code/modules/plumbing/ducts.dm index 273f9f12853..e8982ef4f30 100644 --- a/code/modules/plumbing/ducts.dm +++ b/code/modules/plumbing/ducts.dm @@ -8,7 +8,6 @@ All the important duct code: icon = 'icons/obj/plumbing/fluid_ducts.dmi' icon_state = "nduct" layer = PLUMBING_PIPE_VISIBILE_LAYER - use_power = NO_POWER_USE ///bitfield with the directions we're connected in diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm index 7fe97c3e49a..bce4fcc1e3e 100644 --- a/code/modules/plumbing/plumbers/_plumb_machinery.dm +++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm @@ -14,6 +14,8 @@ var/buffer = 50 ///Flags for reagents, like INJECTABLE, TRANSPARENT bla bla everything thats in DEFINES/reagents.dm var/reagent_flags = TRANSPARENT + ///category for plumbing RCD + var/category = "" /obj/machinery/plumbing/Initialize(mapload, bolt = TRUE) . = ..() @@ -59,6 +61,9 @@ icon_state = "pipe_input" pass_flags_self = PASSMACHINE | LETPASSTHROW // Small reagent_flags = TRANSPARENT | REFILLABLE + ///category for plumbing RCD + category="Distribution" + /obj/machinery/plumbing/input/Initialize(mapload, bolt, layer) . = ..() @@ -71,6 +76,9 @@ icon_state = "pipe_output" pass_flags_self = PASSMACHINE | LETPASSTHROW // Small reagent_flags = TRANSPARENT | DRAINABLE + ///category for plumbing service rcd + category="Distribution" + /obj/machinery/plumbing/output/Initialize(mapload, bolt, layer) . = ..() @@ -80,12 +88,16 @@ name = "drinking tap" desc = "A manual output for plumbing systems, for taking drinks directly into glasses." icon_state = "tap_output" + ///category for plumbing RCD + category = "Distribution" /obj/machinery/plumbing/tank name = "chemical tank" desc = "A massive chemical holding tank." icon_state = "tank" buffer = 400 + ///category for plumbing RCD + category="Storage" /obj/machinery/plumbing/tank/Initialize(mapload, bolt, layer) . = ..() @@ -98,6 +110,8 @@ desc = "A plumbing manifold for layers." icon_state = "manifold" density = FALSE + ///category for plumbing service rcd + category="Distribution" /obj/machinery/plumbing/layer_manifold/Initialize(mapload, bolt, layer) . = ..() diff --git a/code/modules/plumbing/plumbers/acclimator.dm b/code/modules/plumbing/plumbers/acclimator.dm index 7cc83ca4f48..84501303775 100644 --- a/code/modules/plumbing/plumbers/acclimator.dm +++ b/code/modules/plumbing/plumbers/acclimator.dm @@ -12,6 +12,8 @@ base_icon_state = "acclimator" buffer = 200 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Storage" ///towards wich temperature do we build? var/target_temperature = 300 diff --git a/code/modules/plumbing/plumbers/bottler.dm b/code/modules/plumbing/plumbers/bottler.dm index 46a0e1d328d..933f89a0eff 100644 --- a/code/modules/plumbing/plumbers/bottler.dm +++ b/code/modules/plumbing/plumbers/bottler.dm @@ -8,6 +8,9 @@ reagent_flags = TRANSPARENT | DRAINABLE buffer = 100 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Storage" + ///how much do we fill var/wanted_amount = 10 ///where things are sent diff --git a/code/modules/plumbing/plumbers/destroyer.dm b/code/modules/plumbing/plumbers/destroyer.dm index e6aecd95bca..58a322fe34f 100644 --- a/code/modules/plumbing/plumbers/destroyer.dm +++ b/code/modules/plumbing/plumbers/destroyer.dm @@ -4,6 +4,9 @@ icon_state = "disposal" pass_flags_self = PASSMACHINE | LETPASSTHROW // Small active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Synthesizers" + ///we remove 5 reagents per second var/disposal_rate = 5 diff --git a/code/modules/plumbing/plumbers/fermenter.dm b/code/modules/plumbing/plumbers/fermenter.dm index b5d26ccbbc3..eccbc382eae 100644 --- a/code/modules/plumbing/plumbers/fermenter.dm +++ b/code/modules/plumbing/plumbers/fermenter.dm @@ -5,9 +5,13 @@ layer = ABOVE_ALL_MOB_LAYER plane = ABOVE_GAME_PLANE + reagent_flags = TRANSPARENT | DRAINABLE buffer = 400 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Synthesizers" + ///input dir var/eat_dir = SOUTH diff --git a/code/modules/plumbing/plumbers/filter.dm b/code/modules/plumbing/plumbers/filter.dm index 34b29325569..a085c255070 100644 --- a/code/modules/plumbing/plumbers/filter.dm +++ b/code/modules/plumbing/plumbers/filter.dm @@ -4,6 +4,8 @@ desc = "A chemical filter for filtering chemicals. The left and right outputs appear to be from the perspective of the input port." icon_state = "filter" density = FALSE + ///category for plumbing RCD + category="Distribution" ///whitelist of chems id's that go to the left side. Empty to disable port var/list/left = list() @@ -41,11 +43,11 @@ var/selected_reagent = tgui_input_list(usr, "Select [which] reagent", "Reagent", GLOB.chemical_name_list) if(!selected_reagent) return TRUE - + var/chem_id = get_chem_id(selected_reagent) if(!chem_id) return TRUE - + switch(which) if("left") if(!left.Find(chem_id)) diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm index 54a8b48f2d2..fcc5037c18f 100644 --- a/code/modules/plumbing/plumbers/grinder_chemical.dm +++ b/code/modules/plumbing/plumbers/grinder_chemical.dm @@ -9,6 +9,8 @@ buffer = 400 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 var/eat_dir = SOUTH + ///category for plumbing RCD + category="Synthesizers" /obj/machinery/plumbing/grinder_chemical/Initialize(mapload, bolt, layer) . = ..() diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm index 43c7e9cbc19..0e12f5228b6 100644 --- a/code/modules/plumbing/plumbers/pill_press.dm +++ b/code/modules/plumbing/plumbers/pill_press.dm @@ -5,6 +5,9 @@ icon_state = "pill_press" buffer = 60 //SKYRAT EDIT HYPOVIALS. This is needed so it can completely fill the vials up. active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Storage" + ///maximum size of a pill var/max_pill_volume = 50 ///maximum size of a patch diff --git a/code/modules/plumbing/plumbers/plumbing_buffer.dm b/code/modules/plumbing/plumbers/plumbing_buffer.dm index a04421a9e77..9a48407d4ad 100644 --- a/code/modules/plumbing/plumbers/plumbing_buffer.dm +++ b/code/modules/plumbing/plumbers/plumbing_buffer.dm @@ -8,6 +8,8 @@ icon_state = "buffer" pass_flags_self = PASSMACHINE | LETPASSTHROW // It looks short enough. buffer = 200 + ///category for plumbing RCD + category="Synthesizers" var/datum/buffer_net/buffer_net var/activation_volume = 100 diff --git a/code/modules/plumbing/plumbers/pumps.dm b/code/modules/plumbing/plumbers/pumps.dm index c10cacbc7ec..5dc246da533 100644 --- a/code/modules/plumbing/plumbers/pumps.dm +++ b/code/modules/plumbing/plumbers/pumps.dm @@ -8,6 +8,8 @@ anchored = FALSE density = TRUE use_power = NO_POWER_USE + ///category for plumbing RCD + category="Synthesizers" ///units we pump per second var/pump_power = 1 diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm index 823d889f4f4..b7061bd6363 100644 --- a/code/modules/plumbing/plumbers/reaction_chamber.dm +++ b/code/modules/plumbing/plumbers/reaction_chamber.dm @@ -7,6 +7,9 @@ buffer = 200 reagent_flags = TRANSPARENT | NO_REACT active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + ///category for plumbing RCD + category="Synthesizers" + /** * list of set reagents that the reaction_chamber allows in, and must all be present before mixing is enabled. * example: list(/datum/reagent/water = 20, /datum/reagent/fuel/oil = 50) diff --git a/code/modules/plumbing/plumbers/splitters.dm b/code/modules/plumbing/plumbers/splitters.dm index e18a3a49b05..1b704783c27 100644 --- a/code/modules/plumbing/plumbers/splitters.dm +++ b/code/modules/plumbing/plumbers/splitters.dm @@ -1,11 +1,13 @@ ///it splits the reagents however you want. So you can "every 60 units, 45 goes left and 15 goes straight". The side direction is EAST, you can change this in the component /obj/machinery/plumbing/splitter - name = "Chemical Splitter" + name = "chemical splitter" desc = "A chemical splitter for smart chemical factorization. Waits till a set of conditions is met and then stops all input and splits the buffer evenly or other in two ducts." icon_state = "splitter" active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 buffer = 100 density = FALSE + ///category for plumbing RCD + category="Distribution" ///constantly switches between TRUE and FALSE. TRUE means the batch tick goes straight, FALSE means the next batch goes in the side duct. var/turn_straight = TRUE diff --git a/code/modules/plumbing/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm index d3625e10148..228eb32f6d6 100644 --- a/code/modules/plumbing/plumbers/synthesizer.dm +++ b/code/modules/plumbing/plumbers/synthesizer.dm @@ -6,6 +6,10 @@ icon_state = "synthesizer" icon = 'icons/obj/plumbing/plumbers.dmi' active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 + + ///category for plumbing RCD + category="Synthesizers" + ///Amount we produce for every process. Ideally keep under 5 since thats currently the standard duct capacity var/amount = 1 ///I track them here because I have no idea how I'd make tgui loop like that diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm index 5956bf95436..35d46dd80a6 100644 --- a/code/modules/plumbing/plumbers/teleporter.dm +++ b/code/modules/plumbing/plumbers/teleporter.dm @@ -3,8 +3,9 @@ name = "chemical beacon" desc = "A bluespace anchor for chemicals. Does not require power. Use a multitool linked to a Chemical Recipient on this machine to start teleporting reagents." icon_state = "beacon" - density = FALSE + ///category for plumbing RCD + category="Distribution" ///whoever we teleport our chems to var/obj/machinery/plumbing/receiver/target = null diff --git a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm index 4daae8a520a..204658fd447 100644 --- a/code/modules/research/xenobiology/vatgrowing/vatgrower.dm +++ b/code/modules/research/xenobiology/vatgrowing/vatgrower.dm @@ -4,6 +4,10 @@ desc = "Tastes just like the chef's soup." icon_state = "growing_vat" buffer = 300 + ///category for plumbing RCD + category = "Synthesizers" + + ///List of all microbiological samples in this soup. var/datum/biological_sample/biological_sample ///If the vat will restart the sample upon completion diff --git a/tgstation.dme b/tgstation.dme index 886a69da408..8be0be575ad 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2598,6 +2598,7 @@ #include "code\modules\asset_cache\assets\pills.dm" #include "code\modules\asset_cache\assets\pipes.dm" #include "code\modules\asset_cache\assets\plane_debug.dm" +#include "code\modules\asset_cache\assets\plumbing.dm" #include "code\modules\asset_cache\assets\portraits.dm" #include "code\modules\asset_cache\assets\radar.dm" #include "code\modules\asset_cache\assets\research_designs.dm" diff --git a/tgui/packages/tgui/interfaces/PlumbingService.tsx b/tgui/packages/tgui/interfaces/PlumbingService.tsx new file mode 100644 index 00000000000..87e54a2c09b --- /dev/null +++ b/tgui/packages/tgui/interfaces/PlumbingService.tsx @@ -0,0 +1,152 @@ +import { BooleanLike, classes } from 'common/react'; +import { Window } from '../layouts'; +import { useBackend, useLocalState } from '../backend'; +import { Section, Tabs, Button, Stack, Box } from '../components'; +import { ColorItem, LayerSelect } from './RapidPipeDispenser'; +import { capitalizeAll } from 'common/string'; + +type Data = { + layer_icon: string; + categories: Category[]; + selected_category: string; +}; + +type Category = { + cat_name: string; + recipes: Recipe[]; + active: BooleanLike; +}; + +type Recipe = { + index: number; + icon: string; + selected: BooleanLike; + name: string; +}; + +const PlumbingTypeSection = (props, context) => { + const { act, data } = useBackend(context); + const { categories = [], selected_category } = data; + const [categoryName, setCategoryName] = useLocalState( + context, + 'categoryName', + selected_category + ); + const shownCategory = + categories.find((category) => category.cat_name === categoryName) || + categories[0]; + return ( +
+ + {categories.map((category) => ( + setCategoryName(category.cat_name)}> + {category.cat_name} + + ))} + + {shownCategory?.recipes.map((recipe) => ( + + ))} +
+ ); +}; + +const ColorSection = (props, context) => { + return ( +
+ +
+ ); +}; + +const LayerSection = (props, context) => { + return ( +
+ +
+ ); +}; + +const LayerIconSection = (props, context) => { + const { data } = useBackend(context); + const { layer_icon } = data; + return ( +
+ +
+ ); +}; + +export const PlumbingService = (props, context) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/RapidPipeDispenser.js b/tgui/packages/tgui/interfaces/RapidPipeDispenser.js index 860cc5b2b44..f3f91b2ee41 100644 --- a/tgui/packages/tgui/interfaces/RapidPipeDispenser.js +++ b/tgui/packages/tgui/interfaces/RapidPipeDispenser.js @@ -105,7 +105,6 @@ const CategoryItem = (props, context) => { }; const SelectionSection = (props, context) => { - const { act, data } = useBackend(context); return (
@@ -141,7 +140,6 @@ export const LayerSelect = (props, context) => { const PreviewSelect = (props, context) => { const { act, data } = useBackend(context); - const { category: rootCategoryIndex } = data; const previews = data.preview_rows.flatMap((row) => row.previews); return ( @@ -178,9 +176,8 @@ const PreviewSelect = (props, context) => { }; const LayerSection = (props, context) => { - const { act, data } = useBackend(context); + const { data } = useBackend(context); const { category: rootCategoryIndex, piping_layer } = data; - const previews = data.preview_rows.flatMap((row) => row.previews); return (
{rootCategoryIndex === 0 && } @@ -192,9 +189,11 @@ const LayerSection = (props, context) => { const PipeTypeSection = (props, context) => { const { act, data } = useBackend(context); const { categories = [] } = data; + const { selected_category } = data; const [categoryName, setCategoryName] = useLocalState( context, - 'categoryName' + 'categoryName', + selected_category ); const shownCategory = categories.find((category) => category.cat_name === categoryName) || @@ -236,7 +235,6 @@ const PipeTypeSection = (props, context) => { export const SmartPipeBlockSection = (props, context) => { const { act, data } = useBackend(context); const init_directions = data.init_directions || []; - const { category: rootCategoryIndex } = data; return (
@@ -314,7 +312,7 @@ export const SmartPipeBlockSection = (props, context) => { }; export const RapidPipeDispenser = (props, context) => { - const { act, data } = useBackend(context); + const { data } = useBackend(context); const { category: rootCategoryIndex } = data; return (