/obj/machinery/computer/cloning name = "cloning console" icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" circuit = /obj/item/weapon/circuitboard/cloning req_access = list(access_heads) //Only used for record deletion right now. var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. var/list/pods = list() //Linked cloning pods. var/temp = "" var/scantemp = "Scanner ready." var/menu = 1 //Which menu screen to display var/list/records = list() var/datum/dna2/record/active_record = null var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text var/autoprocess = 0 var/obj/machinery/clonepod/selected_pod // 0: Standard body scan // 1: The "Best" scan available var/scan_mode = 1 light_color = LIGHT_COLOR_DARKBLUE /obj/machinery/computer/cloning/initialize() ..() updatemodules() /obj/machinery/computer/cloning/Destroy() releasecloner() return ..() /obj/machinery/computer/cloning/process() if(!scanner || !pods.len || !autoprocess || stat & NOPOWER) return if(scanner.occupant && can_autoprocess()) scan_mob(scanner.occupant) for(var/obj/machinery/clonepod/pod in pods) if(!(pod.occupant || pod.mess) && (pod.efficiency > 5)) for(var/datum/dna2/record/R in src.records) if(!(pod.occupant || pod.mess)) if(pod.growclone(R)) records.Remove(R) /obj/machinery/computer/cloning/proc/updatemodules() src.scanner = findscanner() releasecloner() findcloner() if(!selected_pod && pods.len) selected_pod = pods[1] /obj/machinery/computer/cloning/proc/findscanner() var/obj/machinery/dna_scannernew/scannerf = null //Try to find scanner on adjacent tiles first for(dir in list(NORTH,EAST,SOUTH,WEST)) scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) if(scannerf) return scannerf //Then look for a free one in the area if(!scannerf) for(var/obj/machinery/dna_scannernew/S in get_area(src)) return S return 0 /obj/machinery/computer/cloning/proc/releasecloner() for(var/obj/machinery/clonepod/P in pods) P.connected = null P.name = initial(P.name) pods.Cut() /obj/machinery/computer/cloning/proc/findcloner() var/num = 1 for(var/obj/machinery/clonepod/P in get_area(src)) if(!P.connected) pods += P P.connected = src P.name = "[initial(P.name)] #[num++]" /obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES if(!src.diskette) user.drop_item() W.loc = src src.diskette = W to_chat(user, "You insert [W].") nanomanager.update_uis(src) return else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/M = W if(M.buffer && istype(M.buffer, /obj/machinery/clonepod)) var/obj/machinery/clonepod/P = M.buffer if(P && !(P in pods)) pods += P P.connected = src P.name = "[initial(P.name)] #[pods.len]" to_chat(user, "You connect [P] to [src].") else ..() return /obj/machinery/computer/cloning/attack_ai(mob/user as mob) return attack_hand(user) /obj/machinery/computer/cloning/attack_hand(mob/user as mob) user.set_machine(src) add_fingerprint(user) if(stat & (BROKEN|NOPOWER)) return updatemodules() ui_interact(user) /obj/machinery/computer/cloning/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(stat & (NOPOWER|BROKEN)) return var/data[0] data["menu"] = src.menu data["scanner"] = sanitize("[src.scanner]") var/canpodautoprocess = 0 if(pods.len) data["numberofpods"] = src.pods.len var/list/tempods[0] for(var/obj/machinery/clonepod/pod in pods) if(pod.efficiency > 5) canpodautoprocess = 1 tempods.Add(list(list("pod" = "\ref[pod]", "name" = sanitize(capitalize(pod.name)), "biomass" = pod.biomass))) data["pods"] = tempods data["loading"] = loading data["autoprocess"] = autoprocess data["can_brainscan"] = can_brainscan() // You'll need tier 4s for this data["scan_mode"] = scan_mode if(scanner && pods.len && ((scanner.scan_level > 2) || canpodautoprocess)) data["autoallowed"] = 1 else data["autoallowed"] = 0 if(src.scanner) data["occupant"] = src.scanner.occupant data["locked"] = src.scanner.locked data["temp"] = temp data["scantemp"] = scantemp data["disk"] = src.diskette data["selected_pod"] = "\ref[selected_pod]" var/list/temprecords[0] for(var/datum/dna2/record/R in records) var tempRealName = R.dna.real_name temprecords.Add(list(list("record" = "\ref[R]", "realname" = sanitize(tempRealName)))) data["records"] = temprecords if(src.menu == 3) if(src.active_record) data["activerecord"] = "\ref[src.active_record]" var/obj/item/weapon/implant/health/H = null if(src.active_record.implant) H = locate(src.active_record.implant) if((H) && (istype(H))) data["health"] = H.sensehealth() data["realname"] = sanitize(src.active_record.dna.real_name) data["unidentity"] = src.active_record.dna.uni_identity data["strucenzymes"] = src.active_record.dna.struc_enzymes if(selected_pod && (selected_pod in pods) && selected_pod.biomass >= CLONE_BIOMASS) data["podready"] = 1 else data["podready"] = 0 // Set up the Nano UI ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) ui = new(user, src, ui_key, "cloning_console.tmpl", "Cloning Console UI", 640, 520) ui.set_initial_data(data) ui.open() /obj/machinery/computer/cloning/Topic(href, href_list) if(..()) return 1 if(loading) return if(href_list["scan"] && scanner && scanner.occupant) scantemp = "Scanner ready." loading = 1 spawn(20) if(can_brainscan() && scan_mode) scan_mob(scanner.occupant, scan_brain = 1) else scan_mob(scanner.occupant) loading = 0 nanomanager.update_uis(src) if(href_list["task"]) switch(href_list["task"]) if("autoprocess") autoprocess = 1 nanomanager.update_uis(src) if("stopautoprocess") autoprocess = 0 nanomanager.update_uis(src) //No locking an open scanner. else if((href_list["lock"]) && (!isnull(src.scanner))) if((!src.scanner.locked) && (src.scanner.occupant)) src.scanner.locked = 1 else src.scanner.locked = 0 else if(href_list["view_rec"]) src.active_record = locate(href_list["view_rec"]) if(istype(src.active_record,/datum/dna2/record)) if((isnull(src.active_record.ckey))) qdel(src.active_record) src.temp = "Error: Record corrupt." else src.menu = 3 else src.active_record = null src.temp = "Error: Record missing." else if(href_list["del_rec"]) if((!src.active_record) || (src.menu < 3)) return if(src.menu == 3) //If we are viewing a record, confirm deletion src.temp = "Please confirm that you want to delete the record?" src.menu = 4 else if(src.menu == 4) var/obj/item/weapon/card/id/C = usr.get_active_hand() if(istype(C)||istype(C, /obj/item/device/pda)) if(src.check_access(C)) src.records.Remove(src.active_record) qdel(src.active_record) src.temp = "Record deleted." src.menu = 2 else src.temp = "Error: Access denied." else if(href_list["disk"]) //Load or eject. switch(href_list["disk"]) if("load") if((isnull(src.diskette)) || isnull(src.diskette.buf)) src.temp = "Error: The disk's data could not be read." nanomanager.update_uis(src) return if(isnull(src.active_record)) src.temp = "Error: No active record was found." src.menu = 1 nanomanager.update_uis(src) return src.active_record = src.diskette.buf.copy() src.temp = "Load successful." if("eject") if(!isnull(src.diskette)) src.diskette.loc = src.loc src.diskette = null else if(href_list["save_disk"]) //Save to disk! if((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record))) src.temp = "Error: The data could not be saved." nanomanager.update_uis(src) return // DNA2 makes things a little simpler. src.diskette.buf=src.active_record.copy() src.diskette.buf.types=0 switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se if("ui") src.diskette.buf.types=DNA2_BUF_UI if("ue") src.diskette.buf.types=DNA2_BUF_UI|DNA2_BUF_UE if("se") src.diskette.buf.types=DNA2_BUF_SE src.diskette.name = "data disk - '[src.active_record.dna.real_name]'" src.temp = "Save \[[href_list["save_disk"]]\] successful." else if(href_list["refresh"]) nanomanager.update_uis(src) else if(href_list["selectpod"]) var/obj/machinery/clonepod/selected = locate(href_list["selectpod"]) if(istype(selected) && (selected in pods)) selected_pod = selected else if(href_list["clone"]) var/datum/dna2/record/C = locate(href_list["clone"]) //Look for that player! They better be dead! if(istype(C)) //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. if(!pods.len) temp = "Error: No cloning pod detected." else var/obj/machinery/clonepod/pod = selected_pod if(!selected_pod) temp = "Error: No cloning pod selected." else if(pod.occupant) temp = "Error: The cloning pod is currently occupied." else if(pod.biomass < CLONE_BIOMASS) temp = "Error: Not enough biomass." else if(pod.mess) temp = "Error: The cloning pod is malfunctioning." else if(!config.revival_cloning) temp = "Error: Unable to initiate cloning cycle." else if(pod.growclone(C)) temp = "Initiating cloning cycle..." records.Remove(C) qdel(C) menu = 1 else var/mob/selected = find_dead_player("[C.ckey]") if(!selected) return selected << 'sound/machines/chime.ogg' //probably not the best sound but I think it's reasonable var/answer = alert(selected,"Do you want to return to life?","Cloning","Yes","No") if(answer != "No" && pod.growclone(C)) temp = "Initiating cloning cycle..." records.Remove(C) qdel(C) menu = 1 else temp = "Initiating cloning cycle...
Error: Post-initialisation failed. Cloning cycle aborted." else temp = "Error: Data corruption." else if(href_list["menu"]) src.menu = text2num(href_list["menu"]) temp = "" scantemp = "Scanner ready." else if(href_list["toggle_mode"]) if(can_brainscan()) scan_mode = !scan_mode else scan_mode = 0 src.add_fingerprint(usr) nanomanager.update_uis(src) return /obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob, var/scan_brain = 0) if(stat & NOPOWER) return if(scanner.stat & (NOPOWER|BROKEN)) return if(scan_brain && !can_brainscan()) return if((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna) || (subject.species.flags & NO_SCAN)) scantemp = "Error: Unable to locate valid genetic data." nanomanager.update_uis(src) return if(subject.get_int_organ(/obj/item/organ/internal/brain)) var/obj/item/organ/internal/brain/Brn = subject.get_int_organ(/obj/item/organ/internal/brain) if(istype(Brn)) var/datum/species/S = all_species[Brn.dna.species] // stepladder code wooooo if(S.flags & NO_SCAN) scantemp = "Error: Subject's brain is incompatible." nanomanager.update_uis(src) return if(!subject.get_int_organ(/obj/item/organ/internal/brain)) scantemp = "Error: No signs of intelligence detected." nanomanager.update_uis(src) return if(subject.suiciding == 1 && src.scanner.scan_level < 2) scantemp = "Error: Subject's brain is not responding to scanning stimuli." nanomanager.update_uis(src) return if((!subject.ckey) || (!subject.client)) scantemp = "Error: Mental interface failure." nanomanager.update_uis(src) return if((NOCLONE in subject.mutations) && src.scanner.scan_level < 2) scantemp = "Error: Mental interface failure." nanomanager.update_uis(src) return if(scan_brain && !subject.get_int_organ(/obj/item/organ/internal/brain)) scantemp = "Error: No brain found." nanomanager.update_uis(src) return if(!isnull(find_record(subject.ckey))) scantemp = "Subject already in database." nanomanager.update_uis(src) return subject.dna.check_integrity() var/datum/dna2/record/R = new /datum/dna2/record() R.ckey = subject.ckey var/extra_info = "" if(scan_brain) var/obj/item/organ/B = subject.get_int_organ(/obj/item/organ/internal/brain) B.dna.check_integrity() R.dna=B.dna.Clone() var/datum/species/S = all_species[R.dna.species] if(S.flags & NO_SCAN) extra_info = "Proper genetic interface not found, defaulting to genetic data of the body." R.dna.species = subject.species.name R.id= copytext(md5(B.dna.real_name), 2, 6) R.name=B.dna.real_name else R.dna=subject.dna.Clone() R.id= copytext(md5(subject.real_name), 2, 6) R.name=R.dna.real_name R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE R.languages=subject.languages //Add an implant if needed var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) if(isnull(imp)) imp = new /obj/item/weapon/implant/health(subject) imp.implanted = subject R.implant = "\ref[imp]" //Update it if needed else R.implant = "\ref[imp]" if(!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning. R.mind = "\ref[subject.mind]" src.records += R scantemp = "Subject successfully scanned. " + extra_info nanomanager.update_uis(src) //Find a specific record by key. /obj/machinery/computer/cloning/proc/find_record(var/find_key) var/selected_record = null for(var/datum/dna2/record/R in src.records) if(R.ckey == find_key) selected_record = R break return selected_record /obj/machinery/computer/cloning/proc/can_autoprocess() return (scanner && scanner.scan_level > 2) /obj/machinery/computer/cloning/proc/can_brainscan() return (scanner && scanner.scan_level > 3)