From 0036bea6b6f918413ae394112c17bbf2d66bfcb9 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Sat, 26 Jul 2014 20:07:18 +0200 Subject: [PATCH] A sensor which registers mechs and trains attempting to pass by and, if necessary, blocks their movement. If enabled, detects mechs/trains and blocks their movement if they are coming from any of the directions set by dir. Can currently only be enabled/disabled by radio command and airlocks are updated to utilize this. The current setup allows mechs to move through airlocks during normal cycles, which for example lets Odysseus out to save lives. Once a shuttle docks however, the sensors are enabled to prevent boarding. If blocked, players receive a simple message stating that their command has been overridden. --- .../airlock_controllers.dm | 13 +-- .../airlock_docking_controller.dm | 15 +++- .../embedded_controller/airlock_program.dm | 17 ++-- .../docking_program_multi.dm | 52 +++++------ code/game/mecha/mech_sensor.dm | 86 +++++++++++++++++++ 5 files changed, 143 insertions(+), 40 deletions(-) create mode 100644 code/game/mecha/mech_sensor.dm diff --git a/code/game/machinery/embedded_controller/airlock_controllers.dm b/code/game/machinery/embedded_controller/airlock_controllers.dm index 96177f9a9d..4a2a9c5e56 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers.dm @@ -7,6 +7,7 @@ var/tag_chamber_sensor var/tag_exterior_sensor var/tag_interior_sensor + var/tag_mech_sensor var/tag_secure = 0 /obj/machinery/embedded_controller/radio/airlock/initialize() @@ -43,10 +44,10 @@ /obj/machinery/embedded_controller/radio/airlock/advanced_airlock_controller/Topic(href, href_list) if(..()) return - + usr.set_machine(src) src.add_fingerprint(usr) - + var/clean = 0 switch(href_list["command"]) //anti-HTML-hacking checks if("cycle_ext") @@ -99,10 +100,10 @@ /obj/machinery/embedded_controller/radio/airlock/airlock_controller/Topic(href, href_list) if(..()) return - + usr.set_machine(src) src.add_fingerprint(usr) - + var/clean = 0 switch(href_list["command"]) //anti-HTML-hacking checks if("cycle_ext") @@ -163,10 +164,10 @@ /obj/machinery/embedded_controller/radio/airlock/access_controller/Topic(href, href_list) if(..()) return - + usr.set_machine(src) src.add_fingerprint(usr) - + var/clean = 0 switch(href_list["command"]) //anti-HTML-hacking checks if("cycle_ext_door") diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm index b0469bd030..a78ac2be2d 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm @@ -35,10 +35,10 @@ /obj/machinery/embedded_controller/radio/airlock/docking_port/Topic(href, href_list) if(..()) return - + usr.set_machine(src) src.add_fingerprint(usr) - + var/clean = 0 switch(href_list["command"]) //anti-HTML-hacking checks if("cycle_ext") @@ -77,7 +77,7 @@ else enable_override() return - + ..(command) airlock_program.receive_user_command(command) //pass along to subprograms @@ -99,12 +99,14 @@ //we are docked, open the doors or whatever. /datum/computer/file/embedded_program/docking/airlock/finish_docking() + airlock_program.enable_mech_regulators() airlock_program.open_doors() //tell the docking port to start getting ready for undocking - e.g. close those doors. /datum/computer/file/embedded_program/docking/airlock/prepare_for_undocking() airlock_program.stop_cycling() airlock_program.close_doors() + airlock_program.disable_mech_regulators() //are we ready for undocking? /datum/computer/file/embedded_program/docking/airlock/ready_for_undocking() @@ -115,13 +117,18 @@ //An airlock controller to be used by the airlock-based docking port controller. //Same as a regular airlock controller but allows disabling of the regular airlock functions when docking /datum/computer/file/embedded_program/airlock/docking - var/datum/computer/file/embedded_program/docking/airlock/master_prog /datum/computer/file/embedded_program/airlock/docking/receive_user_command(command) if (master_prog.undocked() || master_prog.override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled ..(command) +/datum/computer/file/embedded_program/airlock/docking/proc/enable_mech_regulators() + enable_mech_regulation() + +/datum/computer/file/embedded_program/airlock/docking/proc/disable_mech_regulators() + disable_mech_regulation() + /datum/computer/file/embedded_program/airlock/docking/proc/open_doors() toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "open") toggleDoor(memory["exterior_status"], tag_exterior_door, memory["secure"], "open") diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index 3d7d306df3..90a2ca5720 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -16,13 +16,14 @@ var/tag_chamber_sensor var/tag_exterior_sensor var/tag_interior_sensor + var/tag_mech_sensor var/state = STATE_WAIT var/target_state = TARGET_NONE /datum/computer/file/embedded_program/airlock/New(var/obj/machinery/embedded_controller/M) ..(M) - + memory["chamber_sensor_pressure"] = ONE_ATMOSPHERE memory["external_sensor_pressure"] = 0 //assume vacuum for simple airlock controller memory["internal_sensor_pressure"] = ONE_ATMOSPHERE @@ -32,7 +33,7 @@ memory["target_pressure"] = ONE_ATMOSPHERE memory["purge"] = 0 memory["secure"] = 0 - + if (istype(M, /obj/machinery/embedded_controller/radio/airlock)) //if our controller is an airlock controller than we can auto-init our tags var/obj/machinery/embedded_controller/radio/airlock/controller = M tag_exterior_door = controller.tag_exterior_door? controller.tag_exterior_door : "[id_tag]_outer" @@ -41,8 +42,9 @@ tag_chamber_sensor = controller.tag_chamber_sensor? controller.tag_chamber_sensor : "[id_tag]_sensor" tag_exterior_sensor = controller.tag_exterior_sensor tag_interior_sensor = controller.tag_interior_sensor + tag_mech_sensor = controller.tag_mech_sensor? controller.tag_mech_sensor : "[id_tag]_mech" memory["secure"] = controller.tag_secure - + spawn(10) signalDoor(tag_exterior_door, "update") //signals connected doors to update their status signalDoor(tag_interior_door, "update") @@ -187,11 +189,11 @@ //make sure to return to a sane idle state if(memory["pump_status"] != "off") //send a signal to stop pumping signalPump(tag_airpump, 0) - + //the airlock will not allow itself to continue to cycle when any of the doors are forced open. if (state && !check_doors_secured()) stop_cycling() - + switch(state) if(STATE_PRESSURIZE) if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95) @@ -293,6 +295,11 @@ signalDoor(tag_exterior_door, command) signalDoor(tag_interior_door, command) +/datum/computer/file/embedded_program/airlock/proc/enable_mech_regulation() + signalDoor(tag_mech_sensor, "enable") + +/datum/computer/file/embedded_program/airlock/proc/disable_mech_regulation() + signalDoor(tag_mech_sensor, "disable") /*---------------------------------------------------------- toggleDoor() diff --git a/code/game/machinery/embedded_controller/docking_program_multi.dm b/code/game/machinery/embedded_controller/docking_program_multi.dm index 43906f9d5f..46f7538afd 100644 --- a/code/game/machinery/embedded_controller/docking_program_multi.dm +++ b/code/game/machinery/embedded_controller/docking_program_multi.dm @@ -13,12 +13,12 @@ /datum/computer/file/embedded_program/docking/multi/New(var/obj/machinery/embedded_controller/M) ..(M) - + if (istype(M,/obj/machinery/embedded_controller/radio/docking_port_multi)) //if our parent controller is the right type, then we can auto-init stuff at construction var/obj/machinery/embedded_controller/radio/docking_port_multi/controller = M //parse child_tags_txt and create child tags children_tags = text2list(controller.child_tags_txt, ";") - + children_ready = list() children_override = list() for (var/child_tag in children_tags) @@ -33,13 +33,13 @@ var/receive_tag = signal.data["tag"] //for docking signals, this is the sender id var/command = signal.data["command"] var/recipient = signal.data["recipient"] //the intended recipient of the docking signal - + if (receive_tag in children_tags) - + //track children status if (signal.data["override_status"]) children_override[receive_tag] = signal.data["override_status"] - + if (recipient == id_tag) switch (command) if ("ready_for_docking") @@ -50,13 +50,13 @@ children_override[receive_tag] = 1 if ("status_override_disabled") children_override[receive_tag] = 0 - + ..(signal, receive_method, receive_param) /datum/computer/file/embedded_program/docking/multi/prepare_for_docking() //clear children ready status clear_children_ready_status() - + //tell children to prepare for docking for (var/child_tag in children_tags) send_docking_command(child_tag, "prepare_for_docking") @@ -72,14 +72,14 @@ //tell children to finish docking for (var/child_tag in children_tags) send_docking_command(child_tag, "finish_docking") - + //clear ready flags clear_children_ready_status() /datum/computer/file/embedded_program/docking/multi/prepare_for_undocking() //clear children ready status clear_children_ready_status() - + //tell children to prepare for undocking for (var/child_tag in children_tags) send_docking_command(child_tag, "prepare_for_undocking") @@ -95,7 +95,7 @@ //tell children to finish undocking for (var/child_tag in children_tags) send_docking_command(child_tag, "finish_undocking") - + //clear ready flags clear_children_ready_status() @@ -108,7 +108,7 @@ */ /datum/computer/file/embedded_program/airlock/multi_docking var/master_tag - + var/master_status = "undocked" var/override_enabled = 0 var/docking_enabled = 0 @@ -117,7 +117,7 @@ /datum/computer/file/embedded_program/airlock/multi_docking/New(var/obj/machinery/embedded_controller/M) ..(M) - + if (istype(M, /obj/machinery/embedded_controller/radio/airlock/docking_port_multi)) //if our parent controller is the right type, then we can auto-init stuff at construction var/obj/machinery/embedded_controller/radio/airlock/docking_port_multi/controller = M src.master_tag = controller.master_tag @@ -131,56 +131,58 @@ override_enabled = 1 broadcast_override_status() return - + if (!docking_enabled|| override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled ..(command) /datum/computer/file/embedded_program/airlock/multi_docking/receive_signal(datum/signal/signal, receive_method, receive_param) ..() - + var/receive_tag = signal.data["tag"] //for docking signals, this is the sender id var/command = signal.data["command"] var/recipient = signal.data["recipient"] //the intended recipient of the docking signal - + if (receive_tag != master_tag) return //only respond to master - + //track master's status if (signal.data["dock_status"]) master_status = signal.data["dock_status"] - + if (recipient != id_tag) return //this signal is not for us - + switch (command) if ("prepare_for_docking") docking_enabled = 1 docking_mode = 0 response_sent = 0 - + if (!override_enabled) begin_cycle_in() - + if ("prepare_for_undocking") docking_mode = 1 response_sent = 0 - + if (!override_enabled) stop_cycling() close_doors() - + disable_mech_regulation() + if ("finish_docking") if (!override_enabled) + enable_mech_regulation() open_doors() - + if ("finish_undocking") docking_enabled = 0 /datum/computer/file/embedded_program/airlock/multi_docking/process() ..() - + if (docking_enabled && !response_sent) - + switch (docking_mode) if (0) //docking if (ready_for_docking()) diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm new file mode 100644 index 0000000000..cd85465706 --- /dev/null +++ b/code/game/mecha/mech_sensor.dm @@ -0,0 +1,86 @@ +/obj/machinery/mech_sensor + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "airlock_sensor_off" + name = "mechatronic sensor" + desc = "Regulates mech movement." + anchored = 1 + density = 1 + throwpass = 1 + use_power = 1 + layer = 3.3 + power_channel = EQUIP + var/on = 0 + var/id_tag = null + + var/frequency = 1379 + var/datum/radio_frequency/radio_connection + +/obj/machinery/mech_sensor/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(!src.enabled()) return 1 + if(air_group || (height==0)) return 1 + + if ((get_dir(loc, target) & dir) && src.is_blocked(mover)) + src.give_feedback(mover) + return 0 + return 1 + +/obj/machinery/mech_sensor/proc/is_blocked(O as obj) + return istype(O, /obj/mecha) || istype(O, /obj/vehicle) + +/obj/machinery/mech_sensor/proc/give_feedback(O as obj) + var/block_message = "Movement control overridden. Area denial active." + var/feedback_timer = 0 + if(feedback_timer) + return + + if(istype(O, /obj/mecha)) + var/obj/mecha/R = O + if(R && R.occupant) + R.occupant << block_message + else if(istype(O, /obj/vehicle/train/cargo/engine)) + var/obj/vehicle/train/cargo/engine/E = O + if(E && E.load && E.is_train_head()) + E.load << block_message + + feedback_timer = 1 + spawn(5) //Without this timer the feedback becomes horribly spamy + feedback_timer = 0 + +/obj/machinery/mech_sensor/proc/enabled() + return on && !(stat & NOPOWER) + +/obj/machinery/mech_sensor/power_change() + var/old_stat = stat + ..() + if(old_stat != stat) + update_icon() + +/obj/machinery/mech_sensor/update_icon(var/safety = 0) + if (enabled()) + icon_state = "airlock_sensor_on" + else + icon_state = "airlock_sensor_off" + +/obj/machinery/mech_sensor/initialize() + set_frequency(frequency) + +/obj/machinery/mech_sensor/proc/set_frequency(new_frequency) + if(radio_connection) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + if(frequency) + radio_connection = radio_controller.add_object(src, frequency) + +/obj/machinery/mech_sensor/receive_signal(datum/signal/signal) + if(stat & NOPOWER) + return + + if(!signal.data["tag"] || (signal.data["tag"] != id_tag)) + return + + if(signal.data["command"] == "enable") + on = 1 + else if (signal.data["command"] == "disable") + on = 0 + + update_icon()