mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
If you look at your PDA window, there should be an option to stick an ID in, like with some computers.
While carrying an ID, a PDA can be used for almost everything an ID can.
While ID scanners can read cards through a PDA, it is difficult to shove a PDA into the ID slot on some computers.
It is possible I missed some functions, but I was quite thorough in my sweep through the code.
In the event of PDA destruction, any inserted ID is ejected unharmed.
It is now possible to stick PDAs in your jumpsuit's ID slot.
Since PDAs are named, you can disguise yourself as someone else using one.
Beepsky/ED-209 can see through a PDA disguise if you stick your real ID in for access.
git-svn-id: http://tgstation13.googlecode.com/svn/trunk@592 316c924e-a436-60f5-8080-3fe189b3f50e
731 lines
23 KiB
Plaintext
731 lines
23 KiB
Plaintext
//Cloning revival method.
|
|
//The pod handles the actual cloning while the computer manages the clone profiles
|
|
|
|
//Potential replacement for genetics revives or something I dunno (?)
|
|
|
|
/obj/machinery/clonepod
|
|
anchored = 1
|
|
name = "cloning pod"
|
|
desc = "An electronically-lockable pod for growing organic tissue."
|
|
density = 1
|
|
icon = 'cloning.dmi'
|
|
icon_state = "pod_0"
|
|
req_access = list(access_medlab) //For premature unlocking.
|
|
var/mob/living/occupant
|
|
var/heal_level = 90 //The clone is released once its health reaches this level.
|
|
var/locked = 0
|
|
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
|
|
var/mess = 0 //Need to clean out it if it's full of exploded clone.
|
|
var/attempting = 0 //One clone attempt at a time thanks
|
|
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
|
|
|
|
/obj/machinery/computer/cloning
|
|
name = "Cloning console"
|
|
icon = 'computer.dmi'
|
|
icon_state = "dna"
|
|
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 = "Initializing System..."
|
|
var/menu = 1 //Which menu screen to display
|
|
var/list/records = list()
|
|
var/datum/data/record/active_record = null
|
|
var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything.
|
|
|
|
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
|
|
//TO-DO: Make the genetics machine accept them.
|
|
/obj/item/weapon/disk/data
|
|
name = "Cloning Data Disk"
|
|
icon = 'cloning.dmi'
|
|
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
|
|
item_state = "card-id"
|
|
w_class = 1.0
|
|
var/data = ""
|
|
var/ue = 0
|
|
var/data_type = "ui" //ui|se
|
|
var/owner = "God Emperor of Mankind"
|
|
var/read_only = 0 //Well,it's still a floppy disk
|
|
|
|
/obj/item/weapon/disk/data/demo
|
|
name = "data disk - 'God Emperor of Mankind'"
|
|
data = "066000033000000000AF00330660FF4DB002690"
|
|
//data = "0C80C80C80C80C80C8000000000000161FBDDEF" - Farmer Jeff
|
|
ue = 1
|
|
read_only = 1
|
|
|
|
/obj/item/weapon/disk/data/monkey
|
|
name = "data disk - 'Mr. Muggles'"
|
|
data_type = "se"
|
|
data = "0983E840344C39F4B059D5145FC5785DC6406A4FFF"
|
|
read_only = 1
|
|
|
|
/obj/machinery/computer/cloning/New()
|
|
..()
|
|
spawn(5)
|
|
src.scanner = locate(/obj/machinery/dna_scannernew, get_step(src, WEST))
|
|
src.pod1 = locate(/obj/machinery/clonepod, get_step(src, EAST))
|
|
|
|
src.temp = ""
|
|
if (isnull(src.scanner))
|
|
src.temp += " <font color=red>SCNR-ERROR</font>"
|
|
if (isnull(src.pod1))
|
|
src.temp += " <font color=red>POD1-ERROR</font>"
|
|
else
|
|
src.pod1.connected = src
|
|
|
|
if (src.temp == "")
|
|
src.temp = "System ready."
|
|
return
|
|
return
|
|
|
|
/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob)
|
|
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
|
|
if (!src.diskette)
|
|
user.drop_item()
|
|
W.loc = src
|
|
src.diskette = W
|
|
user << "You insert [W]."
|
|
src.updateUsrDialog()
|
|
return
|
|
else if((istype(W, /obj/item/weapon/screwdriver)) && (src.stat & BROKEN))
|
|
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
|
|
if(do_after(user, 20))
|
|
user << "\blue The broken glass falls out."
|
|
var/obj/computerframe/A = new /obj/computerframe( src.loc )
|
|
new /obj/item/weapon/shard( src.loc )
|
|
var/obj/item/weapon/circuitboard/cloning/M = new /obj/item/weapon/circuitboard/cloning( A )
|
|
for (var/obj/C in src)
|
|
C.loc = src.loc
|
|
M.records = src.records
|
|
A.circuit = M
|
|
A.state = 3
|
|
A.icon_state = "3"
|
|
A.anchored = 1
|
|
del(src)
|
|
else
|
|
src.attack_hand(user)
|
|
return
|
|
|
|
/obj/machinery/computer/cloning/attack_paw(mob/user as mob)
|
|
return attack_hand(user)
|
|
|
|
/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.machine = src
|
|
add_fingerprint(user)
|
|
|
|
if(stat & (BROKEN|NOPOWER))
|
|
return
|
|
|
|
var/dat = "<h3>Cloning System Control</h3>"
|
|
dat += "<font size=-1><a href='byond://?src=\ref[src];refresh=1'>Refresh</a></font>"
|
|
|
|
dat += "<br><tt>[temp]</tt><br>"
|
|
|
|
switch(src.menu)
|
|
if(1)
|
|
dat += "<h4>Scanner Functions</h4>"
|
|
|
|
if (isnull(src.scanner))
|
|
dat += "No scanner connected!"
|
|
else
|
|
if (src.scanner.occupant)
|
|
dat += "<a href='byond://?src=\ref[src];scan=1'>Scan - [src.scanner.occupant]</a>"
|
|
else
|
|
dat += "Scanner unoccupied"
|
|
|
|
dat += "<br>Lock status: <a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Locked" : "Unlocked"]</a>"
|
|
|
|
dat += "<h4>Database Functions</h4>"
|
|
dat += "<a href='byond://?src=\ref[src];menu=2'>View Records</a><br>"
|
|
if (src.diskette)
|
|
dat += "<a href='byond://?src=\ref[src];disk=eject'>Eject Disk</a>"
|
|
|
|
|
|
if(2)
|
|
dat += "<h4>Current records</h4>"
|
|
dat += "<a href='byond://?src=\ref[src];menu=1'>Back</a><br><br>"
|
|
for(var/datum/data/record/R in src.records)
|
|
dat += "<a href='byond://?src=\ref[src];view_rec=\ref[R]'>[R.fields["id"]]-[R.fields["name"]]</a><br>"
|
|
|
|
if(3)
|
|
dat += "<h4>Selected Record</h4>"
|
|
dat += "<a href='byond://?src=\ref[src];menu=2'>Back</a><br>"
|
|
|
|
if (!src.active_record)
|
|
dat += "<font color=red>ERROR: Record not found.</font>"
|
|
else
|
|
dat += "<br><font size=1><a href='byond://?src=\ref[src];del_rec=1'>Delete Record</a></font><br>"
|
|
dat += "<b>Name:</b> [src.active_record.fields["name"]]<br>"
|
|
|
|
var/obj/item/weapon/implant/health/H = locate(src.active_record.fields["imp"])
|
|
|
|
if ((H) && (istype(H)))
|
|
dat += "<b>Health:</b> [H.sensehealth()] | OXY-BURN-TOX-BRUTE<br>"
|
|
else
|
|
dat += "<font color=red>Unable to locate implant.</font><br>"
|
|
|
|
if (!isnull(src.diskette))
|
|
dat += "<a href='byond://?src=\ref[src];disk=load'>Load from disk.</a>"
|
|
|
|
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=ue'>UI + UE</a>"
|
|
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=ui'>UI</a>"
|
|
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=se'>SE</a>"
|
|
dat += "<br>"
|
|
else
|
|
dat += "<br>" //Keeping a line empty for appearances I guess.
|
|
|
|
dat += {"<b>UI:</b> [src.active_record.fields["UI"]]<br>
|
|
<b>SE:</b> [src.active_record.fields["SE"]]<br><br>
|
|
<a href='byond://?src=\ref[src];clone=\ref[src.active_record]'>Clone</a><br>"}
|
|
|
|
if(4)
|
|
if (!src.active_record)
|
|
src.menu = 2
|
|
dat = "[src.temp]<br>"
|
|
dat += "<h4>Confirm Record Deletion</h4>"
|
|
|
|
dat += "<b><a href='byond://?src=\ref[src];del_rec=1'>Scan card to confirm.</a></b><br>"
|
|
dat += "<b><a href='byond://?src=\ref[src];menu=3'>No</a></b>"
|
|
|
|
|
|
user << browse(dat, "window=cloning")
|
|
onclose(user, "cloning")
|
|
return
|
|
|
|
/obj/machinery/computer/cloning/Topic(href, href_list)
|
|
if(..())
|
|
return
|
|
|
|
if ((href_list["scan"]) && (!isnull(src.scanner)))
|
|
src.scan_mob(src.scanner.occupant)
|
|
|
|
//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 ((isnull(src.active_record.fields["ckey"])) || (src.active_record.fields["ckey"] == ""))
|
|
del(src.active_record)
|
|
src.temp = "ERROR: Record Corrupt"
|
|
else
|
|
src.menu = 3
|
|
|
|
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 = "Delete record?"
|
|
src.menu = 4
|
|
|
|
else if (src.menu == 4)
|
|
var/obj/item/weapon/card/id/C = usr.equipped()
|
|
if (istype(C)||istype(C, /obj/item/device/pda))
|
|
if(src.check_access(C))
|
|
src.records.Remove(src.active_record)
|
|
del(src.active_record)
|
|
src.temp = "Record deleted."
|
|
src.menu = 2
|
|
else
|
|
src.temp = "Access Denied."
|
|
|
|
else if (href_list["disk"]) //Load or eject.
|
|
switch(href_list["disk"])
|
|
if("load")
|
|
if ((isnull(src.diskette)) || (src.diskette.data == ""))
|
|
src.temp = "Load error."
|
|
src.updateUsrDialog()
|
|
return
|
|
if (isnull(src.active_record))
|
|
src.temp = "Record error."
|
|
src.menu = 1
|
|
src.updateUsrDialog()
|
|
return
|
|
|
|
if (src.diskette.data_type == "ui")
|
|
src.active_record.fields["UI"] = src.diskette.data
|
|
if (src.diskette.ue)
|
|
src.active_record.fields["name"] = src.diskette.owner
|
|
else if (src.diskette.data_type == "se")
|
|
src.active_record.fields["SE"] = src.diskette.data
|
|
|
|
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 = "Save error."
|
|
src.updateUsrDialog()
|
|
return
|
|
|
|
switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se
|
|
if("ui")
|
|
src.diskette.data = src.active_record.fields["UI"]
|
|
src.diskette.ue = 0
|
|
src.diskette.data_type = "ui"
|
|
if("ue")
|
|
src.diskette.data = src.active_record.fields["UI"]
|
|
src.diskette.ue = 1
|
|
src.diskette.data_type = "ui"
|
|
if("se")
|
|
src.diskette.data = src.active_record.fields["SE"]
|
|
src.diskette.ue = 0
|
|
src.diskette.data_type = "se"
|
|
src.diskette.owner = src.active_record.fields["name"]
|
|
src.diskette.name = "data disk - '[src.diskette.owner]'"
|
|
src.temp = "Save \[[href_list["save_disk"]]\] successful."
|
|
|
|
else if (href_list["refresh"])
|
|
src.updateUsrDialog()
|
|
|
|
else if (href_list["clone"])
|
|
var/datum/data/record/C = locate(href_list["clone"])
|
|
//Look for that player! They better be dead!
|
|
var/mob/selected = find_dead_player("[C.fields["ckey"]]")
|
|
|
|
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
|
|
if ((!selected) || (!src.pod1) || (src.pod1.occupant) || (src.pod1.mess))
|
|
src.temp = "Unable to initiate cloning cycle." // most helpful error message in THE HISTORY OF THE WORLD
|
|
else if (src.pod1.growclone(selected, C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"]))
|
|
src.temp = "Cloning cycle activated."
|
|
src.records.Remove(C)
|
|
del(C)
|
|
src.menu = 1
|
|
|
|
else if (href_list["menu"])
|
|
src.menu = text2num(href_list["menu"])
|
|
|
|
src.add_fingerprint(usr)
|
|
src.updateUsrDialog()
|
|
return
|
|
|
|
/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob)
|
|
if ((isnull(subject)) || (!istype(subject, /mob/living/carbon/human)) || (!subject.dna))
|
|
src.temp = "Error: Unable to locate valid genetic data."
|
|
return
|
|
if ((!subject.ckey) || (!subject.client))
|
|
src.temp = "Error: Mental interface failure."
|
|
return
|
|
if (!isnull(find_record(subject.ckey)))
|
|
src.temp = "Subject already in database."
|
|
return
|
|
|
|
subject.dna.check_integrity()
|
|
|
|
var/datum/data/record/R = new /datum/data/record( )
|
|
R.fields["ckey"] = subject.ckey
|
|
R.fields["name"] = subject.real_name
|
|
R.fields["id"] = copytext(md5(subject.real_name), 2, 6)
|
|
R.fields["UI"] = subject.dna.uni_identity
|
|
R.fields["SE"] = subject.dna.struc_enzymes
|
|
|
|
//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]"
|
|
|
|
src.records += R
|
|
src.temp = "Subject successfully scanned."
|
|
|
|
//Find a specific record by key.
|
|
/obj/machinery/computer/cloning/proc/find_record(var/find_key)
|
|
var/selected_record = null
|
|
for(var/datum/data/record/R in src.records)
|
|
if (R.fields["ckey"] == find_key)
|
|
selected_record = R
|
|
break
|
|
return selected_record
|
|
|
|
/obj/machinery/computer/cloning/power_change()
|
|
|
|
if(stat & BROKEN)
|
|
icon_state = "commb"
|
|
else
|
|
if( powered() )
|
|
icon_state = initial(icon_state)
|
|
stat &= ~NOPOWER
|
|
else
|
|
spawn(rand(0, 15))
|
|
src.icon_state = "c_unpowered"
|
|
stat |= NOPOWER
|
|
|
|
|
|
//Find a dead mob with a brain and client.
|
|
/proc/find_dead_player(var/find_key)
|
|
if (isnull(find_key))
|
|
return
|
|
|
|
var/mob/selected = null
|
|
for(var/mob/M in world)
|
|
//Dead people only thanks!
|
|
if ((M.stat != 2) || (!M.client))
|
|
continue
|
|
//They need a brain!
|
|
if ((istype(M, /mob/living/carbon/human)) && (M:brain_op_stage >= 4.0))
|
|
continue
|
|
|
|
if (M.ckey == find_key)
|
|
selected = M
|
|
break
|
|
return selected
|
|
|
|
//Disk stuff.
|
|
/obj/item/weapon/disk/data/New()
|
|
..()
|
|
var/diskcolor = pick(0,1,2)
|
|
src.icon_state = "datadisk[diskcolor]"
|
|
|
|
/obj/item/weapon/disk/data/attack_self(mob/user as mob)
|
|
src.read_only = !src.read_only
|
|
user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]."
|
|
|
|
/obj/item/weapon/disk/data/examine()
|
|
set src in oview(5)
|
|
..()
|
|
usr << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].")
|
|
return
|
|
|
|
//Health Tracker Implant
|
|
|
|
/obj/item/weapon/implant/health
|
|
name = "health implant"
|
|
var/healthstring = ""
|
|
|
|
/obj/item/weapon/implant/health/proc/sensehealth()
|
|
if (!src.implanted)
|
|
return "ERROR"
|
|
else
|
|
src.healthstring = "[round(src.implanted:oxyloss)] - [round(src.implanted:fireloss)] - [round(src.implanted:toxloss)] - [round(src.implanted:bruteloss)]"
|
|
if (!src.healthstring)
|
|
src.healthstring = "ERROR"
|
|
return src.healthstring
|
|
|
|
/obj/machinery/clonepod/attack_ai(mob/user as mob)
|
|
return attack_hand(user)
|
|
/obj/machinery/clonepod/attack_paw(mob/user as mob)
|
|
return attack_hand(user)
|
|
/obj/machinery/clonepod/attack_hand(mob/user as mob)
|
|
if ((isnull(src.occupant)) || (stat & NOPOWER))
|
|
return
|
|
if ((!isnull(src.occupant)) && (src.occupant.stat != 2))
|
|
var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100)))
|
|
user << "Current clone cycle is [round(completion)]% complete."
|
|
return
|
|
|
|
//Clonepod
|
|
|
|
//Start growing a human clone in the pod!
|
|
/obj/machinery/clonepod/proc/growclone(mob/ghost as mob, var/clonename, var/ui, var/se, var/mindref)
|
|
if (((!ghost) || (!ghost.client)) || src.mess || src.attempting)
|
|
return 0
|
|
|
|
src.attempting = 1 //One at a time!!
|
|
src.locked = 1
|
|
|
|
src.eject_wait = 1
|
|
spawn(30)
|
|
src.eject_wait = 0
|
|
|
|
src.occupant = new /mob/living/carbon/human(src)
|
|
ghost.client.mob = src.occupant
|
|
|
|
src.icon_state = "pod_1"
|
|
//Get the clone body ready
|
|
src.occupant.rejuv = 10
|
|
src.occupant.bruteloss += 90
|
|
src.occupant.toxloss += 50
|
|
src.occupant.oxyloss += 40
|
|
src.occupant.brainloss += 90
|
|
src.occupant.paralysis += 4
|
|
|
|
//Here let's calculate their health so the pod doesn't immediately eject them!!!
|
|
src.occupant.health = (src.occupant.bruteloss + src.occupant.toxloss + src.occupant.oxyloss)
|
|
|
|
src.occupant << "\blue <b>Clone generation process initiated.</b>"
|
|
src.occupant << "\blue This will take a moment, please hold."
|
|
|
|
if (clonename)
|
|
src.occupant.real_name = clonename
|
|
else
|
|
src.occupant.real_name = "clone" //No null names!!
|
|
|
|
var/datum/mind/clonemind = (locate(mindref) in ticker.minds)
|
|
|
|
if ((clonemind) && (istype(clonemind))) //Move that mind over!!
|
|
clonemind.transfer_to(src.occupant)
|
|
else //welp
|
|
src.occupant.mind = new /datum/mind( )
|
|
src.occupant.mind.key = src.occupant.key
|
|
src.occupant.mind.current = src.occupant
|
|
src.occupant.mind.transfer_to(src.occupant)
|
|
ticker.minds += src.occupant.mind
|
|
|
|
// -- Mode/mind specific stuff goes here
|
|
switch(ticker.mode.name)
|
|
if ("revolution")
|
|
if ((src.occupant.mind in ticker.mode:revolutionaries) || (src.occupant.mind in ticker.mode:head_revolutionaries))
|
|
ticker.mode:add_revolutionary(src.occupant.mind)
|
|
ticker.mode:update_all_rev_icons() //So the icon actually appears
|
|
if ("cult")
|
|
if (src.occupant.mind in ticker.mode:cult)
|
|
ticker.mode:add_cultist(src.occupant.mind)
|
|
ticker.mode:update_all_cult_icons() //So the icon actually appears
|
|
if ("changeling")
|
|
if (src.occupant.mind in ticker.mode:changelings)
|
|
src.occupant.make_changeling()
|
|
|
|
// -- End mode specific stuff
|
|
|
|
if (istype(ghost, /mob/dead/observer))
|
|
del(ghost) //Don't leave ghosts everywhere!!
|
|
|
|
if (!src.occupant.dna)
|
|
src.occupant.dna = new /datum/dna( )
|
|
if (ui)
|
|
src.occupant.dna.uni_identity = ui
|
|
updateappearance(src.occupant, ui)
|
|
if (se)
|
|
src.occupant.dna.struc_enzymes = se
|
|
randmutb(src.occupant) //Sometimes the clones come out wrong.
|
|
|
|
src.attempting = 0
|
|
return 1
|
|
|
|
//Grow clones to maturity then kick them out. FREELOADERS
|
|
/obj/machinery/clonepod/process()
|
|
|
|
if (stat & NOPOWER) //Autoeject if power is lost
|
|
if (src.occupant)
|
|
src.locked = 0
|
|
src.go_out()
|
|
return
|
|
|
|
if ((src.occupant) && (src.occupant.loc == src))
|
|
if((src.occupant.stat == 2) || (src.occupant.suiciding)) //Autoeject corpses and suiciding dudes.
|
|
src.locked = 0
|
|
src.go_out()
|
|
src.connected_message("Clone Rejected: Deceased.")
|
|
return
|
|
|
|
else if(src.occupant.health < src.heal_level)
|
|
src.occupant.paralysis = 4
|
|
|
|
//Slowly get that clone healed and finished.
|
|
src.occupant.bruteloss = max(src.occupant.bruteloss-1, 0)
|
|
|
|
//At this rate one clone takes about 95 seconds to produce.(with heal_level 90)
|
|
src.occupant.toxloss = max(src.occupant.toxloss-0.5, 0)
|
|
|
|
//Premature clones may have brain damage.
|
|
src.occupant.brainloss = max(src.occupant.brainloss-1, 0)
|
|
|
|
//So clones don't die of oxyloss in a running pod.
|
|
if (src.occupant.reagents.get_reagent_amount("inaprovaline") < 30)
|
|
src.occupant.reagents.add_reagent("inaprovaline", 60)
|
|
|
|
//Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!!
|
|
src.occupant.oxyloss = max(src.occupant.oxyloss-2, 0)
|
|
|
|
//Stop baking in the tubes you jerks.
|
|
src.occupant.fireloss = max(src.occupant.fireloss-2, 0)
|
|
|
|
use_power(7500) //This might need tweaking.
|
|
return
|
|
|
|
else if((src.occupant.health >= src.heal_level) && (!src.eject_wait))
|
|
src.connected_message("Cloning Process Complete.")
|
|
src.locked = 0
|
|
src.go_out()
|
|
return
|
|
|
|
else if ((!src.occupant) || (src.occupant.loc != src))
|
|
src.occupant = null
|
|
if (src.locked)
|
|
src.locked = 0
|
|
if (!src.mess)
|
|
icon_state = "pod_0"
|
|
use_power(200)
|
|
return
|
|
|
|
return
|
|
|
|
//Let's unlock this early I guess. Might be too early, needs tweaking.
|
|
/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
|
if (!src.check_access(W))
|
|
user << "\red Access Denied."
|
|
return
|
|
if ((!src.locked) || (isnull(src.occupant)))
|
|
return
|
|
if ((src.occupant.health < -20) && (src.occupant.stat != 2))
|
|
user << "\red Access Refused."
|
|
return
|
|
else
|
|
src.locked = 0
|
|
user << "System unlocked."
|
|
else if (istype(W, /obj/item/weapon/card/emag))
|
|
if (isnull(src.occupant))
|
|
return
|
|
user << "You force an emergency ejection."
|
|
src.locked = 0
|
|
src.go_out()
|
|
return
|
|
else
|
|
..()
|
|
|
|
//Put messages in the connected computer's temp var for display.
|
|
/obj/machinery/clonepod/proc/connected_message(var/message)
|
|
if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning)))
|
|
return 0
|
|
if (!message)
|
|
return 0
|
|
|
|
src.connected.temp = message
|
|
src.connected.updateUsrDialog()
|
|
return 1
|
|
|
|
/obj/machinery/clonepod/verb/eject()
|
|
set src in oview(1)
|
|
|
|
if (usr.stat != 0)
|
|
return
|
|
src.go_out()
|
|
add_fingerprint(usr)
|
|
return
|
|
|
|
/obj/machinery/clonepod/proc/go_out()
|
|
if (src.locked)
|
|
return
|
|
|
|
if (src.mess) //Clean that mess and dump those gibs!
|
|
src.mess = 0
|
|
gibs(src.loc)
|
|
src.icon_state = "pod_0"
|
|
for(var/obj/O in src)
|
|
O.loc = src.loc
|
|
return
|
|
|
|
if (!(src.occupant))
|
|
return
|
|
for(var/obj/O in src)
|
|
O.loc = src.loc
|
|
|
|
if (src.occupant.client)
|
|
src.occupant.client.eye = src.occupant.client.mob
|
|
src.occupant.client.perspective = MOB_PERSPECTIVE
|
|
src.occupant.loc = src.loc
|
|
src.icon_state = "pod_0"
|
|
src.eject_wait = 0 //If it's still set somehow.
|
|
domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing.
|
|
src.occupant = null
|
|
return
|
|
|
|
/obj/machinery/clonepod/proc/malfunction()
|
|
if (src.occupant)
|
|
src.connected_message("Critical Error!")
|
|
src.mess = 1
|
|
src.icon_state = "pod_g"
|
|
src.occupant.ghostize()
|
|
spawn(5)
|
|
del(src.occupant)
|
|
return
|
|
|
|
/obj/machinery/clonepod/relaymove(mob/user as mob)
|
|
if (user.stat)
|
|
return
|
|
src.go_out()
|
|
return
|
|
|
|
/obj/machinery/clonepod/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
A.loc = src.loc
|
|
ex_act(severity)
|
|
del(src)
|
|
return
|
|
if(2.0)
|
|
if (prob(50))
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
A.loc = src.loc
|
|
ex_act(severity)
|
|
del(src)
|
|
return
|
|
if(3.0)
|
|
if (prob(25))
|
|
for(var/atom/movable/A as mob|obj in src)
|
|
A.loc = src.loc
|
|
ex_act(severity)
|
|
del(src)
|
|
return
|
|
else
|
|
return
|
|
|
|
/*
|
|
* Diskette Box
|
|
*/
|
|
/obj/item/weapon/storage/diskbox
|
|
name = "Diskette Box"
|
|
icon_state = "disk_kit"
|
|
item_state = "syringe_kit"
|
|
|
|
/obj/item/weapon/storage/diskbox/New()
|
|
..()
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
new /obj/item/weapon/disk/data(src)
|
|
|
|
/*
|
|
* Manual -- A big ol' manual.
|
|
*/
|
|
|
|
/obj/item/weapon/paper/Cloning
|
|
name = "paper - 'H-87 Cloning Apparatus Manual"
|
|
info = {"<h4>Getting Started</h4>
|
|
Congratulations, your station has purchased the H-87 industrial cloning device!<br>
|
|
Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!<br>
|
|
<b>That's all there is to it!</b><br>
|
|
<i>Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.</i><br>
|
|
<p>Clone profiles may be viewed through the profiles menu. Scanning implants a complementary HEALTH MONITOR IMPLANT into the subject, which may be viewed from each profile.
|
|
Profile Deletion has been restricted to \[Station Head\] level access.</p>
|
|
<h4>Cloning from a profile</h4>
|
|
Cloning is as simple as pressing the CLONE option at the bottom of the desired profile.<br>
|
|
Per your company's EMPLOYEE PRIVACY RIGHTS agreement, the H-87 has been blocked from cloning crewmembers while they are still alive.<br>
|
|
<br>
|
|
<p>The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times (With SPEEDCLONE technology) are roughly 90 seconds.
|
|
The cloning pod may be unlocked early with any \[Medical Researcher\] ID after initial maturation is complete.</p><br>
|
|
<i>Please note that resulting clones may have a small DEVELOPMENTAL DEFECT as a result of genetic drift.</i><br>
|
|
<h4>Profile Management</h4>
|
|
<p>The H-87 (as well as your station's standard genetics machine) can accept STANDARD DATA DISKETTES.
|
|
These diskettes are used to transfer genetic information between machines and profiles.
|
|
A load/save dialog will become available in each profile if a disk is inserted.</p><br>
|
|
<i>A good diskette is a great way to counter aforementioned genetic drift!</i><br>
|
|
<br>
|
|
<font size=1>This technology produced under license from Thinktronic Systems, LTD.</font>"}
|
|
|
|
//SOME SCRAPS I GUESS
|
|
/* EMP grenade/spell effect
|
|
if(istype(A, /obj/machinery/clonepod))
|
|
A:malfunction()
|
|
*/ |