diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e03e6ded05f..95c6211f083 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -867,6 +867,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// Trait applied when an integrated circuit/module becomes undupable #define TRAIT_CIRCUIT_UNDUPABLE "circuit_undupable" +/// Trait applied when an integrated circuit opens a UI on a player (see list pick component) +#define TRAIT_CIRCUIT_UI_OPEN "circuit_ui_open" + /// Hearing trait that is from the hearing component #define CIRCUIT_HEAR_TRAIT "circuit_hear" diff --git a/code/__DEFINES/wiremod.dm b/code/__DEFINES/wiremod.dm index 14a03d780ce..421650e3bf1 100644 --- a/code/__DEFINES/wiremod.dm +++ b/code/__DEFINES/wiremod.dm @@ -45,6 +45,8 @@ #define PORT_TYPE_ATOM "entity" /// Datum datatype #define PORT_TYPE_DATUM "datum" +/// User datatype +#define PORT_TYPE_USER "user" /// The maximum range between a port and an atom diff --git a/code/controllers/subsystem/circuit_component.dm b/code/controllers/subsystem/circuit_component.dm index 3ef1be5a3aa..bae302ed9d0 100644 --- a/code/controllers/subsystem/circuit_component.dm +++ b/code/controllers/subsystem/circuit_component.dm @@ -39,7 +39,7 @@ SUBSYSTEM_DEF(circuit_component) * Those that registered first will be executed first and those registered last will be executed last. */ /datum/controller/subsystem/circuit_component/proc/add_callback(datum/port/input, datum/callback/to_call) - if(instant_run_tick == world.time && (TICK_USAGE - instant_run_start_cpu_usage) < instant_run_max_cpu_usage) + if(instant_run_tick == world.time && (TICK_USAGE - instant_run_start_cpu_usage) <= instant_run_max_cpu_usage) instant_run_callbacks_to_run += to_call return @@ -80,7 +80,7 @@ SUBSYSTEM_DEF(circuit_component) else instant_run_tick = 0 - if((TICK_USAGE - instant_run_start_cpu_usage) < instant_run_max_cpu_usage) + if((TICK_USAGE - instant_run_start_cpu_usage) <= instant_run_max_cpu_usage) return received_inputs else return null diff --git a/code/modules/tgui_input/list.dm b/code/modules/tgui_input/list.dm index a58b96b06e3..18525e6b10a 100644 --- a/code/modules/tgui_input/list.dm +++ b/code/modules/tgui_input/list.dm @@ -29,6 +29,9 @@ if(!user.client.prefs.read_preference(/datum/preference/toggle/tgui_input)) return input(user, message, title, default) as null|anything in items var/datum/tgui_list_input/input = new(user, message, title, items, default, timeout, ui_state) + if(input.invalid) + qdel(input) + return input.ui_interact(user) input.wait() if (input) @@ -62,6 +65,8 @@ var/closed /// The TGUI UI state that will be returned in ui_state(). Default: always_state var/datum/ui_state/state + /// Whether the tgui list input is invalid or not (i.e. due to all list entries being null) + var/invalid = FALSE /datum/tgui_list_input/New(mob/user, message, title, list/items, default, timeout, ui_state) src.title = title @@ -81,6 +86,9 @@ string_key = avoid_assoc_duplicate_keys(string_key, repeat_items) src.items += string_key src.items_map[string_key] = i + + if(length(src.items) == 0) + invalid = TRUE if (timeout) src.timeout = timeout start_time = world.time diff --git a/code/modules/wiremod/components/list/assoc_list_pick.dm b/code/modules/wiremod/components/list/assoc_list_pick.dm index 9c8e94c074a..64dbe6a0a0b 100644 --- a/code/modules/wiremod/components/list/assoc_list_pick.dm +++ b/code/modules/wiremod/components/list/assoc_list_pick.dm @@ -15,7 +15,6 @@ /obj/item/circuit_component/list_pick/assoc/make_list_port() input_list = add_input_port("List", PORT_TYPE_ASSOC_LIST(PORT_TYPE_STRING, PORT_TYPE_ANY)) - /obj/item/circuit_component/list_pick/assoc/pre_input_received(datum/port/input/port) if(port == list_options) var/new_type = list_options.value diff --git a/code/modules/wiremod/components/list/assoc_literal.dm b/code/modules/wiremod/components/list/assoc_literal.dm index a3f97cae745..f829ad08f25 100644 --- a/code/modules/wiremod/components/list/assoc_literal.dm +++ b/code/modules/wiremod/components/list/assoc_literal.dm @@ -38,15 +38,6 @@ list_options = add_option_port("List Type", GLOB.wiremod_basic_types) /obj/item/circuit_component/assoc_literal/populate_ports() - AddComponent(/datum/component/circuit_component_add_port, \ - port_list = entry_ports, \ - add_action = "add", \ - remove_action = "remove", \ - port_type = PORT_TYPE_ANY, \ - prefix = "Index", \ - minimum_amount = 1, \ - maximum_amount = 20 \ - ) AddComponent(/datum/component/circuit_component_add_port, \ port_list = key_ports, \ add_action = "add", \ @@ -56,6 +47,15 @@ minimum_amount = 1, \ maximum_amount = 20 \ ) + AddComponent(/datum/component/circuit_component_add_port, \ + port_list = entry_ports, \ + add_action = "add", \ + remove_action = "remove", \ + port_type = PORT_TYPE_ANY, \ + prefix = "Value", \ + minimum_amount = 1, \ + maximum_amount = 20 \ + ) list_output = add_output_port("Value", PORT_TYPE_ASSOC_LIST(PORT_TYPE_STRING, PORT_TYPE_ANY), order = 1.1) /obj/item/circuit_component/assoc_literal/input_received(datum/port/input/port) diff --git a/code/modules/wiremod/components/list/list_pick.dm b/code/modules/wiremod/components/list/list_pick.dm index bce3e82688f..a1e8141f3c3 100644 --- a/code/modules/wiremod/components/list/list_pick.dm +++ b/code/modules/wiremod/components/list/list_pick.dm @@ -27,39 +27,24 @@ circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL - var/index_type = PORT_TYPE_NUMBER - -/obj/item/circuit_component/list_pick/populate_options() - list_options = add_option_port("List Type", GLOB.wiremod_basic_types) - /obj/item/circuit_component/list_pick/proc/make_list_port() - input_list = add_input_port("List", PORT_TYPE_LIST(PORT_TYPE_ANY)) + input_list = add_input_port("List", PORT_TYPE_LIST(PORT_TYPE_STRING)) /obj/item/circuit_component/list_pick/populate_ports() input_name = add_input_port("Input Name", PORT_TYPE_STRING) - user = add_input_port("User", PORT_TYPE_ATOM) + user = add_input_port("User", PORT_TYPE_USER) make_list_port() - output = add_output_port("Picked Item", PORT_TYPE_NUMBER) - trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL) + output = add_output_port("Picked Item", PORT_TYPE_STRING) failure = add_output_port("On Failure", PORT_TYPE_SIGNAL) - success = add_output_port("On Succes", PORT_TYPE_SIGNAL) - - -/obj/item/circuit_component/list_pick/pre_input_received(datum/port/input/port) - if(port == list_options) - var/new_type = list_options.value - input_list.set_datatype(PORT_TYPE_LIST(new_type)) - output.set_datatype(new_type) - + success = add_output_port("On Success", PORT_TYPE_SIGNAL) /obj/item/circuit_component/list_pick/input_received(datum/port/input/port) - if(parent.Adjacent(user.value)) + var/mob/mob_user = user.value + if(!ismob(mob_user) || HAS_TRAIT_FROM(parent, TRAIT_CIRCUIT_UI_OPEN, REF(mob_user))) + failure.set_output(COMPONENT_SIGNAL) return - - if(ismob(user.value)) - trigger_output.set_output(COMPONENT_SIGNAL) - INVOKE_ASYNC(src, PROC_REF(show_list), user.value, input_name.value, input_list.value) + INVOKE_ASYNC(src, PROC_REF(show_list), mob_user, input_name.value, input_list.value) /// Show a list of options to the user using standed TGUI input list /obj/item/circuit_component/list_pick/proc/show_list(mob/user, message, list/showed_list) @@ -68,10 +53,17 @@ return if(!message) message = "circuit input" - if(!(user.can_perform_action(src, FORBID_TELEKINESIS_REACH))) + if(!(user.can_perform_action(parent.shell, FORBID_TELEKINESIS_REACH|ALLOW_SILICON_REACH|ALLOW_RESTING))) + failure.set_output(COMPONENT_SIGNAL) return + var/user_ref = REF(user) + ADD_TRAIT(parent, TRAIT_CIRCUIT_UI_OPEN, user_ref) var/picked = tgui_input_list(user, message = message, items = showed_list) - if(!(user.can_perform_action(src, FORBID_TELEKINESIS_REACH))) + REMOVE_TRAIT(parent, TRAIT_CIRCUIT_UI_OPEN, user_ref) + if(QDELETED(src)) + return + if(!(user.can_perform_action(parent.shell, FORBID_TELEKINESIS_REACH|ALLOW_SILICON_REACH|ALLOW_RESTING))) + failure.set_output(COMPONENT_SIGNAL) return choose_item(picked, showed_list) diff --git a/code/modules/wiremod/datatypes/datum.dm b/code/modules/wiremod/datatypes/datum.dm index f3faa8f5d8e..4045ee3793e 100644 --- a/code/modules/wiremod/datatypes/datum.dm +++ b/code/modules/wiremod/datatypes/datum.dm @@ -4,6 +4,7 @@ datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT|DATATYPE_FLAG_ALLOW_ATOM_INPUT can_receive_from = list( PORT_TYPE_ATOM, + PORT_TYPE_USER ) /datum/circuit_datatype/datum/convert_value(datum/port/port, value_to_convert) diff --git a/code/modules/wiremod/datatypes/entity.dm b/code/modules/wiremod/datatypes/entity.dm index e3a76892f97..437b3d7adb4 100644 --- a/code/modules/wiremod/datatypes/entity.dm +++ b/code/modules/wiremod/datatypes/entity.dm @@ -2,6 +2,9 @@ datatype = PORT_TYPE_ATOM color = "purple" datatype_flags = DATATYPE_FLAG_ALLOW_MANUAL_INPUT|DATATYPE_FLAG_ALLOW_ATOM_INPUT + can_receive_from = list( + PORT_TYPE_USER, + ) /datum/circuit_datatype/entity/convert_value(datum/port/port, value_to_convert) var/atom/object = value_to_convert diff --git a/code/modules/wiremod/datatypes/user.dm b/code/modules/wiremod/datatypes/user.dm new file mode 100644 index 00000000000..693941dcd74 --- /dev/null +++ b/code/modules/wiremod/datatypes/user.dm @@ -0,0 +1,9 @@ +/datum/circuit_datatype/user + datatype = PORT_TYPE_USER + color = "label" + +/datum/circuit_datatype/user/convert_value(datum/port/port, value_to_convert) + var/datum/object = value_to_convert + if(QDELETED(object)) + return null + return object diff --git a/code/modules/wiremod/shell/bot.dm b/code/modules/wiremod/shell/bot.dm index 36fd6c5b369..dfd9845bc05 100644 --- a/code/modules/wiremod/shell/bot.dm +++ b/code/modules/wiremod/shell/bot.dm @@ -31,7 +31,7 @@ var/datum/port/output/entity /obj/item/circuit_component/bot/populate_ports() - entity = add_output_port("User", PORT_TYPE_ATOM) + entity = add_output_port("User", PORT_TYPE_USER) signal = add_output_port("Signal", PORT_TYPE_SIGNAL) /obj/item/circuit_component/bot/register_shell(atom/movable/shell) @@ -46,4 +46,3 @@ playsound(source, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) entity.set_output(user) signal.set_output(COMPONENT_SIGNAL) - diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm index 89aac209c83..c3ac3154d2d 100644 --- a/code/modules/wiremod/shell/brain_computer_interface.dm +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -114,7 +114,7 @@ send_message_signal = add_input_port("Send Message", PORT_TYPE_SIGNAL) show_charge_meter = add_input_port("Show Charge Meter", PORT_TYPE_NUMBER, trigger = PROC_REF(update_charge_action)) - user_port = add_output_port("User", PORT_TYPE_ATOM) + user_port = add_output_port("User", PORT_TYPE_USER) /obj/item/circuit_component/bci_core/Destroy() QDEL_NULL(charge_action) diff --git a/code/modules/wiremod/shell/controller.dm b/code/modules/wiremod/shell/controller.dm index 7040e554a0a..3092d3315f1 100644 --- a/code/modules/wiremod/shell/controller.dm +++ b/code/modules/wiremod/shell/controller.dm @@ -34,7 +34,7 @@ var/datum/port/output/entity /obj/item/circuit_component/controller/populate_ports() - entity = add_output_port("User", PORT_TYPE_ATOM) + entity = add_output_port("User", PORT_TYPE_USER) signal = add_output_port("Signal", PORT_TYPE_SIGNAL) alt = add_output_port("Alternate Signal", PORT_TYPE_SIGNAL) right = add_output_port("Extra Signal", PORT_TYPE_SIGNAL) @@ -51,6 +51,12 @@ COMSIG_CLICK_ALT, )) +/obj/item/circuit_component/controller/proc/handle_trigger(atom/source, user, port_name, datum/port/output/port_signal) + source.balloon_alert(user, "clicked [port_name] button") + playsound(source, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) + entity.set_output(user) + port_signal.set_output(COMPONENT_SIGNAL) + /** * Called when the shell item is used in hand */ @@ -58,10 +64,7 @@ SIGNAL_HANDLER if(!user.Adjacent(source)) return - source.balloon_alert(user, "clicked primary button") - playsound(source, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) - entity.set_output(user) - signal.set_output(COMPONENT_SIGNAL) + handle_trigger(source, user, "primary", signal) /** * Called when the shell item is alt-clicked @@ -70,10 +73,8 @@ SIGNAL_HANDLER if(!user.Adjacent(source)) return - source.balloon_alert(user, "clicked alternate button") - playsound(source, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) - entity.set_output(user) - alt.set_output(COMPONENT_SIGNAL) + handle_trigger(source, user, "alternate", alt) + /** * Called when the shell item is right-clicked in active hand @@ -82,7 +83,4 @@ SIGNAL_HANDLER if(!user.Adjacent(source)) return - source.balloon_alert(user, "clicked extra button") - playsound(source, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) - entity.set_output(user) - right.set_output(COMPONENT_SIGNAL) + handle_trigger(source, user, "extra", right) diff --git a/code/modules/wiremod/shell/keyboard.dm b/code/modules/wiremod/shell/keyboard.dm index 4231a6dc814..05b9ded074b 100644 --- a/code/modules/wiremod/shell/keyboard.dm +++ b/code/modules/wiremod/shell/keyboard.dm @@ -27,7 +27,7 @@ var/datum/port/output/output /obj/item/circuit_component/keyboard_shell/populate_ports() - entity = add_output_port("User", PORT_TYPE_ATOM) + entity = add_output_port("User", PORT_TYPE_USER) output = add_output_port("Message", PORT_TYPE_STRING) signal = add_output_port("Signal", PORT_TYPE_SIGNAL) @@ -53,4 +53,3 @@ output.set_output(message) signal.set_output(COMPONENT_SIGNAL) - diff --git a/code/modules/wiremod/shell/module.dm b/code/modules/wiremod/shell/module.dm index bffff02e5fb..4201c6afb17 100644 --- a/code/modules/wiremod/shell/module.dm +++ b/code/modules/wiremod/shell/module.dm @@ -123,7 +123,7 @@ toggle_suit = add_input_port("Toggle Suit", PORT_TYPE_SIGNAL) select_module = add_input_port("Select Module", PORT_TYPE_SIGNAL) // States - wearer = add_output_port("Wearer", PORT_TYPE_ATOM) + wearer = add_output_port("Wearer", PORT_TYPE_USER) deployed = add_output_port("Deployed", PORT_TYPE_NUMBER) activated = add_output_port("Activated", PORT_TYPE_NUMBER) selected_module = add_output_port("Selected Module", PORT_TYPE_STRING) diff --git a/code/modules/wiremod/shell/moneybot.dm b/code/modules/wiremod/shell/moneybot.dm index 46a834e2d60..20eb596eb72 100644 --- a/code/modules/wiremod/shell/moneybot.dm +++ b/code/modules/wiremod/shell/moneybot.dm @@ -95,7 +95,7 @@ /obj/item/circuit_component/money_bot/populate_ports() total_money = add_output_port("Total Money", PORT_TYPE_NUMBER) money_input = add_output_port("Last Input Money", PORT_TYPE_NUMBER) - entity = add_output_port("User", PORT_TYPE_ATOM) + entity = add_output_port("User", PORT_TYPE_USER) money_trigger = add_output_port("Money Input", PORT_TYPE_SIGNAL) /obj/item/circuit_component/money_bot/register_shell(atom/movable/shell) diff --git a/tgstation.dme b/tgstation.dme index b478c116850..eed219791dc 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5968,6 +5968,7 @@ #include "code\modules\wiremod\datatypes\option.dm" #include "code\modules\wiremod\datatypes\signal.dm" #include "code\modules\wiremod\datatypes\string.dm" +#include "code\modules\wiremod\datatypes\user.dm" #include "code\modules\wiremod\datatypes\composite\assoc_list.dm" #include "code\modules\wiremod\datatypes\composite\composite.dm" #include "code\modules\wiremod\datatypes\composite\list.dm"