diff --git a/code/__DEFINES/dcs/signals/signals_circuit.dm b/code/__DEFINES/dcs/signals/signals_circuit.dm index 08d5f675b28..14be995d6ce 100644 --- a/code/__DEFINES/dcs/signals/signals_circuit.dm +++ b/code/__DEFINES/dcs/signals/signals_circuit.dm @@ -22,6 +22,9 @@ /// Sent when a circuit is removed from its shell #define COMSIG_CIRCUIT_SHELL_REMOVED "circuit_shell_removed" +/// Send to [/obj/item/circuit_component] when it is added to a circuit. (/obj/item/integrated_circuit) +#define COMSIG_CIRCUIT_COMPONENT_ADDED "circuit_component_added" + /// Sent to [/obj/item/circuit_component] when it is removed from a circuit. (/obj/item/integrated_circuit) #define COMSIG_CIRCUIT_COMPONENT_REMOVED "circuit_component_removed" diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 132adba02e0..2044aab51e2 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -550,3 +550,27 @@ #define COMSIG_WINGS_OPENED "wings_opened" /// Sent from /obj/item/organ/wings/functional/proc/close_wings(): (mob/living/carbon/owner) #define COMSIG_WINGS_CLOSED "wings_closed" + +/// Sent from /obj/item/assembly/on_attach(): (atom/holder) +#define COMSIG_ASSEMBLY_ATTACHED "assembly_attached" + +/// Sent from /obj/item/assembly/on_detach(): (atom/holder) +#define COMSIG_ASSEMBLY_DETACHED "assembly_detached" + +/* + * The following two signals are separate from the above two because buttons don't set the holder of the inserted assembly. + * This causes subtle behavioral differences that future handlers for these signals may need to account for, + * even if none of the currently implemented handlers do. + */ + +/// Sent from /obj/machinery/button/assembly_act(obj/machinery/button/button, mob/user) +#define COMSIG_ASSEMBLY_ADDED_TO_BUTTON "assembly_added_to_button" + +/// Sent from /obj/machinery/button/remove_assembly(obj/machinery/button/button, mob/user) +#define COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON "assembly_removed_from_button" + +/// Sent from /datum/powernet/add_cable() +#define COMSIG_CABLE_ADDED_TO_POWERNET "cable_added_to_powernet" + +/// Sent from /datum/powernet/remove_cable() +#define COMSIG_CABLE_REMOVED_FROM_POWERNET "cable_removed_from_powernet" diff --git a/code/__DEFINES/dcs/signals/signals_powernet.dm b/code/__DEFINES/dcs/signals/signals_powernet.dm new file mode 100644 index 00000000000..1343e9e1d66 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_powernet.dm @@ -0,0 +1,4 @@ +// Powernet signals + +/// Sent when a wirenet circuit component sends a signal (list/data) +#define COMSIG_POWERNET_CIRCUIT_TRANSMISSION "powernet_circuit_transmision" diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 70d46576790..c8aba44ef47 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -145,6 +145,7 @@ return ITEM_INTERACT_BLOCKING device = new_device + SEND_SIGNAL(new_device, COMSIG_ASSEMBLY_ADDED_TO_BUTTON, src, user) to_chat(user, span_notice("You add \the [new_device] to the button.")) update_appearance() @@ -273,6 +274,7 @@ return ..() /obj/machinery/button/proc/remove_assembly(mob/user) + SEND_SIGNAL(device, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON, src, user) user.put_in_hands(device) to_chat(user, span_notice("You remove \the [device] from the button frame.")) device = null diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index add95cdd6db..dbd5a704614 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -40,18 +40,22 @@ * Will also be called if the assembly holder is attached to a plasma (internals) tank or welding fuel (dispenser) tank. */ /obj/item/assembly/proc/on_attach() + SHOULD_CALL_PARENT(TRUE) if(!holder && connected) holder = connected.holder + SEND_SIGNAL(src, COMSIG_ASSEMBLY_ATTACHED, holder) /** * on_detach: Called when removed from an assembly holder or wiring datum */ /obj/item/assembly/proc/on_detach() + SHOULD_CALL_PARENT(TRUE) if(connected) connected = null if(!holder) return FALSE forceMove(holder.drop_location()) + SEND_SIGNAL(src, COMSIG_ASSEMBLY_DETACHED, holder) holder = null return TRUE diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index 618812351f9..88aa3b7655f 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -35,6 +35,7 @@ //if the powernet is then empty, delete it //Warning : this proc DON'T check if the cable exists /datum/powernet/proc/remove_cable(obj/structure/cable/C) + SEND_SIGNAL(C, COMSIG_CABLE_REMOVED_FROM_POWERNET) cables -= C C.powernet = null if(is_empty())//the powernet is now empty... @@ -50,6 +51,7 @@ C.powernet.remove_cable(C) //..remove it C.powernet = src cables +=C + SEND_SIGNAL(C, COMSIG_CABLE_ADDED_TO_POWERNET) //remove a power machine from the current powernet //if the powernet is then empty, delete it @@ -90,3 +92,7 @@ /datum/powernet/proc/get_electrocute_damage() return ELECTROCUTE_DAMAGE(energy_to_power(avail)) // Assuming 1 second of contact. + +// Mostly just a wrapper for sending the COMSIG_POWERNET_CIRCUIT_TRANSMISSION signal, but could be retooled in the future to give it other uses +/datum/powernet/proc/data_transmission(list/data, encryption_key, datum/weakref/port) + SEND_SIGNAL(src, COMSIG_POWERNET_CIRCUIT_TRANSMISSION, list("data" = data, "enc_key" = encryption_key, "port" = port)) diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index 418dec186e9..f8732cc332b 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -477,6 +477,21 @@ id = "comp_assoc_list_pick" build_path = /obj/item/circuit_component/list_pick/assoc +/datum/design/component/wirenet_receive + name = "Wirenet Receiver Component" + id = "comp_wirenet_receive" + build_path = /obj/item/circuit_component/wirenet_receive + +/datum/design/component/wirenet_send + name = "Wirenet Transmitter Component" + id = "comp_wirenet_send" + build_path = /obj/item/circuit_component/wirenet_send + +/datum/design/component/wirenet_send_literal + name = "Wirenet List Literal Transmitter Component" + id = "comp_wirenet_send_literal" + build_path = /obj/item/circuit_component/list_literal/wirenet_send + /datum/design/component/bci/bci_camera name = "BCI Camera" id = "comp_camera_bci" diff --git a/code/modules/research/techweb/nodes/circuit_nodes.dm b/code/modules/research/techweb/nodes/circuit_nodes.dm index 554e9997c04..109873c3851 100644 --- a/code/modules/research/techweb/nodes/circuit_nodes.dm +++ b/code/modules/research/techweb/nodes/circuit_nodes.dm @@ -86,6 +86,9 @@ "comp_typecast", "comp_typecheck", "comp_view_sensor", + "comp_wirenet_receive", + "comp_wirenet_send", + "comp_wirenet_send_literal", ) /datum/techweb_node/circuit_shells diff --git a/code/modules/wiremod/components/wirenet/receive.dm b/code/modules/wiremod/components/wirenet/receive.dm new file mode 100644 index 00000000000..2533573c493 --- /dev/null +++ b/code/modules/wiremod/components/wirenet/receive.dm @@ -0,0 +1,76 @@ +/obj/item/circuit_component/wirenet_receive + display_name = "Wirenet Receiver" + desc = "Receives data packets through the connected cable network. If Encryption Key is set then only signals with the same Encryption Key will be received." + category = "Utility" + + circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL //trigger_output + + ui_buttons = list( + "1" = CABLE_LAYER_1_NAME, + "2" = CABLE_LAYER_2_NAME, + "3" = CABLE_LAYER_3_NAME, + ) + + var/cable_layer = /datum/component/circuit_component_wirenet_connection::cable_layer + + /// The list type + var/datum/port/input/option/list_options + + /// Data being received + var/datum/port/output/data_package + + /// Encryption key + var/datum/port/input/enc_key + +/obj/item/circuit_component/wirenet_receive/Initialize(mapload) + . = ..() + AddComponent(\ + /datum/component/circuit_component_wirenet_connection,\ + connection_callback = CALLBACK(src, PROC_REF(on_powernet_connection)),\ + disconnection_callback = CALLBACK(src, PROC_REF(on_powernet_disconnection)),\ + post_set_cable_layer_callback = CALLBACK(src, PROC_REF(on_set_cable_layer)),\ + ) + +/obj/item/circuit_component/wirenet_receive/proc/on_powernet_connection(datum/powernet/new_powernet) + RegisterSignal(new_powernet, COMSIG_POWERNET_CIRCUIT_TRANSMISSION, PROC_REF(on_circuit_transmission)) + +/obj/item/circuit_component/wirenet_receive/proc/on_powernet_disconnection(datum/powernet/old_powernet) + UnregisterSignal(old_powernet, COMSIG_POWERNET_CIRCUIT_TRANSMISSION) + +/obj/item/circuit_component/wirenet_receive/proc/on_set_cable_layer(new_layer) + cable_layer = new_layer + +/obj/item/circuit_component/wirenet_receive/get_ui_notices() + . = ..() + . += create_ui_notice("Set the cable layer to connect to with the \"1\", \"2\", and \"3\" buttons.", "green", "info") + . += create_ui_notice("Currently connected to: [GLOB.cable_layer_to_name["[cable_layer]"]]", "green", "info") + +/obj/item/circuit_component/wirenet_receive/populate_options() + list_options = add_option_port("List Type", GLOB.wiremod_basic_types) + +/obj/item/circuit_component/wirenet_receive/populate_ports() + data_package = add_output_port("Data Package", PORT_TYPE_LIST(PORT_TYPE_ANY)) + enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING) + +/obj/item/circuit_component/wirenet_receive/pre_input_received(datum/port/input/port) + if(port == list_options) + var/new_datatype = list_options.value + data_package.set_datatype(PORT_TYPE_LIST(new_datatype)) + +/obj/item/circuit_component/wirenet_receive/proc/on_circuit_transmission(_source, list/data) + SIGNAL_HANDLER + + if(data["enc_key"] != enc_key.value) + return + + var/datum/weakref/ref = data["port"] + var/datum/port/input/port = ref?.resolve() + if(!port) + return + + var/datum/circuit_datatype/datatype_handler = data_package.datatype_handler + if(!datatype_handler?.can_receive_from_datatype(port.datatype)) + return + + data_package.set_output(data["data"]) + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/components/wirenet/send.dm b/code/modules/wiremod/components/wirenet/send.dm new file mode 100644 index 00000000000..8852b59da4d --- /dev/null +++ b/code/modules/wiremod/components/wirenet/send.dm @@ -0,0 +1,68 @@ +/obj/item/circuit_component/wirenet_send + display_name = "Wirenet Transmitter" + desc = "Sends a data package through the connected cable network. If Encryption Key is set then transmitted data will be only picked up by receivers with the same Encryption Key." + category = "Utility" + + circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL + + ui_buttons = list( + "1" = CABLE_LAYER_1_NAME, + "2" = CABLE_LAYER_2_NAME, + "3" = CABLE_LAYER_3_NAME, + ) + + var/cable_layer = /datum/component/circuit_component_wirenet_connection::cable_layer + + /// Powernet reference provided by the circuit_component_wirenet_connection component + var/datum/powernet/connected_powernet + + /// The list type + var/datum/port/input/option/list_options + + /// Data being sent + var/datum/port/input/data_package + + /// Encryption key + var/datum/port/input/enc_key + +/obj/item/circuit_component/wirenet_send/Initialize(mapload) + . = ..() + AddComponent(\ + /datum/component/circuit_component_wirenet_connection,\ + connection_callback = CALLBACK(src, PROC_REF(on_powernet_connection)),\ + disconnection_callback = CALLBACK(src, PROC_REF(on_powernet_disconnection)),\ + post_set_cable_layer_callback = CALLBACK(src, PROC_REF(on_set_cable_layer)),\ + ) + +/obj/item/circuit_component/wirenet_send/Destroy() + . = ..() + connected_powernet = null + +/obj/item/circuit_component/wirenet_send/proc/on_powernet_connection(datum/powernet/new_powernet) + connected_powernet = new_powernet + +/obj/item/circuit_component/wirenet_send/proc/on_powernet_disconnection(datum/powernet/old_powernet) + connected_powernet = null + +/obj/item/circuit_component/wirenet_send/proc/on_set_cable_layer(new_layer) + cable_layer = new_layer + +/obj/item/circuit_component/wirenet_send/get_ui_notices() + . = ..() + . += create_ui_notice("Set the cable layer to connect to with the \"1\", \"2\", and \"3\" buttons.", "green", "info") + . += create_ui_notice("Currently connected to: [GLOB.cable_layer_to_name["[cable_layer]"]]", "green", "info") + +/obj/item/circuit_component/wirenet_send/populate_options() + list_options = add_option_port("List Type", GLOB.wiremod_basic_types) + +/obj/item/circuit_component/wirenet_send/populate_ports() + data_package = add_input_port("Data Package", PORT_TYPE_LIST(PORT_TYPE_ANY)) + enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING) + +/obj/item/circuit_component/wirenet_send/pre_input_received(datum/port/input/port) + if(port == list_options) + var/new_datatype = list_options.value + data_package.set_datatype(PORT_TYPE_LIST(new_datatype)) + +/obj/item/circuit_component/wirenet_send/input_received(datum/port/input/port) + connected_powernet?.data_transmission(data_package.value, enc_key.value, WEAKREF(data_package)) diff --git a/code/modules/wiremod/components/wirenet/send_literal.dm b/code/modules/wiremod/components/wirenet/send_literal.dm new file mode 100644 index 00000000000..7d46152d5d9 --- /dev/null +++ b/code/modules/wiremod/components/wirenet/send_literal.dm @@ -0,0 +1,54 @@ +/obj/item/circuit_component/list_literal/wirenet_send + display_name = "Wirenet Transmitter List Literal" + desc = "Creates a list literal data package and sends it through the connected cable network. If Encryption Key is set then transmitted data will be only picked up by receivers with the same Encryption Key." + category = "Utility" + + ui_buttons = list( + "1" = CABLE_LAYER_1_NAME, + "2" = CABLE_LAYER_2_NAME, + "3" = CABLE_LAYER_3_NAME, + "plus" = "add", + "minus" = "remove", + ) + + var/cable_layer = /datum/component/circuit_component_wirenet_connection::cable_layer + + /// Powernet reference provided by the circuit_component_wirenet_connection component + var/datum/powernet/connected_powernet + + /// Encryption key + var/datum/port/input/enc_key + +/obj/item/circuit_component/list_literal/wirenet_send/Initialize(mapload) + . = ..() + AddComponent(\ + /datum/component/circuit_component_wirenet_connection,\ + connection_callback = CALLBACK(src, PROC_REF(on_powernet_connection)),\ + disconnection_callback = CALLBACK(src, PROC_REF(on_powernet_disconnection)),\ + post_set_cable_layer_callback = CALLBACK(src, PROC_REF(on_set_cable_layer)),\ + ) + +/obj/item/circuit_component/list_literal/wirenet_send/Destroy() + . = ..() + connected_powernet = null + +/obj/item/circuit_component/list_literal/wirenet_send/proc/on_powernet_connection(datum/powernet/new_powernet) + connected_powernet = new_powernet + +/obj/item/circuit_component/list_literal/wirenet_send/proc/on_powernet_disconnection(datum/powernet/old_powernet) + connected_powernet = null + +/obj/item/circuit_component/list_literal/wirenet_send/proc/on_set_cable_layer(new_layer) + cable_layer = new_layer + +/obj/item/circuit_component/list_literal/wirenet_send/get_ui_notices() + . = ..() + . += create_ui_notice("Set the cable layer to connect to with the \"1\", \"2\", and \"3\" buttons.", "green", "info") + . += create_ui_notice("Currently connected to: [GLOB.cable_layer_to_name["[cable_layer]"]]", "green", "info") + +/obj/item/circuit_component/list_literal/wirenet_send/populate_ports() + . = ..() + enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING) + +/obj/item/circuit_component/list_literal/wirenet_send/input_received(datum/port/input/port) + connected_powernet?.data_transmission(list_output.value, enc_key.value, WEAKREF(list_output)) diff --git a/code/modules/wiremod/core/integrated_circuit.dm b/code/modules/wiremod/core/integrated_circuit.dm index f3d52653baf..1023a59eb21 100644 --- a/code/modules/wiremod/core/integrated_circuit.dm +++ b/code/modules/wiremod/core/integrated_circuit.dm @@ -276,6 +276,7 @@ GLOBAL_LIST_EMPTY_TYPED(integrated_circuits, /obj/item/integrated_circuit) to_add.rel_x = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_x to_add.rel_y = rand(COMPONENT_MIN_RANDOM_POS, COMPONENT_MAX_RANDOM_POS) - screen_y + SEND_SIGNAL(to_add, COMSIG_CIRCUIT_COMPONENT_ADDED, src) to_add.parent = src attached_components += to_add current_size += to_add.circuit_size diff --git a/code/modules/wiremod/dcs_components/component_wirenet_connection.dm b/code/modules/wiremod/dcs_components/component_wirenet_connection.dm new file mode 100644 index 00000000000..81c7d304ecd --- /dev/null +++ b/code/modules/wiremod/dcs_components/component_wirenet_connection.dm @@ -0,0 +1,188 @@ +/datum/component/circuit_component_wirenet_connection + var/cable_layer = CABLE_LAYER_2 + + var/atom/movable/tracked_shell + + var/atom/movable/tracked_movable + var/obj/structure/cable/tracked_node + var/datum/powernet/tracked_powernet + + var/static/list/turf_connections = list(COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON = PROC_REF(on_atom_initialized_on_turf)) + + /// What action sets the component to link to cable layer 1 + var/layer_1_action + + /// What action sets the component to link to cable layer 2 + var/layer_2_action + + /// What action sets the component to link to cable layer 3 + var/layer_3_action + + /// Callback to invoke when the component is connected to a powernet + var/datum/callback/connection_callback + + /// Callback to invoke when the component is disconnected from a powernet + var/datum/callback/disconnection_callback + + /// Callback to invoke after setting the cable layer to link to + var/datum/callback/post_set_cable_layer_callback + +/datum/component/circuit_component_wirenet_connection/Initialize(layer_1_action = CABLE_LAYER_1_NAME, layer_2_action = CABLE_LAYER_2_NAME, layer_3_action = CABLE_LAYER_3_NAME, datum/callback/connection_callback, datum/callback/disconnection_callback, datum/callback/post_set_cable_layer_callback) + . = ..() + if(!istype(parent, /obj/item/circuit_component)) + return COMPONENT_INCOMPATIBLE + src.layer_1_action = layer_1_action + src.layer_2_action = layer_2_action + src.layer_3_action = layer_3_action + src.connection_callback = connection_callback + src.disconnection_callback = disconnection_callback + src.post_set_cable_layer_callback = post_set_cable_layer_callback + +/datum/component/circuit_component_wirenet_connection/Destroy(force) + . = ..() + connection_callback = null + disconnection_callback = null + post_set_cable_layer_callback = null + +/datum/component/circuit_component_wirenet_connection/RegisterWithParent() + RegisterSignal(parent, COMSIG_CIRCUIT_COMPONENT_PERFORM_ACTION, PROC_REF(on_action)) + RegisterSignal(parent, COMSIG_CIRCUIT_COMPONENT_ADDED, PROC_REF(on_parent_added_to_circuit)) + RegisterSignal(parent, COMSIG_CIRCUIT_COMPONENT_REMOVED, PROC_REF(on_parent_removed_from_circuit)) + +/datum/component/circuit_component_wirenet_connection/UnregisterFromParent() + unset_shell() + UnregisterSignal(parent, list(COMSIG_CIRCUIT_COMPONENT_PERFORM_ACTION, COMSIG_CIRCUIT_COMPONENT_ADDED, COMSIG_CIRCUIT_COMPONENT_REMOVED)) + +/datum/component/circuit_component_wirenet_connection/proc/on_parent_added_to_circuit(_source, obj/item/integrated_circuit/circuit) + SIGNAL_HANDLER + RegisterSignal(circuit, COMSIG_CIRCUIT_SET_SHELL, PROC_REF(on_circuit_set_shell)) + RegisterSignal(circuit, COMSIG_CIRCUIT_SHELL_REMOVED, PROC_REF(unset_shell)) + if(circuit.shell) + set_shell(circuit.shell) + +/datum/component/circuit_component_wirenet_connection/proc/on_parent_removed_from_circuit(_source, obj/item/integrated_circuit/circuit) + SIGNAL_HANDLER + unset_shell() + UnregisterSignal(circuit, list(COMSIG_CIRCUIT_SET_SHELL, COMSIG_CIRCUIT_SHELL_REMOVED)) + +/datum/component/circuit_component_wirenet_connection/proc/on_circuit_set_shell(_source, atom/movable/shell) + SIGNAL_HANDLER + set_shell(shell) + +/datum/component/circuit_component_wirenet_connection/proc/set_shell(atom/movable/new_shell) + tracked_shell = new_shell + if(isassembly(new_shell)) + RegisterSignals(new_shell, list(COMSIG_ASSEMBLY_ATTACHED, COMSIG_ASSEMBLY_ADDED_TO_BUTTON), PROC_REF(on_assembly_shell_attached)) + RegisterSignals(new_shell, list(COMSIG_ASSEMBLY_DETACHED, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON), PROC_REF(on_assembly_shell_detached)) + else + set_tracked_movable(new_shell) + +/datum/component/circuit_component_wirenet_connection/proc/unset_shell() + SIGNAL_HANDLER + unset_tracked_movable() + if(!tracked_shell) + return + if(isassembly(tracked_shell)) + UnregisterSignal(tracked_shell, list(COMSIG_ASSEMBLY_ATTACHED, COMSIG_ASSEMBLY_DETACHED, COMSIG_ASSEMBLY_ADDED_TO_BUTTON, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON)) + tracked_shell = null + +/datum/component/circuit_component_wirenet_connection/proc/on_assembly_shell_attached(_source, atom/holder) + SIGNAL_HANDLER + if(ismovable(holder)) + set_tracked_movable(holder) + +/datum/component/circuit_component_wirenet_connection/proc/on_assembly_shell_detached() + SIGNAL_HANDLER + unset_tracked_movable() + +/datum/component/circuit_component_wirenet_connection/proc/set_tracked_movable(atom/movable/new_tracked_movable) + if(tracked_movable == new_tracked_movable) //Should only happen when an assembly holder the assembly was attached to calls on_attach when it itself is attached to something + return + tracked_movable = new_tracked_movable + RegisterSignal(new_tracked_movable, COMSIG_MOVABLE_SET_ANCHORED, PROC_REF(on_tracked_movable_set_anchored)) + RegisterSignal(new_tracked_movable, COMSIG_QDELETING, PROC_REF(unset_tracked_movable)) + if(tracked_movable.anchored) + try_set_tracked_node() + +/datum/component/circuit_component_wirenet_connection/proc/unset_tracked_movable() + SIGNAL_HANDLER + unset_tracked_node() + if(!tracked_movable) + return + UnregisterSignal(tracked_movable, list(COMSIG_MOVABLE_SET_ANCHORED, COMSIG_QDELETING)) + tracked_movable = null + +/datum/component/circuit_component_wirenet_connection/proc/on_tracked_movable_set_anchored(atom/movable/source, now_anchored) + SIGNAL_HANDLER + if(now_anchored) + try_set_tracked_node() + else + unset_tracked_node() + +/datum/component/circuit_component_wirenet_connection/proc/try_set_tracked_node() + SIGNAL_HANDLER + if(tracked_node) + unset_tracked_node() + var/turf/our_turf = get_turf(tracked_movable) + var/obj/structure/cable/node = our_turf.get_cable_node(cable_layer) + if(!node) + AddElement(/datum/element/connect_loc, turf_connections) + return + set_tracked_node(node) + +/datum/component/circuit_component_wirenet_connection/proc/on_atom_initialized_on_turf(_source, obj/structure/cable/initialized) + SIGNAL_HANDLER + if(!istype(initialized)) + return + if(!(initialized.cable_layer & cable_layer)) + return + set_tracked_node(initialized) + +/datum/component/circuit_component_wirenet_connection/proc/set_tracked_node(obj/structure/cable/node) + tracked_node = node + RemoveElement(/datum/element/connect_loc, turf_connections) + RegisterSignal(tracked_movable, COMSIG_MOVABLE_MOVED, PROC_REF(unset_tracked_node)) //Because of wack cases of something pushing an anchored object + RegisterSignal(node, COMSIG_CABLE_ADDED_TO_POWERNET, PROC_REF(set_tracked_powernet)) + RegisterSignal(node, COMSIG_CABLE_REMOVED_FROM_POWERNET, PROC_REF(unset_tracked_powernet)) + RegisterSignal(node, COMSIG_QDELETING, PROC_REF(unset_tracked_node)) + if(node.powernet) + set_tracked_powernet(node.powernet) + +/datum/component/circuit_component_wirenet_connection/proc/unset_tracked_node() + SIGNAL_HANDLER + unset_tracked_powernet() + if(!tracked_node) + return + UnregisterSignal(tracked_movable, COMSIG_MOVABLE_MOVED) + UnregisterSignal(tracked_node, list(COMSIG_CABLE_ADDED_TO_POWERNET, COMSIG_CABLE_REMOVED_FROM_POWERNET, COMSIG_QDELETING)) + tracked_node = null + +/datum/component/circuit_component_wirenet_connection/proc/set_tracked_powernet(datum/powernet/source) + SIGNAL_HANDLER + tracked_powernet = source + connection_callback?.Invoke(source) + +/datum/component/circuit_component_wirenet_connection/proc/unset_tracked_powernet() + SIGNAL_HANDLER + if(!tracked_powernet) + return + disconnection_callback?.Invoke(tracked_powernet) + tracked_powernet = null + +/datum/component/circuit_component_wirenet_connection/proc/on_action(obj/item/circuit_component/component, mob/user, action) + SIGNAL_HANDLER + switch(action) + if(CABLE_LAYER_1_NAME) + set_cable_layer(CABLE_LAYER_1) + if(CABLE_LAYER_2_NAME) + set_cable_layer(CABLE_LAYER_2) + if(CABLE_LAYER_3_NAME) + set_cable_layer(CABLE_LAYER_3) + +/datum/component/circuit_component_wirenet_connection/proc/set_cable_layer(new_layer) + if(cable_layer == new_layer) + return + cable_layer = new_layer + post_set_cable_layer_callback?.Invoke(new_layer) + if(tracked_movable?.anchored) + try_set_tracked_node() diff --git a/code/modules/wiremod/shell/assembly.dm b/code/modules/wiremod/shell/assembly.dm index ea278fb4a64..3e69331c4c8 100644 --- a/code/modules/wiremod/shell/assembly.dm +++ b/code/modules/wiremod/shell/assembly.dm @@ -9,12 +9,60 @@ icon_state = "wiremod" attachable = TRUE + /// A reference to any holder to use power from instead of the circuit's own cell + var/atom/movable/power_use_proxy + + /// Valid types for `power_use_proxy` to be + var/static/list/power_use_override_types = list(/obj/machinery, /obj/vehicle/sealed/mecha, /obj/item/mod/control, /mob/living/silicon/robot) + /obj/item/assembly/wiremod/Initialize(mapload) . = ..() - AddComponent(/datum/component/shell, list( + var/datum/component/shell/shell = AddComponent(/datum/component/shell, list( new /obj/item/circuit_component/assembly_input(), new /obj/item/circuit_component/assembly_output(), ), SHELL_CAPACITY_SMALL) + RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_ATTACHED, PROC_REF(on_circuit_attached)) + RegisterSignal(shell, COMSIG_SHELL_CIRCUIT_REMOVED, PROC_REF(on_circuit_removed)) + RegisterSignals(src, list(COMSIG_ASSEMBLY_ATTACHED, COMSIG_ASSEMBLY_ADDED_TO_BUTTON), PROC_REF(on_attached)) + RegisterSignals(src, list(COMSIG_ASSEMBLY_DETACHED, COMSIG_ASSEMBLY_REMOVED_FROM_BUTTON), PROC_REF(on_detached)) + +/obj/item/assembly/wiremod/proc/on_circuit_attached(_source, obj/item/integrated_circuit/circuit) + SIGNAL_HANDLER + RegisterSignal(circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE, PROC_REF(override_circuit_power_usage)) + +/obj/item/assembly/wiremod/proc/on_circuit_removed(datum/component/shell/source) + SIGNAL_HANDLER + UnregisterSignal(source.attached_circuit, COMSIG_CIRCUIT_PRE_POWER_USAGE) + +/obj/item/assembly/wiremod/proc/on_attached(_source, atom/movable/holder) + SIGNAL_HANDLER + if(is_type_in_list(holder, power_use_override_types)) + power_use_proxy = holder + +/obj/item/assembly/wiremod/proc/on_detached(_source) + SIGNAL_HANDLER + power_use_proxy = null + +/obj/item/assembly/wiremod/proc/override_circuit_power_usage(obj/item/integrated_circuit/source, power_to_use) + SIGNAL_HANDLER + if(ismachinery(power_use_proxy)) + var/obj/machinery/machine = power_use_proxy + if(!(machine.is_operational && machine.anchored)) + return + if(machine.use_energy(power_to_use, AREA_USAGE_EQUIP)) + return COMPONENT_OVERRIDE_POWER_USAGE + if(ismecha(power_use_proxy)) + var/obj/vehicle/sealed/mecha/mech = power_use_proxy + if(mech.use_energy(power_to_use)) + return COMPONENT_OVERRIDE_POWER_USAGE + if(istype(power_use_proxy, /obj/item/mod/control)) + var/obj/item/mod/control/modsuit = power_use_proxy + if(modsuit.subtract_charge(power_to_use)) + return COMPONENT_OVERRIDE_POWER_USAGE + if(iscyborg(power_use_proxy)) + var/mob/living/silicon/robot/borg = power_use_proxy + if(borg.cell?.use(power_to_use, force = TRUE)) + return COMPONENT_OVERRIDE_POWER_USAGE /obj/item/assembly/wiremod/examine(mob/user) . = ..() diff --git a/tgstation.dme b/tgstation.dme index 896fa2f3818..979ceb8a1a7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -348,6 +348,7 @@ #include "code\__DEFINES\dcs\signals\signals_operatives.dm" #include "code\__DEFINES\dcs\signals\signals_painting.dm" #include "code\__DEFINES\dcs\signals\signals_plane_master_group.dm" +#include "code\__DEFINES\dcs\signals\signals_powernet.dm" #include "code\__DEFINES\dcs\signals\signals_proxmonitor.dm" #include "code\__DEFINES\dcs\signals\signals_radiation.dm" #include "code\__DEFINES\dcs\signals\signals_reagent.dm" @@ -6466,6 +6467,9 @@ #include "code\modules\wiremod\components\utility\typecheck.dm" #include "code\modules\wiremod\components\variables\getter.dm" #include "code\modules\wiremod\components\variables\setter.dm" +#include "code\modules\wiremod\components\wirenet\receive.dm" +#include "code\modules\wiremod\components\wirenet\send.dm" +#include "code\modules\wiremod\components\wirenet\send_literal.dm" #include "code\modules\wiremod\core\admin_panel.dm" #include "code\modules\wiremod\core\assets.dm" #include "code\modules\wiremod\core\component.dm" @@ -6490,6 +6494,7 @@ #include "code\modules\wiremod\datatypes\composite\composite.dm" #include "code\modules\wiremod\datatypes\composite\list.dm" #include "code\modules\wiremod\dcs_components\component_add_port.dm" +#include "code\modules\wiremod\dcs_components\component_wirenet_connection.dm" #include "code\modules\wiremod\preset\hello_world.dm" #include "code\modules\wiremod\preset\speech_relay.dm" #include "code\modules\wiremod\shell\airlock.dm"