diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 22894dd2c34..b8715810c69 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -808,6 +808,125 @@ GLOBAL_VAR(bomb_set) if(length(open_turfs)) return pick(open_turfs) +// MARK: NAD Scanner + +/obj/item/nad_scanner + name = "authentication disk decryptor" + desc = "A tiny tablet computer that can scan a nuclear authentication disk. The syndicate will relay the activation codes to you but it is likely the transmission will be intercepted by NT. Be prepared for a fight." + icon = 'icons/obj/device.dmi' + icon_state = "nadscanner" + worn_icon_state = "electronic" + inhand_icon_state = "electronic" + w_class = WEIGHT_CLASS_TINY + /// The currently stored NAD + var/obj/item/disk/nuclear/disky + /// Is the device currently scanning? + var/scanning = FALSE + /// Is the device done decryption? + var/decrypted = FALSE + + new_attack_chain = TRUE + +/obj/item/nad_scanner/examine(mob/user) + . = ..() + if(decrypted) + . += "It's burnt out!" + +/obj/item/nad_scanner/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(!istype(used, /obj/item/disk/nuclear)) + return ..() + if(disky) + to_chat(user, "There is already something in [src]!") + return ITEM_INTERACT_COMPLETE + + if(used.flags & NODROP || !user.transfer_item_to(used, src)) + to_chat(user, "[used] is stuck to your hand!") + return ITEM_INTERACT_COMPLETE + + to_chat(user, "You insert [used] into [src].") + disky = used + playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) + update_icon(UPDATE_ICON_STATE) + +/obj/item/nad_scanner/update_icon_state(updates) + icon_state = "nadscanner" + if(!disky) + return + if(decrypted) + icon_state += "_decrypted" + else if(scanning) + icon_state += "_decrypting" + else if(disky) + icon_state += "_insert" + +/obj/item/nad_scanner/activate_self(mob/user) + if(world.time < 45 MINUTES) // 45 minutes of no nuke + to_chat(user, "[src] is still calibrating. Please wait another [round((27000 - world.time) / 600)] minutes before trying again.") + return ..() + scan_nad(user) + return ..() + +/obj/item/nad_scanner/AltClick(mob/user, modifiers) + if(scanning) + to_chat(user, "The disk is currently being scanned!") + return ..() + eject_nad(user) + return ..() + +/obj/item/nad_scanner/proc/eject_nad(mob/living/carbon/user) + if(!disky) + return + var/mob/M = user + M.put_in_hands(disky) + to_chat(user, "You remove [disky] from [src].") + disky = null + update_icon(UPDATE_ICON_STATE) + playsound(src, 'sound/machines/terminal_eject.ogg', 50, TRUE) + +/obj/item/nad_scanner/proc/scan_nad(mob/user) + if(!disky) + to_chat(user, "There is no disk inserted!") + return + if(decrypted) + to_chat(user, "This device is burnt out!") + return + if(scanning) + to_chat(user, "You are already scanning a disk!") + return + scanning = TRUE + to_chat(user, "You start the decryption process.") + update_icon(UPDATE_ICON_STATE) + if(!do_after(user, 10 SECONDS, needhand = FALSE, target = src, allow_moving = TRUE, hidden = TRUE)) + to_chat(user, "You stop the decryption process.") + return + if(istype(disky, /obj/item/disk/nuclear/training)) + atom_say("Incompatible disk detected!") + scanning = FALSE + update_icon(UPDATE_ICON_STATE) + return + var/complete_message = "We have intercepted a syndicate communication inbound to your station. The message reads: \n\"We have decrypted the codes from the nuclear authentication disk." + var/code + for(var/obj/machinery/nuclearbomb/bombue in SSmachines.get_by_type(/obj/machinery/nuclearbomb)) + if(length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN") + code = bombue.r_code + break + if(!code) + atom_say("No nuclear device detected!") + return + complete_message += " The code is [code]. Take those scum down.\" \n" + complete_message += "We suspect the syndicate is trying to detonate your nuclear device. All crew are to ensure this does not happen." + + GLOB.major_announcement.Announce( + complete_message, + new_title = "Enemy Communication Intercepted", + new_subtitle = "Intercepted Syndicate Communique", + new_sound = 'sound/AI/intercept.ogg' + ) + print_command_report(complete_message, "Intercepted Syndicate Communique") + decrypted = TRUE + scanning = FALSE + update_icon(UPDATE_ICON_STATE) + // MARK: Training Nuke /obj/machinery/nuclearbomb/training diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 54cb48613ef..79650f1bca0 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -584,13 +584,8 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/nuke/New(text, datum/team/team_to_join, datum/mind/_owner) . = ..() - var/code - for(var/obj/machinery/nuclearbomb/bombue in SSmachines.get_by_type(/obj/machinery/nuclearbomb)) - if(length(bombue.r_code) <= 5 && bombue.r_code != "LOLNO" && bombue.r_code != "ADMIN") - code = bombue.r_code - break - if(code) - explanation_text += " We have intercepted the nuclear codes for the warhead. The code is [code]. Good luck." + // We have to do it with a callback because mind/Topic creates the objective without an owner + addtimer(CALLBACK(src, PROC_REF(give_kit), /obj/item/nad_scanner), 5 SECONDS, TIMER_DELETE_ME) /datum/objective/nuke/check_completion() if(SSticker.mode.station_was_nuked) diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index ca9e98b7015..5e0e58f477e 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ