From 921416b5d8f21c29ac1bacfdbd906cd9ca82a2f2 Mon Sep 17 00:00:00 2001 From: Watermelon914 <37270891+Watermelon914@users.noreply.github.com> Date: Thu, 24 Jun 2021 18:22:19 +0100 Subject: [PATCH] Adds the airlock shell, refactors USB code to be easier to use, implements USB cables for the binary valve and more. (#59728) Adds the airlock shell. The circuit has full control over the airlock. Refactors USB code to be easier to use for less experienced coders. Implements USB cables for the binary valve to be able to open/close the valve. Adds a private channel for radios that only lets circuits with the same owner's ID to interact with it. --- code/__DEFINES/dcs/signals.dm | 8 +- code/__DEFINES/wiremod.dm | 7 + code/datums/components/shell.dm | 4 + code/datums/components/usb_port.dm | 44 +++--- code/game/machinery/computer/tram_controls.dm | 32 ++--- code/game/machinery/doors/airlock.dm | 11 +- .../components/binary_devices/valve.dm | 82 +++++++++-- .../research/designs/wiremod_designs.dm | 12 ++ code/modules/research/techweb/all_nodes.dm | 1 + code/modules/wiremod/component.dm | 6 + .../wiremod/components/action/radio.dm | 15 +- code/modules/wiremod/integrated_circuit.dm | 3 +- code/modules/wiremod/shell/airlock.dm | 128 ++++++++++++++++++ code/modules/wiremod/shell/bot.dm | 1 + code/modules/wiremod/shell/shell_items.dm | 7 + tgstation.dme | 1 + 16 files changed, 313 insertions(+), 49 deletions(-) create mode 100644 code/modules/wiremod/shell/airlock.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index a37ca2563e3..0d24b9ba172 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -761,13 +761,19 @@ /// from /obj/machinery/atmospherics/components/unary/cryo_cell/set_on(bool): (on) #define COMSIG_CRYO_SET_ON "cryo_set_on" +// /obj/machinery/atmospherics/components/binary/valve signals + +/// from /obj/machinery/atmospherics/components/binary/valve/toggle(): (on) +#define COMSIG_VALVE_SET_OPEN "valve_toggled" + // /obj/machinery/door/airlock signals //from /obj/machinery/door/airlock/open(): (forced) #define COMSIG_AIRLOCK_OPEN "airlock_open" //from /obj/machinery/door/airlock/close(): (forced) #define COMSIG_AIRLOCK_CLOSE "airlock_close" - +///from /obj/machinery/door/airlock/set_bolt(): +#define COMSIG_AIRLOCK_SET_BOLT "airlock_set_bolt" // /obj/item signals ///from base of obj/item/equipped(): (/mob/equipper, slot) diff --git a/code/__DEFINES/wiremod.dm b/code/__DEFINES/wiremod.dm index f1f29bf6e89..e912af0ebaa 100644 --- a/code/__DEFINES/wiremod.dm +++ b/code/__DEFINES/wiremod.dm @@ -84,6 +84,10 @@ // Clock component #define COMP_CLOCK_DELAY 0.9 SECONDS +// Radio component +#define COMP_RADIO_PUBLIC "public" +#define COMP_RADIO_PRIVATE "private" + // Shells /// Whether a circuit is stuck on a shell and cannot be removed (by a user) @@ -95,6 +99,9 @@ /// Whether or not the shell has a USB port. #define SHELL_FLAG_USB_PORT (1<<2) +/// Whether the shell allows actions to be peformed on a shell if the action fails. This will additionally block the messages from being displayed. +#define SHELL_FLAG_ALLOW_FAILURE_ACTION (1<<3) + // Shell capacities. These can be converted to configs very easily later #define SHELL_CAPACITY_SMALL 10 #define SHELL_CAPACITY_MEDIUM 25 diff --git a/code/datums/components/shell.dm b/code/datums/components/shell.dm index d0e546ae382..37381848252 100644 --- a/code/datums/components/shell.dm +++ b/code/datums/components/shell.dm @@ -133,6 +133,8 @@ return if(locked) + if(shell_flags & SHELL_FLAG_ALLOW_FAILURE_ACTION) + return source.balloon_alert(user, "it's locked!") return COMPONENT_BLOCK_TOOL_ATTACK @@ -148,6 +150,8 @@ return if(locked) + if(shell_flags & SHELL_FLAG_ALLOW_FAILURE_ACTION) + return source.balloon_alert(user, "it's locked!") return COMPONENT_BLOCK_TOOL_ATTACK diff --git a/code/datums/components/usb_port.dm b/code/datums/components/usb_port.dm index 9131e45f42d..4770fd600f8 100644 --- a/code/datums/components/usb_port.dm +++ b/code/datums/components/usb_port.dm @@ -19,13 +19,20 @@ if (!isatom(parent)) return COMPONENT_INCOMPATIBLE - src.circuit_component_types = circuit_component_types + circuit_components = list() + + for(var/circuit_component_type in circuit_component_types) + var/obj/item/circuit_component/circuit_component = new circuit_component_type(null) + circuit_components += circuit_component /datum/component/usb_port/RegisterWithParent() RegisterSignal(parent, COMSIG_ATOM_USB_CABLE_TRY_ATTACH, .proc/on_atom_usb_cable_try_attach) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_moved) RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) + for(var/obj/item/circuit_component/component as anything in circuit_components) + component.register_usb_parent(parent) + /datum/component/usb_port/UnregisterFromParent() UnregisterSignal(parent, list( COMSIG_ATOM_USB_CABLE_TRY_ATTACH, @@ -33,10 +40,14 @@ COMSIG_PARENT_EXAMINE, )) + for(var/obj/item/circuit_component/component as anything in circuit_components) + component.unregister_usb_parent(parent) + unregister_circuit_signals() + attached_circuit = null /datum/component/usb_port/Destroy() - QDEL_LAZYLIST(circuit_components) + QDEL_LIST(circuit_components) QDEL_NULL(usb_cable_beam) attached_circuit = null @@ -58,16 +69,12 @@ UnregisterSignal(shell, COMSIG_MOVABLE_MOVED) UnregisterSignal(shell, COMSIG_PARENT_EXAMINE) -/datum/component/usb_port/proc/create_circuit_components(obj/item/integrated_circuit/circuitboard) - var/created_circuit_components = list() +/datum/component/usb_port/proc/attach_circuit_components(obj/item/integrated_circuit/circuitboard) + for(var/obj/item/circuit_component/component as anything in circuit_components) + circuitboard.add_component(component) + RegisterSignal(component, COMSIG_CIRCUIT_COMPONENT_REMOVED, .proc/on_circuit_component_removed) - for(var/circuit_component_type in circuit_component_types) - var/obj/item/circuit_component/circuit_component = new circuit_component_type(parent) - circuitboard.add_component(circuit_component) - created_circuit_components += circuit_component - RegisterSignal(circuit_component, COMSIG_CIRCUIT_COMPONENT_REMOVED, .proc/on_circuit_component_removed) - - return created_circuit_components + return /datum/component/usb_port/proc/on_examine(datum/source, mob/user, list/examine_text) SIGNAL_HANDLER @@ -103,7 +110,7 @@ attached_circuit = connecting_cable.attached_circuit connecting_cable.forceMove(attached_circuit) - circuit_components = create_circuit_components(attached_circuit) + attach_circuit_components(attached_circuit) attached_circuit.interact(user) usb_cable_beam = atom_parent.Beam(attached_circuit.shell, "usb_cable_beam", 'icons/obj/wiremod.dmi') @@ -128,19 +135,15 @@ /datum/component/usb_port/proc/on_circuit_deleting() SIGNAL_HANDLER - unregister_circuit_signals() - attached_circuit = null + detach() qdel(usb_cable_ref) /datum/component/usb_port/proc/on_circuit_component_removed(datum/source) SIGNAL_HANDLER - - qdel(source) detach() /datum/component/usb_port/proc/on_circuit_shell_removed() SIGNAL_HANDLER - detach() /datum/component/usb_port/proc/detach() @@ -148,14 +151,17 @@ if (isnull(usb_cable)) return + for(var/obj/item/circuit_component/component as anything in circuit_components) + UnregisterSignal(component, COMSIG_CIRCUIT_COMPONENT_REMOVED) + attached_circuit.remove_component(component) + component.moveToNullspace() + unregister_circuit_signals() var/atom/atom_parent = parent usb_cable.forceMove(atom_parent.drop_location()) usb_cable.balloon_alert_to_viewers("snap") - QDEL_LAZYLIST(circuit_components) - attached_circuit = null usb_cable_ref = null diff --git a/code/game/machinery/computer/tram_controls.dm b/code/game/machinery/computer/tram_controls.dm index 5edb3b9895a..fa77b1fc6d8 100644 --- a/code/game/machinery/computer/tram_controls.dm +++ b/code/game/machinery/computer/tram_controls.dm @@ -117,24 +117,28 @@ var/datum/port/output/travelling_output /// The tram controls computer (/obj/machinery/computer/tram_controls) - var/datum/weakref/computer + var/obj/machinery/computer/tram_controls/computer /obj/item/circuit_component/tram_controls/Initialize() . = ..() - - var/obj/machinery/computer/tram_controls/computer_object = get(src, /obj/machinery/computer/tram_controls) - if (computer_object) - computer = WEAKREF(computer_object) - - RegisterSignal(computer_object.tram_part, COMSIG_TRAM_SET_TRAVELLING, .proc/on_tram_set_travelling) - RegisterSignal(computer_object.tram_part, COMSIG_TRAM_TRAVEL, .proc/on_tram_travel) - new_destination = add_input_port("Destination", PORT_TYPE_STRING, FALSE) trigger_move = add_input_port("Send Tram", PORT_TYPE_SIGNAL) location = add_output_port("Location", PORT_TYPE_STRING) travelling_output = add_output_port("Travelling", PORT_TYPE_NUMBER) +/obj/item/circuit_component/tram_controls/register_usb_parent(atom/movable/parent) + . = ..() + if (istype(parent, /obj/machinery/computer/tram_controls)) + computer = parent + RegisterSignal(computer.tram_part, COMSIG_TRAM_SET_TRAVELLING, .proc/on_tram_set_travelling) + RegisterSignal(computer.tram_part, COMSIG_TRAM_TRAVEL, .proc/on_tram_travel) + +/obj/item/circuit_component/tram_controls/unregister_usb_parent(atom/movable/parent) + computer = null + UnregisterSignal(computer.tram_part, list(COMSIG_TRAM_SET_TRAVELLING, COMSIG_TRAM_TRAVEL)) + return ..() + /obj/item/circuit_component/tram_controls/Destroy() new_destination = null trigger_move = null @@ -151,12 +155,10 @@ if (!COMPONENT_TRIGGERED_BY(trigger_move, port)) return - var/obj/machinery/computer/tram_controls/tram_controls = computer.resolve() - - if (isnull(tram_controls)) + if (isnull(computer)) return - if (!tram_controls.powered()) + if (!computer.powered()) return var/destination @@ -169,14 +171,12 @@ if (!destination) return - tram_controls.try_send_tram(destination) + computer.try_send_tram(destination) /obj/item/circuit_component/tram_controls/proc/on_tram_set_travelling(datum/source, travelling) SIGNAL_HANDLER - travelling_output.set_output(travelling) /obj/item/circuit_component/tram_controls/proc/on_tram_travel(datum/source, obj/effect/landmark/tram/from_where, obj/effect/landmark/tram/to_where) SIGNAL_HANDLER - location.set_output(to_where.name) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 7586996d18e..ac797262123 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -298,18 +298,25 @@ /obj/machinery/door/airlock/proc/bolt() if(locked) return - locked = TRUE + set_bolt(TRUE) playsound(src,boltDown,30,FALSE,3) audible_message(span_hear("You hear a click from the bottom of the door."), null, 1) update_appearance() +/obj/machinery/door/airlock/proc/set_bolt(should_bolt) + if(locked == should_bolt) + return + SEND_SIGNAL(src, COMSIG_AIRLOCK_SET_BOLT, should_bolt) + . = locked + locked = should_bolt + /obj/machinery/door/airlock/unlock() unbolt() /obj/machinery/door/airlock/proc/unbolt() if(!locked) return - locked = FALSE + set_bolt(FALSE) playsound(src,boltUp,30,FALSE,3) audible_message(span_hear("You hear a click from the bottom of the door."), null, 1) update_appearance() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm index 8075bb2901f..ad2fd531cb6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm @@ -28,20 +28,24 @@ It's like a regular ol' straight pipe, but you can turn it on and off. /** * Called by finish_interact(), switch between open and closed, reconcile the air between two pipelines */ -/obj/machinery/atmospherics/components/binary/valve/proc/toggle() +/obj/machinery/atmospherics/components/binary/valve/proc/set_open(to_open) + if(on == to_open) + return + SEND_SIGNAL(src, COMSIG_VALVE_SET_OPEN, to_open) + . = on + on = to_open if(on) - on = FALSE - update_icon_nopipes() - investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) - vent_movement &= ~VENTCRAWL_ALLOWED - else - on = TRUE update_icon_nopipes() update_parents() var/datum/pipeline/parent1 = parents[1] parent1.reconcile_air() investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) vent_movement |= VENTCRAWL_ALLOWED + else + update_icon_nopipes() + investigate_log("was closed by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS) + vent_movement &= ~VENTCRAWL_ALLOWED + /obj/machinery/atmospherics/components/binary/valve/interact(mob/user) add_fingerprint(usr) @@ -55,7 +59,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off. * Called by iteract() after a 1 second timer, calls toggle(), allows another interaction with the component. */ /obj/machinery/atmospherics/components/binary/valve/proc/finish_interact() - toggle() + set_open(!on) switching = FALSE /obj/machinery/atmospherics/components/binary/valve/digital // can be controlled by AI @@ -68,6 +72,68 @@ It's like a regular ol' straight pipe, but you can turn it on and off. interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE | INTERACT_MACHINE_OPEN | INTERACT_MACHINE_OPEN_SILICON +/obj/machinery/atmospherics/components/binary/valve/digital/Initialize() + . = ..() + AddComponent(/datum/component/usb_port, list(/obj/item/circuit_component/digital_valve)) + +/obj/item/circuit_component/digital_valve + display_name = "Digital Valve" + display_desc = "The interface for communicating with a digital valve." + + var/obj/machinery/atmospherics/components/binary/valve/digital/attached_valve + + /// Opens the digital valve + var/datum/port/input/open + /// Closes the digital valve + var/datum/port/input/close + + /// Whether the valve is currently open + var/datum/port/output/is_open + /// Sent when the valve is opened + var/datum/port/output/opened + /// Sent when the valve is closed + var/datum/port/output/closed + +/obj/item/circuit_component/digital_valve/Initialize() + . = ..() + open = add_input_port("Open", PORT_TYPE_SIGNAL) + close = add_input_port("Close", PORT_TYPE_SIGNAL) + + is_open = add_output_port("Is Open", PORT_TYPE_NUMBER) + opened = add_output_port("Opened", PORT_TYPE_SIGNAL) + closed = add_output_port("Closed", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/digital_valve/register_usb_parent(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/atmospherics/components/binary/valve/digital)) + attached_valve = shell + RegisterSignal(attached_valve, COMSIG_VALVE_SET_OPEN, .proc/handle_valve_toggled) + +/obj/item/circuit_component/digital_valve/unregister_usb_parent(atom/movable/shell) + UnregisterSignal(attached_valve, COMSIG_VALVE_SET_OPEN) + attached_valve = null + return ..() + +/obj/item/circuit_component/digital_valve/proc/handle_valve_toggled(datum/source, on) + is_open.set_output(on) + if(on) + opened.set_output(COMPONENT_SIGNAL) + else + closed.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/digital_valve/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!attached_valve) + return + + if(COMPONENT_TRIGGERED_BY(open, port) && !attached_valve.on) + attached_valve.set_open(TRUE) + if(COMPONENT_TRIGGERED_BY(close, port) && attached_valve.on) + attached_valve.set_open(FALSE) + /obj/machinery/atmospherics/components/binary/valve/digital/update_icon_nopipes(animation) if(!is_operational) normalize_cardinal_directions() diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm index b45c463e042..25aa7f227fa 100644 --- a/code/modules/research/designs/wiremod_designs.dm +++ b/code/modules/research/designs/wiremod_designs.dm @@ -244,3 +244,15 @@ build_path = /obj/item/shell/server build_type = PROTOLATHE | COMPONENT_PRINTER category = list("Circuitry", "Shells") + +/datum/design/airlock_shell + name = "Airlock Shell" + desc = "A door shell that cannot be moved around when assembled." + id = "door_shell" + materials = list( + /datum/material/glass = 5000, + /datum/material/iron = 15000, + ) + build_path = /obj/item/shell/airlock + build_type = PROTOLATHE | COMPONENT_PRINTER + category = list("Circuitry", "Shells") diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index e6ee1de061c..addf254bf73 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -644,6 +644,7 @@ prereq_ids = list("basic_circuitry", "engineering") design_ids = list( "bot_shell", + "door_shell", "controller_shell", "money_bot_shell", ) diff --git a/code/modules/wiremod/component.dm b/code/modules/wiremod/component.dm index efffd358763..0dcfd6358db 100644 --- a/code/modules/wiremod/component.dm +++ b/code/modules/wiremod/component.dm @@ -231,3 +231,9 @@ "content" = "Power Usage Per Input: [power_usage_per_input]", "color" = "orange", )) + +/obj/item/circuit_component/proc/register_usb_parent(atom/movable/parent) + return + +/obj/item/circuit_component/proc/unregister_usb_parent(atom/movable/parent) + return diff --git a/code/modules/wiremod/components/action/radio.dm b/code/modules/wiremod/components/action/radio.dm index b0b5fa58fa9..88c46bd93ac 100644 --- a/code/modules/wiremod/components/action/radio.dm +++ b/code/modules/wiremod/components/action/radio.dm @@ -5,7 +5,7 @@ */ /obj/item/circuit_component/radio display_name = "Radio" - display_desc = "A component that can listen and send frequencies." + display_desc = "A component that can listen and send frequencies. If set to private, the component will only receive signals from other components attached to circuitboards with the same owner id." /// Frequency input var/datum/port/input/freq @@ -17,10 +17,18 @@ var/datum/radio_frequency/radio_connection +/obj/item/circuit_component/radio/populate_options() + var/static/component_options = list( + COMP_RADIO_PUBLIC, + COMP_RADIO_PRIVATE, + ) + options = component_options + /obj/item/circuit_component/radio/Initialize() . = ..() freq = add_input_port("Frequency", PORT_TYPE_NUMBER, default = FREQ_SIGNALER) code = add_input_port("Code", PORT_TYPE_NUMBER, default = DEFAULT_SIGNALER_CODE) + TRIGGER_CIRCUIT_COMPONENT(src, null) // These are cleaned up on the parent trigger_input = add_input_port("Send", PORT_TYPE_SIGNAL) trigger_output = add_output_port("Received", PORT_TYPE_SIGNAL) @@ -44,7 +52,7 @@ current_freq = frequency if(COMPONENT_TRIGGERED_BY(trigger_input, port)) - var/datum/signal/signal = new(list("code" = round(code.input_value) || 0)) + var/datum/signal/signal = new(list("code" = round(code.input_value) || 0, "key" = parent?.owner_id)) radio_connection.post_signal(src, signal) /obj/item/circuit_component/radio/receive_signal(datum/signal/signal) @@ -54,4 +62,7 @@ if(signal.data["code"] != round(code.input_value || 0)) return + if(current_option == COMP_RADIO_PRIVATE && parent?.owner_id != signal.data["key"]) + return + trigger_output.set_output(COMPONENT_SIGNAL) diff --git a/code/modules/wiremod/integrated_circuit.dm b/code/modules/wiremod/integrated_circuit.dm index 6463334bbf9..40476c4c0ba 100644 --- a/code/modules/wiremod/integrated_circuit.dm +++ b/code/modules/wiremod/integrated_circuit.dm @@ -329,7 +329,8 @@ return component.disconnect() remove_component(component) - usr.put_in_hands(component) + if(component.loc == src) + usr.put_in_hands(component) . = TRUE if("set_component_coordinates") var/component_id = text2num(params["component_id"]) diff --git a/code/modules/wiremod/shell/airlock.dm b/code/modules/wiremod/shell/airlock.dm new file mode 100644 index 00000000000..c14511e9eb1 --- /dev/null +++ b/code/modules/wiremod/shell/airlock.dm @@ -0,0 +1,128 @@ +/obj/machinery/door/airlock/shell + name = "circuit airlock" + autoclose = FALSE + +/obj/machinery/door/airlock/shell/Initialize() + . = ..() + AddComponent( \ + /datum/component/shell, \ + unremovable_circuit_components = list(new /obj/item/circuit_component/airlock), \ + capacity = SHELL_CAPACITY_LARGE, \ + shell_flags = SHELL_FLAG_ALLOW_FAILURE_ACTION \ + ) + +/obj/machinery/door/airlock/shell/check_access(obj/item/I) + return FALSE + +/obj/item/circuit_component/airlock + display_name = "Airlock" + display_desc = "The general interface with an airlock. Includes general statuses of the airlock" + + /// Called when attack_hand is called on the shell. + var/obj/machinery/door/airlock/attached_airlock + + /// Bolts the airlock (if possible) + var/datum/port/input/bolt + /// Unbolts the airlock (if possible) + var/datum/port/input/unbolt + /// Opens the airlock (if possible) + var/datum/port/input/open + /// Closes the airlock (if possible) + var/datum/port/input/close + + /// Contains whether the airlock is open or not + var/datum/port/output/is_open + /// Contains whether the airlock is bolted or not + var/datum/port/output/is_bolted + + /// Called when the airlock is opened. + var/datum/port/output/opened + /// Called when the airlock is closed + var/datum/port/output/closed + + /// Called when the airlock is bolted + var/datum/port/output/bolted + /// Called when the airlock is unbolted + var/datum/port/output/unbolted + +/obj/item/circuit_component/airlock/Initialize() + . = ..() + // Input Signals + bolt = add_input_port("Bolt", PORT_TYPE_SIGNAL) + unbolt = add_input_port("Unbolt", PORT_TYPE_SIGNAL) + open = add_input_port("Open", PORT_TYPE_SIGNAL) + close = add_input_port("Close", PORT_TYPE_SIGNAL) + // States + is_open = add_output_port("Is Open", PORT_TYPE_NUMBER) + is_bolted = add_output_port("Is Bolted", PORT_TYPE_NUMBER) + // Output Signals + opened = add_output_port("Opened", PORT_TYPE_SIGNAL) + closed = add_output_port("Closed", PORT_TYPE_SIGNAL) + bolted = add_output_port("Bolted", PORT_TYPE_SIGNAL) + unbolted = add_output_port("Unbolted", PORT_TYPE_SIGNAL) + +/obj/item/circuit_component/airlock/Destroy() + bolt = null + unbolt = null + open = null + close = null + is_open = null + is_bolted = null + opened = null + closed = null + bolted = null + unbolted = null + attached_airlock = null + return ..() + +/obj/item/circuit_component/airlock/register_shell(atom/movable/shell) + . = ..() + if(istype(shell, /obj/machinery/door/airlock)) + attached_airlock = shell + RegisterSignal(shell, COMSIG_AIRLOCK_SET_BOLT, .proc/on_airlock_set_bolted) + RegisterSignal(shell, COMSIG_AIRLOCK_OPEN, .proc/on_airlock_open) + RegisterSignal(shell, COMSIG_AIRLOCK_CLOSE, .proc/on_airlock_closed) + +/obj/item/circuit_component/airlock/unregister_shell(atom/movable/shell) + attached_airlock = null + UnregisterSignal(shell, list( + COMSIG_AIRLOCK_SET_BOLT, + COMSIG_AIRLOCK_OPEN, + COMSIG_AIRLOCK_CLOSE, + )) + return ..() + +/obj/item/circuit_component/airlock/proc/on_airlock_set_bolted(datum/source, should_bolt) + SIGNAL_HANDLER + is_bolted.set_output(should_bolt) + if(should_bolt) + bolted.set_output(COMPONENT_SIGNAL) + else + unbolted.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/proc/on_airlock_open(datum/source, force) + SIGNAL_HANDLER + is_open.set_output(TRUE) + opened.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/proc/on_airlock_closed(datum/source, forced) + SIGNAL_HANDLER + is_open.set_output(FALSE) + closed.set_output(COMPONENT_SIGNAL) + +/obj/item/circuit_component/airlock/input_received(datum/port/input/port) + . = ..() + if(.) + return + + if(!attached_airlock) + return + + if(COMPONENT_TRIGGERED_BY(bolt, port)) + attached_airlock.bolt() + if(COMPONENT_TRIGGERED_BY(unbolt, port)) + attached_airlock.unbolt() + if(COMPONENT_TRIGGERED_BY(open, port) && attached_airlock.density) + INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/open) + if(COMPONENT_TRIGGERED_BY(close, port) && !attached_airlock.density) + INVOKE_ASYNC(attached_airlock, /obj/machinery/door/airlock.proc/close) diff --git a/code/modules/wiremod/shell/bot.dm b/code/modules/wiremod/shell/bot.dm index 73c782e3993..752cb06af41 100644 --- a/code/modules/wiremod/shell/bot.dm +++ b/code/modules/wiremod/shell/bot.dm @@ -23,6 +23,7 @@ /obj/item/circuit_component/bot display_name = "Bot" + display_desc = "Triggers when someone interacts with the bot." /// Called when attack_hand is called on the shell. var/datum/port/output/signal diff --git a/code/modules/wiremod/shell/shell_items.dm b/code/modules/wiremod/shell/shell_items.dm index 2fde05f8ef1..6f2abdfd12b 100644 --- a/code/modules/wiremod/shell/shell_items.dm +++ b/code/modules/wiremod/shell/shell_items.dm @@ -45,3 +45,10 @@ icon_state = "setup_stationary-open" shell_to_spawn = /obj/structure/server screw_delay = 10 SECONDS + +/obj/item/shell/airlock + name = "circuit airlock assembly" + icon = 'icons/obj/doors/airlocks/station/public.dmi' + icon_state = "construction" + shell_to_spawn = /obj/machinery/door/airlock/shell + screw_delay = 10 SECONDS diff --git a/tgstation.dme b/tgstation.dme index b66b1b7845b..3c2b86f4fe4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3598,6 +3598,7 @@ #include "code\modules\wiremod\components\utility\typecheck.dm" #include "code\modules\wiremod\preset\hello_world.dm" #include "code\modules\wiremod\preset\speech_relay.dm" +#include "code\modules\wiremod\shell\airlock.dm" #include "code\modules\wiremod\shell\bot.dm" #include "code\modules\wiremod\shell\compact_remote.dm" #include "code\modules\wiremod\shell\controller.dm"