/obj/machinery/computer3/cloning
default_prog = /datum/file/program/cloning
spawn_parts = list(/obj/item/part/computer/storage/hdd,/obj/item/part/computer/storage/removable,/obj/item/part/computer/networking/prox)
/datum/file/program/cloning
name = "cloning console"
desc = "Connects to cloning machinery through the local network."
active_state = "dna_old"
req_access = list(access_heads) //Only used for record deletion right now.
var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/obj/machinery/clonepod/pod1 = null //Linked cloning pod.
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record = null
var/loading = 0 // Nice loading text
var/has_disk = 0
proc/updatemodules()
if(!computer.net) return
if(scanner && pod1)
if(!computer.net.verify_machine(scanner))
scanner = null
if(!computer.net.verify_machine(pod1))
pod1 = null
if(!scanner || !pod1)
var/list/nearby = computer.net.get_machines()
scanner = locate(/obj/machinery/dna_scannernew) in nearby
pod1 = locate(/obj/machinery/clonepod) in nearby
if (pod1)
pod1.connected = src // Some variable the pod needs
proc/ScanningMenu()
if (isnull(scanner))
return "ERROR: No Scanner detected!
"
var/dat = "
Scanner Functions
"
dat += ""
if (!scanner.occupant)
dat += "Scanner Unoccupied"
else if(loading)
dat += "[scanner.occupant] => Scanning..."
else
if (scanner.occupant.ckey != scantemp_ckey)
scantemp = "Ready to Scan"
scantemp_ckey = scanner.occupant.ckey
dat += "[scanner.occupant] => [scantemp]"
dat += "
"
if (scanner.occupant)
dat += topic_link(src,"scan","Start Scan") + "
"
if(scanner.locked)
dat += topic_link(src,"lock","Unlock Scanner")
else
dat += topic_link(src,"lock","Lock Scanner")
else
dat += fake_link("Start Scan")
// Footer
dat += "Database Functions
"
if (records.len > 0)
dat += topic_link(src,"menu=2","View Records ([records.len])") + "
"
else
dat += fake_link("View Records (0)")
if (has_disk)
dat += topic_link(src,"eject_disk","Eject Disk") + "
"
return dat
proc/RecordsList()
var/dat = "Current records
"
dat += topic_link(src,"menu=1","<< Back") + "
"
for(var/datum/data/record/R in records)
dat += "[R.fields["name"]]
Scan ID [R.fields["id"]] " + topic_link(src,"view_rec=\ref[R]","View Record")
return dat
proc/ShowRecord()
var/dat = "Selected Record
"
dat += topic_link(src,"menu=2","<< Back") + "
"
if (!active_record)
dat += "Record not found."
else
dat += "[active_record.fields["name"]]
"
dat += "Scan ID [active_record.fields["id"]] [topic_link(src,"clone","Clone")]
"
var/obj/item/weapon/implant/health/H = locate(active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "Health Implant Data:
[H.sensehealth()]
"
else
dat += "Unable to locate Health Implant.
"
dat += "Unique Identifier:
[active_record.fields["UI"]]
"
dat += "Structural Enzymes:
[active_record.fields["SE"]]
"
if (has_disk)
dat += ""
dat += "
Inserted Disk
"
dat += "Contents: "
if (computer.floppy.inserted.files.len == 0)
dat += "Empty"
else
for(var/datum/file/data/genome/G in computer.floppy.inserted.files)
dat += topic_link(src,"loadfile=\ref[G]","[G.name]") + "
"
dat += "
Save to Disk:
"
dat += topic_link(src,"save_disk=ue","Unique Identifier + Unique Enzymes") + "
"
dat += topic_link(src,"save_disk=ui","Unique Identifier") + "
"
dat += topic_link(src,"save_disk=se","Structural Enzymes") + "
"
dat += ""
dat += "[topic_link(src,"del_rec","Delete Record")]"
return dat
proc/ConfirmDelete()
var/dat = "[temp]
"
dat += "Confirm Record Deletion
"
dat += "[topic_link(src,"del_rec","Scan card to confirm")]
"
dat += "[topic_link(src,"menu=3","Cancel")]"
return dat
interact()
if(!interactable())
return
updatemodules()
var/dat = ""
dat += topic_link(src,"refresh","Refresh")
dat += "Cloning Pod Status
"
dat += "[temp]
"
has_disk = (computer.floppy && computer.floppy.inserted)
if(!active_record && menu > 2)
menu = 2
switch(menu)
if(1)
dat += ScanningMenu()
if(2)
dat += RecordsList()
if(3)
dat += ShowRecord()
if(4)
dat = ConfirmDelete() // not (+=), this is how it used to be, just putting it in a function
if(!popup)
popup = new(usr, "\ref[computer]", "Cloning System Control")
popup.set_title_image(usr.browse_rsc_icon(overlay.icon, overlay.icon_state))
popup.set_content(dat)
popup.open()
return
Topic(var/href, var/list/href_list)
if(loading || !interactable())
return
if (href_list["menu"])
menu = text2num(href_list["menu"])
else if (("scan" in href_list) && !isnull(scanner))
scantemp = ""
loading = 1
computer.updateUsrDialog()
spawn(20)
scan_mob(scanner.occupant)
loading = 0
computer.updateUsrDialog()
//No locking an open scanner.
else if (("lock" in href_list) && !isnull(scanner))
if ((!scanner.locked) && (scanner.occupant))
scanner.locked = 1
else
scanner.locked = 0
else if ("view_rec" in href_list)
active_record = locate(href_list["view_rec"])
if(istype(active_record,/datum/data/record))
if ( !active_record.fields["ckey"] || active_record.fields["ckey"] == "" )
del(active_record)
temp = "Record Corrupt"
else
menu = 3
else
active_record = null
temp = "Record missing."
else if ("del_rec" in href_list)
if ((!active_record) || (menu < 3))
return
if (menu == 3) //If we are viewing a record, confirm deletion
temp = "Delete record?"
menu = 4
else if (menu == 4)
var/obj/item/weapon/card/id/C = usr.get_active_hand()
if (istype(C)||istype(C, /obj/item/device/pda))
if(check_access(C))
temp = "[active_record.fields["name"]] => Record deleted."
records.Remove(active_record)
del(active_record)
menu = 2
else
temp = "Access Denied."
else if ("eject_disk" in href_list)
if(computer.floppy)
computer.floppy.eject_disk()
else if("loadfile" in href_list)
var/datum/file/data/genome/G = locate(href_list["loadfile"]) in computer.floppy.files
if(!istype(G))
temp = "Load error."
computer.updateUsrDialog()
return
switch(G.type)
if(/datum/file/data/genome/UI)
active_record.fields["UI"] = G.content
if(/datum/file/data/genome/UE)
active_record.fields["name"] = G.real_name
if(/datum/file/data/genome/SE)
active_record.fields["SE"] = G.content
if(/datum/file/data/genome/cloning)
active_record = G:record
else if("savefile" in href_list)
if (!active_record || !computer || !computer.floppy)
temp = "Save error."
computer.updateUsrDialog()
return
var/rval = 0
switch(href_list["save_disk"])
if("ui")
var/datum/file/data/genome/UI/ui = new
ui.content = active_record.fields["UI"]
ui.real_name = active_record.fields["name"]
rval = computer.floppy.addfile(ui)
if("ue")
var/datum/file/data/genome/UI/UE/ui = new
ui.content = active_record.fields["UI"]
ui.real_name = active_record.fields["name"]
rval = computer.floppy.addfile(ui)
if("se")
var/datum/file/data/genome/SE/se = new
se.content = active_record.fields["SE"]
se.real_name = active_record.fields["name"]
rval = computer.floppy.addfile(se)
if("clone")
var/datum/file/data/genome/cloning/c = new
c.record = active_record
c.real_name = active_record.fields["name"]
rval = computer.floppy.addfile(c)
if(!rval)
temp = "Disk write error."
else if ("refresh" in href_list)
computer.updateUsrDialog()
else if ("clone" in href_list)
//Look for that player! They better be dead!
if(active_record)
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!pod1)
temp = "No Clonepod detected."
else if(pod1.occupant)
temp = "Clonepod is currently occupied."
else if(pod1.mess)
temp = "Clonepod malfunction."
else if(!config.revival_cloning)
temp = "Unable to initiate cloning cycle."
else if(pod1.growclone(active_record.fields["ckey"], active_record.fields["name"], active_record.fields["UI"], active_record.fields["SE"], active_record.fields["mind"], active_record.fields["mrace"]))
temp = "[active_record.fields["name"]] => Cloning cycle in progress..."
records.Remove(active_record)
del(active_record)
menu = 1
else
temp = "[active_record.fields["name"]] => Initialisation failure."
else
temp = "Data corruption."
computer.add_fingerprint(usr)
computer.updateUsrDialog()
return
proc/scan_mob(mob/living/carbon/human/subject as mob)
if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna))
scantemp = "Unable to locate valid genetic data."
return
if (!getbrain(subject))
scantemp = "No signs of intelligence detected."
return
if (subject.suiciding == 1)
scantemp = "Subject's brain is not responding to scanning stimuli."
return
if ((!subject.ckey) || (!subject.client))
scantemp = "Mental interface failure."
return
if (NOCLONE in subject.mutations)
scantemp = "Mental interface failure."
return
if (!isnull(find_record(subject.ckey)))
scantemp = "Subject already in database."
return
subject.dna.check_integrity()
var/datum/data/record/R = new /datum/data/record( )
if(subject.dna)
R.fields["mrace"] = subject.dna.mutantrace
R.fields["UI"] = subject.dna.uni_identity
R.fields["SE"] = subject.dna.struc_enzymes
else
R.fields["mrace"] = null
R.fields["UI"] = null
R.fields["SE"] = null
R.fields["ckey"] = subject.ckey
R.fields["name"] = subject.real_name
R.fields["id"] = copytext(md5(subject.real_name), 2, 6)
//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.fields["imp"] = "\ref[imp]"
//Update it if needed
else
R.fields["imp"] = "\ref[imp]"
if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "\ref[subject.mind]"
records += R
scantemp = "Subject successfully scanned."
//Find a specific record by key.
proc/find_record(var/find_key)
for(var/datum/data/record/R in records)
if (R.fields["ckey"] == find_key)
return R
return null