/obj/machinery/keycard_auth name = "Keycard Authentication Device" desc = "This device is used to trigger station functions, which require more than one ID card to authenticate." icon = 'icons/obj/monitors.dmi' icon_state = "auth_off" var/active = 0 //This gets set to 1 on all devices except the one where the initial request was made. var/event = "" var/screen = 1 var/list/ert_chosen = list() var/confirmed = 0 //This variable is set by the device that confirms the request. var/confirm_delay = 20 //(2 seconds) var/busy = 0 //Busy when waiting for authentication or an event request has been sent from this device. var/obj/machinery/keycard_auth/event_source var/mob/event_triggered_by var/mob/event_confirmed_by var/ert_reason = "Reason for ERT" anchored = 1 use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 power_channel = ENVIRON req_access = list(ACCESS_KEYCARD_AUTH) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF /obj/machinery/keycard_auth/attack_ai(mob/user as mob) to_chat(user, "The station AI is not to interact with these devices.") return /obj/machinery/keycard_auth/attackby(obj/item/W as obj, mob/user as mob, params) if(stat & (NOPOWER|BROKEN)) to_chat(user, "This device is not powered.") return if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda)) if(check_access(W)) if(active == 1) //This is not the device that made the initial request. It is the device confirming the request. if(event_source) event_source.confirmed = 1 event_source.event_confirmed_by = usr else if(screen == 2) if(event == "Emergency Response Team" && ert_reason == "Reason for ERT") to_chat(user, "Supply a reason for calling the ERT first!") return event_triggered_by = usr broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices else to_chat(user, "Access denied.") return return ..() /obj/machinery/keycard_auth/power_change() if(powered(ENVIRON)) stat &= ~NOPOWER icon_state = "auth_off" else stat |= NOPOWER /obj/machinery/keycard_auth/attack_ghost(mob/user) ui_interact(user) /obj/machinery/keycard_auth/attack_hand(mob/user as mob) if(..()) return 1 ui_interact(user) /obj/machinery/keycard_auth/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(busy) to_chat(user, "This device is busy.") return user.set_machine(src) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "keycard_auth.tmpl", "Keycard Authentication Device UI", 540, 320) ui.open() /obj/machinery/keycard_auth/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) var/data[0] data["screen"] = screen data["event"] = event data["ertreason"] = ert_reason return data /obj/machinery/keycard_auth/Topic(href, href_list) if(..()) return 1 if(busy) to_chat(usr, "This device is busy.") return if(href_list["triggerevent"]) event = href_list["triggerevent"] screen = 2 if(href_list["reset"]) reset() if(href_list["ert"]) ert_reason = stripped_input(usr, "Reason for ERT Call:", "", "") SSnanoui.update_uis(src) add_fingerprint(usr) return /obj/machinery/keycard_auth/proc/reset() active = 0 event = "" screen = 1 confirmed = 0 event_source = null icon_state = "auth_off" event_triggered_by = null event_confirmed_by = null /obj/machinery/keycard_auth/proc/broadcast_request() icon_state = "auth_on" for(var/obj/machinery/keycard_auth/KA in GLOB.machines) if(KA == src) continue KA.reset() spawn() KA.receive_request(src) sleep(confirm_delay) if(confirmed) confirmed = 0 trigger_event(event) log_game("[key_name(event_triggered_by)] triggered and [key_name(event_confirmed_by)] confirmed event [event]") message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1) reset() /obj/machinery/keycard_auth/proc/receive_request(var/obj/machinery/keycard_auth/source) if(stat & (BROKEN|NOPOWER)) return event_source = source busy = 1 active = 1 icon_state = "auth_on" sleep(confirm_delay) event_source = null icon_state = "auth_off" active = 0 busy = 0 /obj/machinery/keycard_auth/proc/trigger_event() switch(event) if("Red Alert") set_security_level(SEC_LEVEL_RED) feedback_inc("alert_keycard_auth_red",1) if("Grant Emergency Maintenance Access") make_maint_all_access() feedback_inc("alert_keycard_auth_maintGrant",1) if("Revoke Emergency Maintenance Access") revoke_maint_all_access() feedback_inc("alert_keycard_auth_maintRevoke",1) if("Activate Station-Wide Emergency Access") make_station_all_access() feedback_inc("alert_keycard_auth_stationGrant",1) if("Deactivate Station-Wide Emergency Access") revoke_station_all_access() feedback_inc("alert_keycard_auth_stationRevoke",1) if("Emergency Response Team") if(is_ert_blocked()) atom_say("All Emergency Response Teams are dispatched and can not be called at this time.") return atom_say("ERT request transmitted!") GLOB.command_announcer.autosay("ERT request transmitted. Reason: [ert_reason]", name) print_centcom_report(ert_reason, station_time_timestamp() + " ERT Request") var/fullmin_count = 0 for(var/client/C in GLOB.admins) if(check_rights(R_EVENT, 0, C.mob)) fullmin_count++ if(fullmin_count) GLOB.ert_request_answered = TRUE ERT_Announce(ert_reason , event_triggered_by, 0) ert_reason = "Reason for ERT" feedback_inc("alert_keycard_auth_ert",1) spawn(3000) if(!GLOB.ert_request_answered) ERT_Announce(ert_reason , event_triggered_by, 1) else trigger_armed_response_team(new /datum/response_team/amber) // No admins? No problem. Automatically send a code amber ERT. /obj/machinery/keycard_auth/proc/is_ert_blocked() return SSticker.mode && SSticker.mode.ert_disabled GLOBAL_VAR_INIT(maint_all_access, 0) GLOBAL_VAR_INIT(station_all_access, 0) /proc/make_maint_all_access() for(var/area/maintenance/A in world) for(var/obj/machinery/door/airlock/D in A) D.emergency = 1 D.update_icon(0) GLOB.minor_announcement.Announce("Access restrictions on maintenance and external airlocks have been removed.") GLOB.maint_all_access = 1 /proc/revoke_maint_all_access() for(var/area/maintenance/A in world) for(var/obj/machinery/door/airlock/D in A) D.emergency = 0 D.update_icon(0) GLOB.minor_announcement.Announce("Access restrictions on maintenance and external airlocks have been re-added.") GLOB.maint_all_access = 0 /proc/make_station_all_access() for(var/obj/machinery/door/airlock/D in GLOB.airlocks) if(is_station_level(D.z)) D.emergency = 1 D.update_icon(0) GLOB.minor_announcement.Announce("Access restrictions on all station airlocks have been removed due to an ongoing crisis. Trespassing laws still apply unless ordered otherwise by Command staff.") GLOB.station_all_access = 1 /proc/revoke_station_all_access() for(var/obj/machinery/door/airlock/D in GLOB.airlocks) if(is_station_level(D.z)) D.emergency = 0 D.update_icon(0) GLOB.minor_announcement.Announce("Access restrictions on all station airlocks have been re-added. Seek station AI or a colleague's assistance if you are stuck.") GLOB.station_all_access = 0