diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 2d8c9ee1163..b60f2436d14 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -308,8 +308,11 @@ radio_filter_in = frequency==1439?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==1439?(RADIO_TO_AIRALARM):null if(frequency) - radio_connection = register_radio(src, frequency, frequency, radio_filter_in) - src.broadcast_status() + set_frequency(frequency) + +/obj/machinery/atmospherics/unary/vent_pump/proc/set_frequency(new_frequency) + radio_connection = register_radio(src, frequency, new_frequency, radio_filter_in) + frequency = new_frequency /obj/machinery/atmospherics/unary/vent_pump/receive_signal(datum/signal/signal) if(stat & (NOPOWER|BROKEN)) @@ -407,6 +410,20 @@ else 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) + return TRUE else ..() diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 229412e93f0..1c22cf8a7c4 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -8,6 +8,7 @@ holder_type = /obj/machinery/door/airlock wire_count = 12 proper_name = "Airlock" + tgui_template = "WiresAirlock" /datum/wires/airlock/interactable(mob/user) var/obj/machinery/door/airlock/A = holder @@ -41,6 +42,39 @@ . += "The 'Check Timing Mechanism' light is [(A.normalspeed == 0 && haspower) ? "on" : "off"]." . += "The IDScan light is [(A.aiDisabledIdScanner == 0 && haspower) ? "on" : "off."]" +/datum/wires/airlock/tgui_data(mob/user) + var/list/data = ..() + + var/obj/machinery/door/airlock/A = holder + data["id_tag"] = A.id_tag + data["frequency"] = A.radio_connection ? A.frequency : null + data["min_freq"] = RADIO_LOW_FREQ + data["max_freq"] = RADIO_HIGH_FREQ + + return data + +/datum/wires/airlock/tgui_act(action, list/params) + . = ..() + if(.) + return + + var/obj/machinery/door/airlock/A = holder + + switch(action) + if("set_id_tag") + var/new_id = tgui_input_text(usr, "Enter a new ID tag for [A]", "[A] ID Tag", A.id_tag, 30, FALSE, TRUE) + if(new_id) + A.id_tag = new_id + return TRUE + + if("set_frequency") + A.set_frequency(sanitize_frequency(text2num(params["freq"]), RADIO_LOW_FREQ, RADIO_HIGH_FREQ)) + return TRUE + + if("clear_frequency") + A.set_frequency(null) + return TRUE + /datum/wires/airlock/on_cut(wire, mend) var/obj/machinery/door/airlock/A = holder switch(wire) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 03ffdb8ecbf..b0b0e738cf9 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -9,6 +9,8 @@ /// The display name for the TGUI window. For example, given the var is "APC"... /// When the TGUI window is opened, "wires" will be appended to it's title, and it would become "APC wires". var/proper_name = "Unknown" + /// The template to use for TGUI. + var/tgui_template = "Wires" /// The total number of wires that our holder atom has. var/wire_count = NONE /// A list of all wires. For a list of valid wires defines that can go here, see `code/__DEFINES/wires.dm` @@ -92,7 +94,7 @@ /datum/wires/tgui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "Wires", "[proper_name] wires") + ui = new(user, src, tgui_template, "[proper_name] wires") ui.open() /datum/wires/tgui_state(mob/user) diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 5301aa56613..9ebdc878cdb 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -125,10 +125,12 @@ return /obj/machinery/door/airlock/proc/set_frequency(new_frequency) + radio_connection = null radio_controller.remove_object(src, frequency) + frequency = new_frequency + if(new_frequency) - frequency = new_frequency - radio_connection = radio_controller.add_object(src, frequency, RADIO_AIRLOCK) + radio_connection = radio_controller.add_object(src, new_frequency, RADIO_AIRLOCK) /obj/machinery/door/airlock/Initialize() @@ -152,6 +154,7 @@ anchored = TRUE power_channel = ENVIRON + circuit = /obj/item/circuitboard/airlock_cycling var/id_tag var/master_tag @@ -165,6 +168,9 @@ var/previousPressure /obj/machinery/airlock_sensor/update_icon() + if(panel_open) + icon_state = "airlock_sensor_open" + return if(on) if(alert) icon_state = "airlock_sensor_alert" @@ -216,6 +222,45 @@ radio_controller.remove_object(src,frequency) return ..() +/obj/machinery/airlock_sensor/examine(mob/user, infix, suffix) + . = ..() + if(in_range(src, user)) + . += "It has a master tag of \"[master_tag]\"." + . += "It has an ID tag of \"[id_tag]\"." + . += "It has a frequency of [frequency]." + . += "It has a command of \"[command]\"." + if(panel_open) + . += "It's panel is open." + +/obj/machinery/airlock_sensor/attackby(obj/item/I, mob/user) + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + if(I.has_tool_quality(TOOL_MULTITOOL)) + var/choice = tgui_alert(user, "What would you like to configure?", "[src] Configuration", list("Master Tag", "ID Tag", "Frequency", "Command", "None")) + switch(choice) + if("Master Tag") + var/new_value = tgui_input_text(user, "The current master tag is \"[master_tag]\", what would you like it to be?", "[src] Master Tag", master_tag, 30, encode = TRUE) + if(new_value) + master_tag = new_value + if("ID Tag") + var/new_value = tgui_input_text(user, "The current id tag is \"[id_tag]\", what would you like it to be?", "[src] ID Tag", id_tag, 30, encode = TRUE) + if(new_value) + id_tag = new_value + 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("Command") + var/new_value = tgui_input_text(user, "The current command is \"[command]\", what would you like it to be? Valid options include: cycle, cycle_interior, cycle_exterior.", "[src] command", command, encode = TRUE) + if(new_value) + command = new_value + + return TRUE + return ..() + /obj/machinery/airlock_sensor/airlock_interior command = "cycle_interior" @@ -237,6 +282,7 @@ anchored = TRUE power_channel = ENVIRON + circuit = /obj/item/circuitboard/airlock_cycling var/master_tag var/frequency = 1449 @@ -246,18 +292,50 @@ var/on = 1 - /obj/machinery/access_button/update_icon() - if(on) + if(panel_open) + icon_state = "access_button_open" + else if(on) icon_state = "access_button_standby" else icon_state = "access_button_off" +/obj/machinery/access_button/examine(mob/user, infix, suffix) + . = ..() + if(in_range(src, user)) + . += "It has a master tag of \"[master_tag]\"." + . += "It has a frequency of \"[frequency]\"." + . += "It is sending a command of \"[command]\"." + if(panel_open) + . += "It's panel is open." + /obj/machinery/access_button/attackby(obj/item/I as obj, mob/user as mob) //Swiping ID on the access button if (istype(I, /obj/item/card/id) || istype(I, /obj/item/pda)) attack_hand(user) return + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + if(I.has_tool_quality(TOOL_MULTITOOL)) + var/choice = tgui_alert(user, "What would you like to change?", "[src] Settings", list("Tag", "Frequency", "Command", "None")) + switch(choice) + if("Tag") + var/new_id = tgui_input_text(user, "[src] has an master tag of \"[master_tag]\". What would you like it to be?", "[src] ID", master_tag, 30, FALSE, TRUE) + if(new_id) + master_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) + if("Command") + var/new_command = tgui_input_text(user, "[src] has a command of \"[command]\". Valid options include: cycle, cycle_interior, cycle_exterior", "[src] command", command, encode = TRUE) + if(new_command) + command = new_command + + return TRUE ..() /obj/machinery/access_button/attack_hand(mob/user) diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 879b532b08a..55e7d97ed20 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -17,6 +17,8 @@ valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure") layer = ABOVE_WINDOW_LAYER + var/deconstructable = FALSE + /obj/machinery/embedded_controller/radio/airlock/Destroy() // TODO - Leshana - Implement dummy terminals //for(var/thing in dummy_terminals) @@ -30,12 +32,75 @@ if(!allowed(user)) return min(STATUS_UPDATE, .) +/obj/machinery/embedded_controller/radio/airlock/attackby(obj/item/I, mob/user) + if(deconstructable) + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + . = ..() + +/obj/machinery/embedded_controller/radio/airlock/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) + var/list/data = ..() + + data["panel_open"] = panel_open + data["tags"] = null + + data["frequency"] = null + data["min_freq"] = null + data["max_freq"] = null + + if(panel_open) + var/datum/embedded_program/airlock/airlock_program = program + data["tags"] = airlock_program.get_all_tags() + + data["frequency"] = frequency + data["min_freq"] = RADIO_LOW_FREQ + data["max_freq"] = RADIO_HIGH_FREQ + + return data + +/obj/machinery/embedded_controller/radio/airlock/tgui_act(action, params) + . = ..() + if(.) + return + + if(!panel_open) + return + + switch(action) + if("edit_tag") + var/datum/embedded_program/airlock/airlock_program = program + + var/tag = params["tag"] + var/current = airlock_program.get_tag(tag) + var/new_tag = tgui_input_text(usr, "What would you like to set [tag] to?", "New [tag]?", current, 30, FALSE, TRUE) + + if(new_tag) + airlock_program.set_tag(tag, new_tag) + return TRUE + + if("set_frequency") + set_frequency(sanitize_frequency(text2num(params["freq"]), RADIO_LOW_FREQ, RADIO_HIGH_FREQ)) + return TRUE + + +/obj/machinery/embedded_controller/radio/airlock/update_icon() + cut_overlays() + if(panel_open) + add_overlay("airlock_control_open") + //Advanced airlock controller for when you want a more versatile airlock controller - useful for turning simple access control rooms into airlocks /obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller name = "Advanced Airlock Controller" + deconstructable = TRUE + circuit = /obj/item/circuitboard/airlock_cycling /obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/tgui_data(mob/user) - . = list( + var/list/data = ..() + + // Deliberately not using UNTYPED_LIST_ADD, we want this to be appended + data += list( "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]), "external_pressure" = round(program.memory["external_sensor_pressure"]), "internal_pressure" = round(program.memory["internal_sensor_pressure"]), @@ -45,15 +110,22 @@ "internalTemplateName" = "AirlockConsoleAdvanced", ) + return data + //Airlock controller for airlock control - most airlocks on the station use this /obj/machinery/embedded_controller/radio/airlock/airlock_controller name = "Airlock Controller" tag_secure = 1 valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort") + deconstructable = TRUE + circuit = /obj/item/circuitboard/airlock_cycling /obj/machinery/embedded_controller/radio/airlock/airlock_controller/tgui_data(mob/user) - . = list( + var/list/data = ..() + + // Deliberately not using UNTYPED_LIST_ADD, we want this to be appended + data += list( "chamber_pressure" = round(program.memory["chamber_sensor_pressure"]), "exterior_status" = program.memory["exterior_status"], "interior_status" = program.memory["interior_status"], @@ -61,6 +133,8 @@ "internalTemplateName" = "AirlockConsoleSimple", ) + return data + //Access controller for door control - used in virology and the like /obj/machinery/embedded_controller/radio/airlock/access_controller icon = 'icons/obj/airlock_machines.dmi' @@ -69,7 +143,8 @@ name = "Access Controller" tag_secure = 1 valid_actions = list("cycle_ext_door", "cycle_int_door", "force_ext", "force_int") - + deconstructable = TRUE + circuit = /obj/item/circuitboard/airlock_cycling /obj/machinery/embedded_controller/radio/airlock/access_controller/update_icon() if(on && program) @@ -81,9 +156,14 @@ icon_state = "access_control_off" /obj/machinery/embedded_controller/radio/airlock/access_controller/tgui_data(mob/user) - . = list( + var/list/data = ..() + + // Deliberately not using UNTYPED_LIST_ADD, we want this to be appended + data += list( "exterior_status" = program.memory["exterior_status"], "interior_status" = program.memory["interior_status"], "processing" = program.memory["processing"], "internalTemplateName" = "DoorAccessConsole", ) + + return data diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index 90558cf6227..93d8b7ed71e 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -414,6 +414,55 @@ send an additional command to open the door again. if(doorCommand) signalDoor(doorTag, doorCommand) +/datum/embedded_program/airlock/proc/get_all_tags() + return list( + "id_tag" = id_tag, + "tag_exterior_door" = tag_exterior_door, + "tag_interior_door" = tag_interior_door, + "tag_airpump" = tag_airpump, + "tag_chamber_sensor" = tag_chamber_sensor, + "tag_exterior_sensor" = tag_exterior_sensor, + "tag_interior_sensor" = tag_interior_sensor, + "tag_airlock_mech_sensor" = tag_airlock_mech_sensor, + "tag_shuttle_mech_sensor" = tag_shuttle_mech_sensor + ) + +/datum/embedded_program/airlock/proc/get_tag(tag_name) + switch(tag_name) + if("id_tag") . = id_tag + if("tag_exterior_door") . = tag_exterior_door + if("tag_interior_door") . = tag_interior_door + if("tag_airpump") . = tag_airpump + if("tag_chamber_sensor") . = tag_chamber_sensor + if("tag_exterior_sensor") . = tag_exterior_sensor + if("tag_interior_sensor") . = tag_interior_sensor + if("tag_airlock_mech_sensor") . = tag_airlock_mech_sensor + if("tag_shuttle_mech_sensor") . = tag_shuttle_mech_sensor + +/datum/embedded_program/airlock/proc/set_tag(tag_name, new_tag) + switch(tag_name) + if("id_tag") + id_tag = new_tag + if("tag_exterior_door") + tag_exterior_door = new_tag + signalDoor(tag_exterior_door, "update") + if("tag_interior_door") + tag_interior_door = new_tag + signalDoor(tag_interior_door, "update") + if("tag_airpump") + tag_airpump = new_tag + if("tag_chamber_sensor") + tag_chamber_sensor = new_tag + if("tag_exterior_sensor") + tag_exterior_sensor = new_tag + if("tag_interior_sensor") + tag_interior_sensor = new_tag + if("tag_airlock_mech_sensor") + tag_airlock_mech_sensor = new_tag + if("tag_shuttle_mech_sensor") + tag_shuttle_mech_sensor = new_tag + + #undef SKIPCYCLE_MARGIN #undef MIN_TARGET_PRESSURE @@ -424,4 +473,4 @@ send an additional command to open the door again. #undef TARGET_NONE #undef TARGET_INOPEN -#undef TARGET_OUTOPEN \ No newline at end of file +#undef TARGET_OUTOPEN diff --git a/code/game/machinery/embedded_controller/construction.dm b/code/game/machinery/embedded_controller/construction.dm new file mode 100644 index 00000000000..0a75ae3f0d5 --- /dev/null +++ b/code/game/machinery/embedded_controller/construction.dm @@ -0,0 +1,44 @@ +/obj/item/circuitboard/airlock_cycling + name = T_BOARD("cycling airlock button") + build_path = /obj/machinery/access_button + board_type = new /datum/frame/frame_types/button + matter = list(MAT_STEEL = 50, MAT_GLASS = 50) + +/datum/design/circuit/airlock_cycling + name = "Machine Design (Cycling Airlock Board)" + desc = "The circuit board for cycling airlock parts." + id = "airlock_cycling" + build_path = /obj/item/circuitboard/airlock_cycling + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2) + sort_string = "MAAAD" + +/obj/item/circuitboard/airlock_cycling/attackby(obj/item/I as obj, mob/user as mob) + if(I.has_tool_quality(TOOL_MULTITOOL)) + var/result = tgui_input_list( + user, + "What do you want to reconfigure the board to?", + "Multitool-Circuitboard interface", + list( + "Button", + "Sensor", + "Controller - Standard", + "Controller - Advanced", + "Controller - Access", + )) + switch(result) + if("Button") + name = T_BOARD("cycling airlock button") + build_path = /obj/machinery/access_button + if("Sensor") + name = T_BOARD("cycling airlock sensor") + build_path = /obj/machinery/airlock_sensor + if("Controller - Standard") + name = T_BOARD("cycling airlock controller (simple)") + build_path = /obj/machinery/embedded_controller/radio/airlock/airlock_controller + if("Controller - Advanced") + name = T_BOARD("cycling airlock controller (advanced)") + build_path = /obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller + if("Controller - Access") + name = T_BOARD("cycling airlock controller (access)") + build_path = /obj/machinery/embedded_controller/radio/airlock/access_controller + return diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index f534ccd832a..c92cbdd650e 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -17,6 +17,11 @@ qdel(program) // the program will clear the ref in its Destroy return ..() +/obj/machinery/embedded_controller/examine(mob/user, infix, suffix) + . = ..() + if(in_range(src, user)) + . += "It has an ID tag of \"[program?.id_tag]\"" + /obj/machinery/embedded_controller/proc/post_signal(datum/signal/signal, comm_line) return 0 @@ -36,6 +41,7 @@ if(LAZYLEN(valid_actions)) if(action in valid_actions) program.receive_user_command(action) + return TRUE if(ui.user) add_fingerprint(ui.user) diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index ab1fe6aa501..003fad71082 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -31,6 +31,14 @@ type = replacetext(type, " ", "_") return "[type]_[state]" +/datum/frame/frame_types/button + name = "Button" + frame_class = FRAME_CLASS_ALARM + frame_size = 1 + frame_style = FRAME_STYLE_WALL + x_offset = 24 + y_offset = 24 + /datum/frame/frame_types/computer name = "Computer" icon_override = 'icons/obj/stock_parts_vr.dmi' //VOREStation Edit @@ -208,14 +216,6 @@ circuit = /obj/machinery/atmospheric_field_generator frame_size = 3 -/datum/frame/frame_types/electrochromic_button - name = "Electrochromic Window Button" - frame_class = FRAME_CLASS_ALARM - frame_size = 1 - frame_style = FRAME_STYLE_WALL - x_offset = 24 - y_offset = 24 - ////////////////////////////// // Frame Object (Structure) ////////////////////////////// diff --git a/code/game/objects/items/weapons/circuitboards/frame.dm b/code/game/objects/items/weapons/circuitboards/frame.dm index 10b9b00771a..02f011ab67e 100644 --- a/code/game/objects/items/weapons/circuitboards/frame.dm +++ b/code/game/objects/items/weapons/circuitboards/frame.dm @@ -84,7 +84,7 @@ /obj/item/circuitboard/electrochromic name = T_BOARD("electrochromic button") build_path = /obj/machinery/button/windowtint - board_type = new /datum/frame/frame_types/electrochromic_button + board_type = new /datum/frame/frame_types/button matter = list(MAT_STEEL = 50, "glass" = 50) //Computer diff --git a/code/modules/economy/vending_machines.dm b/code/modules/economy/vending_machines.dm index 4663e9bb54f..dcd6b42cd6d 100644 --- a/code/modules/economy/vending_machines.dm +++ b/code/modules/economy/vending_machines.dm @@ -689,6 +689,7 @@ /obj/item/multitool = 4, /obj/item/cell/high = 10, /obj/item/airlock_electronics = 10, + /obj/item/circuitboard/airlock_cycling = 20, /obj/item/module/power_control = 10, /obj/item/circuitboard/airalarm = 10, /obj/item/circuitboard/firealarm = 10, diff --git a/icons/obj/airlock_machines.dmi b/icons/obj/airlock_machines.dmi index 1f22e8e1989..9a24724c815 100644 Binary files a/icons/obj/airlock_machines.dmi and b/icons/obj/airlock_machines.dmi differ diff --git a/icons/obj/stock_parts.dmi b/icons/obj/stock_parts.dmi index 30baa36e3cd..dcb032ca655 100644 Binary files a/icons/obj/stock_parts.dmi and b/icons/obj/stock_parts.dmi differ diff --git a/icons/obj/stock_parts_vr.dmi b/icons/obj/stock_parts_vr.dmi index 8e48a4c0a30..6a90bf44852 100644 Binary files a/icons/obj/stock_parts_vr.dmi and b/icons/obj/stock_parts_vr.dmi differ diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleAdvanced.tsx b/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleAdvanced.tsx index 0977fc9d54d..15e7f9b2c89 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleAdvanced.tsx +++ b/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleAdvanced.tsx @@ -1,6 +1,7 @@ import { useBackend } from '../../backend'; import { Box, Button, Section } from '../../components'; import { StandardControls, StatusDisplay } from './EmbeddedControllerHelpers'; +import { PanelOpen } from './PanelOpen'; import { AirlockConsoleAdvancedData } from './types'; /** @@ -12,8 +13,13 @@ import { AirlockConsoleAdvancedData } from './types'; export const AirlockConsoleAdvanced = (props) => { const { act, data } = useBackend(); - const { external_pressure, chamber_pressure, internal_pressure, processing } = - data; + const { + external_pressure, + chamber_pressure, + internal_pressure, + processing, + panel_open, + } = data; const pressure_range = { external_pressure, @@ -59,27 +65,31 @@ export const AirlockConsoleAdvanced = (props) => { return ( <> -
- - - - - - - - -
+ {panel_open ? ( + + ) : ( +
+ + + + + + + + +
+ )} ); }; diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleSimple.tsx b/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleSimple.tsx index bed9c734727..c97e0854cc6 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleSimple.tsx +++ b/tgui/packages/tgui/interfaces/EmbeddedController/AirlockConsoleSimple.tsx @@ -1,6 +1,7 @@ import { useBackend } from '../../backend'; import { Box, Button, Section } from '../../components'; import { StandardControls, StatusDisplay } from './EmbeddedControllerHelpers'; +import { PanelOpen } from './PanelOpen'; import { AirlockConsoleSimpleData } from './types'; /** @@ -12,8 +13,13 @@ import { AirlockConsoleSimpleData } from './types'; export const AirlockConsoleSimple = (props) => { const { act, data } = useBackend(); - const { exterior_status, chamber_pressure, processing, interior_status } = - data; + const { + exterior_status, + chamber_pressure, + processing, + interior_status, + panel_open, + } = data; const status_range = { interior_status, exterior_status }; @@ -37,19 +43,23 @@ export const AirlockConsoleSimple = (props) => { return ( <> -
- - - - -
+ {panel_open ? ( + + ) : ( +
+ + + + +
+ )} ); }; diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/DoorAccessConsole.tsx b/tgui/packages/tgui/interfaces/EmbeddedController/DoorAccessConsole.tsx index 9de6aa36c5f..bd4963fde33 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/DoorAccessConsole.tsx +++ b/tgui/packages/tgui/interfaces/EmbeddedController/DoorAccessConsole.tsx @@ -1,5 +1,6 @@ import { useBackend } from '../../backend'; import { Button, LabeledList, Section } from '../../components'; +import { PanelOpen } from './PanelOpen'; import { DoorAccessConsoleData } from './types'; /** @@ -9,7 +10,7 @@ import { DoorAccessConsoleData } from './types'; export const DoorAccessConsole = (props) => { const { act, data } = useBackend(); - const { interior_status, exterior_status } = data; + const { interior_status, exterior_status, panel_open } = data; const interiorOpen = interior_status.state === 'open' || exterior_status.state === 'closed'; @@ -17,39 +18,42 @@ export const DoorAccessConsole = (props) => { exterior_status.state === 'open' || interior_status.state === 'closed'; return ( -
- {/* Interior Button */} - - {/* Exterior Button */} - - - } - > - - - {exterior_status.state === 'closed' ? 'Locked' : 'Open'} - - - {interior_status.state === 'closed' ? 'Locked' : 'Open'} - - -
+ <> +
+ {/* Interior Button */} + + {/* Exterior Button */} + + + } + > + + + {exterior_status.state === 'closed' ? 'Locked' : 'Open'} + + + {interior_status.state === 'closed' ? 'Locked' : 'Open'} + + +
+ {!!panel_open && } + ); }; diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/PanelOpen.tsx b/tgui/packages/tgui/interfaces/EmbeddedController/PanelOpen.tsx new file mode 100644 index 00000000000..c02bbb78073 --- /dev/null +++ b/tgui/packages/tgui/interfaces/EmbeddedController/PanelOpen.tsx @@ -0,0 +1,57 @@ +import { round, toFixed } from 'common/math'; +import { useBackend } from 'tgui/backend'; +import { + Box, + Button, + LabeledList, + NumberInput, + Section, +} from 'tgui-core/components'; + +import { PanelOpenData } from './types'; + +export const PanelOpen = (props) => { + const { act, data } = useBackend(); + + const { panel_open, tags, frequency, min_freq, max_freq } = data; + + if (!panel_open || !tags) { + return null; + } + + return ( +
+ + + toFixed(val, 1)} + onDrag={(freq) => + act('set_frequency', { freq: round(freq * 10, 0) }) + } + /> + + {Object.entries(tags).map(([tag, value]) => ( + act('edit_tag', { tag })}> + Edit + + } + > + {value || Unset} + + ))} + +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/index.tsx b/tgui/packages/tgui/interfaces/EmbeddedController/index.tsx index eb4504e3510..e7f289bd1cb 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/index.tsx +++ b/tgui/packages/tgui/interfaces/EmbeddedController/index.tsx @@ -98,7 +98,7 @@ export const EmbeddedController = (props) => { } return ( - + {Component} ); diff --git a/tgui/packages/tgui/interfaces/EmbeddedController/types.ts b/tgui/packages/tgui/interfaces/EmbeddedController/types.ts index d6b9c374873..fc343d0a632 100644 --- a/tgui/packages/tgui/interfaces/EmbeddedController/types.ts +++ b/tgui/packages/tgui/interfaces/EmbeddedController/types.ts @@ -44,7 +44,7 @@ export type AirlockConsoleAdvancedData = { purge: BooleanLike; secure: BooleanLike; internalTemplateName: string; -}; +} & PanelOpenData; export type AirlockConsoleSimpleData = { chamber_pressure: number; @@ -52,7 +52,7 @@ export type AirlockConsoleSimpleData = { interior_status: status; processing: BooleanLike; internalTemplateName: string; -}; +} & PanelOpenData; export type AirlockConsolePhoronData = { chamber_pressure: number; @@ -68,7 +68,7 @@ export type DoorAccessConsoleData = { interior_status: status; processing: BooleanLike; internalTemplateName: string; -}; +} & PanelOpenData; export type EscapePodConsoleData = { docking_status: string; @@ -80,3 +80,11 @@ export type EscapePodConsoleData = { }; export type status = { state: string; lock: string }; + +export type PanelOpenData = { + panel_open: BooleanLike; + tags: Record | null; + frequency: number; + min_freq: number; + max_freq: number; +}; diff --git a/tgui/packages/tgui/interfaces/Wires.tsx b/tgui/packages/tgui/interfaces/Wires.tsx index e197b966182..7b771bf3942 100644 --- a/tgui/packages/tgui/interfaces/Wires.tsx +++ b/tgui/packages/tgui/interfaces/Wires.tsx @@ -1,10 +1,9 @@ import { BooleanLike } from 'common/react'; +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { Box, Button, LabeledList, Section } from 'tgui-core/components'; -import { useBackend } from '../backend'; -import { Box, Button, LabeledList, Section } from '../components'; -import { Window } from '../layouts'; - -type Data = { +export type WireData = { wires: { seen_color: string; color_name: string; @@ -17,71 +16,88 @@ type Data = { }; export const Wires = (props) => { - const { act, data } = useBackend(); + const { data } = useBackend(); + const { wires = [] } = data; + + return ( + + + + + + + ); +}; + +export const WiresWires = (props) => { + const { act, data } = useBackend(); const { wires = [] } = data; const statuses = data.status || []; return ( - - -
- - {wires.map((wire) => ( - - - - - - } - > - {!!wire.wire && ({wire.wire})} - - ))} - -
- - {!!statuses.length && ( -
- {statuses.map((status) => ( - - {status} - - ))} -
- )} -
-
+
+ + {wires.map((wire) => ( + + + + + + } + > + {!!wire.wire && ({wire.wire})} + + ))} + +
); }; + +export const WiresStatus = (props) => { + const { act, data } = useBackend(); + + const { wires = [] } = data; + const statuses = data.status || []; + + return statuses.length ? ( +
+ {statuses.map((status) => ( + + {status} + + ))} +
+ ) : null; +}; diff --git a/tgui/packages/tgui/interfaces/WiresAirlock.tsx b/tgui/packages/tgui/interfaces/WiresAirlock.tsx new file mode 100644 index 00000000000..eda4886a3bb --- /dev/null +++ b/tgui/packages/tgui/interfaces/WiresAirlock.tsx @@ -0,0 +1,81 @@ +import { round } from 'common/math'; +import { useBackend } from 'tgui/backend'; +import { Window } from 'tgui/layouts'; +import { + Box, + Button, + LabeledList, + NumberInput, + Section, +} from 'tgui-core/components'; + +import { WireData, WiresStatus, WiresWires } from './Wires'; + +type WiresAirlockData = WireData & { + id_tag: string; + frequency: number | null; + min_freq: number; + max_freq: number; +}; + +export const WiresAirlock = (props) => { + const { act, data } = useBackend(); + const { wires = [], id_tag, frequency, min_freq, max_freq } = data; + + return ( + + +
+ + act('set_id_tag')}> + Edit + + } + > + {id_tag || None Set} + + act('clear_frequency')}> + Clear + + ) : null + } + > + {frequency ? ( + val.toFixed(1)} + onChange={(freq) => + act('set_frequency', { freq: round(freq * 10, 0) }) + } + /> + ) : ( + + )} + + +
+ + +
+
+ ); +}; diff --git a/vorestation.dme b/vorestation.dme index 057b7057863..292246512e4 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1077,6 +1077,7 @@ #include "code\game\machinery\embedded_controller\airlock_docking_controller.dm" #include "code\game\machinery\embedded_controller\airlock_docking_controller_multi.dm" #include "code\game\machinery\embedded_controller\airlock_program.dm" +#include "code\game\machinery\embedded_controller\construction.dm" #include "code\game\machinery\embedded_controller\docking_program.dm" #include "code\game\machinery\embedded_controller\docking_program_multi.dm" #include "code\game\machinery\embedded_controller\embedded_controller_base.dm"