diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm
new file mode 100644
index 00000000000..a3ff47bb05f
--- /dev/null
+++ b/code/modules/mob/living/silicon/pai/death.dm
@@ -0,0 +1,29 @@
+/mob/living/silicon/pai/death(gibbed)
+ var/cancel
+ src.stat = 2
+ src.canmove = 0
+ if(src.blind)
+ src.blind.layer = 0
+ src.sight |= SEE_TURFS
+ src.sight |= SEE_MOBS
+ src.sight |= SEE_OBJS
+ src.see_in_dark = 8
+ src.see_invisible = 2
+
+ //var/tod = time2text(world.realtime,"hh:mm:ss") //weasellos time of death patch
+ //mind.store_memory("Time of death: [tod]", 0)
+
+ if(key)
+ spawn(50)
+ src.ghost()
+ for(var/mob/M in world)
+ if ((M.client && !( M.stat )))
+ cancel = 1
+ break
+ if (!( cancel ))
+ world << "Everyone is dead! Resetting in 30 seconds!"
+ spawn( 300 )
+ log_game("Rebooting because of no live players")
+ world.Reboot()
+ return
+ return ..(gibbed)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/pai/personality.dm b/code/modules/mob/living/silicon/pai/personality.dm
new file mode 100644
index 00000000000..78ed21c8f65
--- /dev/null
+++ b/code/modules/mob/living/silicon/pai/personality.dm
@@ -0,0 +1,58 @@
+/*
+ name
+ key
+ description
+ role
+ comments
+ ready = 0
+*/
+
+/datum/paiCandidate/proc/savefile_path(mob/user)
+ return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav"
+
+/datum/paiCandidate/proc/savefile_save(mob/user)
+ if (IsGuestKey(user.key))
+ return 0
+
+ var/savefile/F = new /savefile(src.savefile_path(user))
+
+
+ F["name"] << src.name
+ F["description"] << src.description
+ F["role"] << src.role
+ F["comments"] << src.comments
+
+ F["version"] << 1
+
+ return 1
+
+// loads the savefile corresponding to the mob's ckey
+// if silent=true, report incompatible savefiles
+// returns 1 if loaded (or file was incompatible)
+// returns 0 if savefile did not exist
+
+/datum/paiCandidate/proc/savefile_load(mob/user, var/silent = 1)
+ if (IsGuestKey(user.key))
+ return 0
+
+ var/path = savefile_path(user)
+
+ if (!fexists(path))
+ return 0
+
+ var/savefile/F = new /savefile(path)
+
+ var/version = null
+ F["version"] >> version
+
+ if (isnull(version) || version != 1)
+ fdel(path)
+ if (!silent)
+ alert(user, "Your savefile was incompatible with this version and was deleted.")
+ return 0
+
+ F["name"] >> src.name
+ F["description"] >> src.description
+ F["role"] >> src.role
+ F["comments"] >> src.comments
+ return 1
diff --git a/code/modules/mob/living/silicon/pai/software2.dm b/code/modules/mob/living/silicon/pai/software2.dm
new file mode 100644
index 00000000000..5e1d51db02e
--- /dev/null
+++ b/code/modules/mob/living/silicon/pai/software2.dm
@@ -0,0 +1,236 @@
+/mob/living/silicon/pai/var/list/available_software = list("crew manifest" = 5, "medical records" = 5, "security records" = 5, "camera" = 5, "atmosphere sensor" = 10, "heartbeat sensor" = 10, "security HUD" = 10, "medical HUD" = 10, "universal translator" = 10)
+
+/mob/living/silicon/pai/Topic(href, href_list)
+ ..()
+ if (href_list["switchcamera"])
+ switchCamera(locate(href_list["switchcamera"]))
+ if (href_list["radio"])
+ src.card.radio.attack_self(src)
+ if (href_list["software"])
+ var/s = href_list["software"]
+ world << s
+ switch(s)
+ if("crew manifest")
+ src.softwareManifest()
+ if("medical records")
+ //blah
+ if("security records")
+ //blah
+ if("camera")
+ // blah
+ if("atmosphere sensor")
+ // blah
+ if("heartbeat sensor")
+ // blah
+ if("security HUD")
+ // blah
+ if("medical HUD")
+ //blah
+ if("universal translator")
+ src.universal_speak = !src.universal_speak
+ else
+ //blahblah
+ if(href_list["softFunction"])
+ var/s = href_list["softFunction"]
+ if(s == "medical records")
+ var/medFunction = href_list["medFunction"]
+ if(medFunction == "view")
+ // Pretty much totally stolen from medical.dm in computers
+ var/datum/data/record/R = locate(href_list["med_rec"])
+ var/datum/data/record/M = locate(href_list["med_rec"])
+ if (!( data_core.general.Find(R) ))
+ src.temp = "Medical Records:
Record Not Found.
"
+ return
+ for(var/datum/data/record/E in data_core.medical)
+ if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
+ M = E
+ src.medicalActive1 = R
+ src.medicalActive2 = M
+ src.medScreen = 1 // Set screen to view a specific record
+ var/tempScreen = href_list["screen"]
+ if(tempScreen)
+ src.medScreen = tempScreen
+ if (href_list["buy"])
+ var/s = href_list["buy"]
+ var/dat = ""
+ if(!src.available_software.Find(s))
+ dat += "Error
Requested software package not found.
"
+ src << browse(dat, "window=paibuy")
+ onclose(src, "paibuy")
+ else if(src.ram < src.available_software[s])
+ dat += "Error
Not enough Remaining Available Memory to complete requested task.
"
+ src << browse(dat, "window=paibuy")
+ onclose(src, "paibuy")
+ else
+ src.ram -= src.available_software[s]
+ switch(s)
+ if("crew manifest")
+ src.software.Add("crew manifest")
+ if("medical records")
+ src.software.Add("medical records")
+ if("security records")
+ src.software.Add("security records")
+ if("camera")
+ src.software.Add("camera")
+ if("atmosphere sensor")
+ src.software.Add("atmosphere sensor")
+ if("heartbeat sensor")
+ src.software.Add("heartbeat sensor")
+ if("security HUD")
+ src.software.Add("security HUD")
+ if("medical HUD")
+ src.software.Add("medical HUD")
+ if("universal translator")
+ src.universal_speak = 1
+ src.software.Add("universal translator")
+ else
+ //blahblah
+ src.downloadSoftware()
+ return
+
+/*
+/mob/living/silicon/pai/proc/ai_network_change()
+ set category = "pAI Commands"
+ set name = "Change Camera Network"
+*/
+
+// Basic Features:
+// Crew Manifest
+// Medical Records
+// Security Records
+// Camera Jack
+//
+// Advanced Features:
+// Atmosphere Sensor
+// Heartbeat sensor
+// Security HUD
+// Medical HUD (Also provides a health analyzer that will assess the user's health)
+// Universal Translator
+//
+// Built-in Features:
+// Radio
+// PDA Messaging
+
+
+
+// Physical Upgrades:
+// - Camera Uplink (Removes the need to be plugged in to a camera to access the network)
+
+
+/mob/verb/makePAI(var/turf/t in view())
+ var/obj/item/device/paicard/card = new(t)
+ var/mob/living/silicon/pai/pai = new(card)
+ pai.key = src.key
+
+/mob/living/silicon/pai/verb/paiInterface()
+ set category = "pAI Commands"
+ set name = "Software Interface"
+
+ var/dat = ""
+ // Built-in
+ dat += "Radio Configuration
"
+ dat += "Text Messaging
"
+ dat += "
"
+
+ // Basic
+ dat += "Basic
"
+ for(var/s in src.software)
+ if(s == "crew manifest")
+ dat += "Crew Manifest
"
+ if(s == "medical records")
+ dat += "Medical Records
"
+ if(s == "security records")
+ dat += "Security Records
"
+ if(s == "camera")
+ dat += "Camera Jack
"
+ dat += "
"
+
+ // Advanced
+ dat += "Advanced
"
+ for(var/s in src.software)
+ if(s == "atmosphere sensor")
+ dat += "Atmospheric Sensor
"
+ if(s == "heartbeat sensor")
+ dat += "Heartbeat Sensor
"
+ if(s == "security HUD")
+ dat += "Facial Recognition Suite
"
+ if(s == "medical HUD")
+ dat += "Medical Analysis Suite
"
+ if(s == "universal translator")
+ dat += "Universal Translator[(src.universal_speak) ? "Enabled" : "Disabled"]
"
+ dat += "
"
+ dat += "
"
+ dat += "Download additional software"
+
+ src << browse(dat, "window=pai")
+ onclose(src, "pai")
+
+
+/mob/living/silicon/pai/proc/downloadSoftware()
+ var/dat = ""
+
+ dat += "CentComm pAI Module Subversion Network
"
+ dat += "Remaining Available Memory: [src.ram]
"
+ dat += "Trunks available for checkout
"
+
+ for(var/s in available_software)
+ if(!software.Find(s))
+ var/cost = src.available_software[s]
+ var/displayName = uppertext(s)
+ dat += "[displayName] ([cost])
"
+ else
+ var/displayName = lowertext(s)
+ dat += "[displayName]
(Download Complete)
"
+ dat += ""
+ //src << browse(dat, "window=paibuy")
+ //onclose(src, "paibuy")
+ return dat
+
+
+
+/mob/living/silicon/pai/proc/softwareManifest()
+ var/dat = ""
+ dat += "Crew Manifest
"
+ for (var/datum/data/record/t in data_core.general)
+ dat += "[t.fields["name"]] - [t.fields["rank"]]
"
+ //src << browse(dat, "window=paimanifest")
+ //onclose(src, "paimanifest")
+ return dat
+
+/mob/living/silicon/pai/proc/softwareMedicalRecords()
+ world << "softwareMedicalRecords() got called"
+ var/dat = ""
+
+ if(medScreen == 0)
+ dat += "Record List:
"
+ for(var/datum/data/record/R in data_core.general)
+ dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"])
+ //Foreach goto(132)
+ dat += text("
Back", src)
+ if(medScreen == 1)
+ dat += "Medical Record
"
+ if ((istype(src.medicalActive1, /datum/data/record) && data_core.general.Find(src.medicalActive1)))
+ dat += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
",
+ src.medicalActive1.fields["name"], src.medicalActive1.fields["id"], src, src.medicalActive1.fields["sex"], src, src.medicalActive1.fields["age"], src, src.medicalActive1.fields["fingerprint"], src, src.medicalActive1.fields["p_stat"], src, src.medicalActive1.fields["m_stat"])
+ else
+ dat += "Requested medical record not found.
"
+ if ((istype(src.medicalActive2, /datum/data/record) && data_core.medical.Find(src.medicalActive2)))
+ dat += text("
\nMedical Data
\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\nComments/Log
", src, src.medicalActive2.fields["b_type"], src, src.medicalActive2.fields["b_dna"], src, src.medicalActive2.fields["mi_dis"], src, src.medicalActive2.fields["mi_dis_d"], src, src.medicalActive2.fields["ma_dis"], src, src.medicalActive2.fields["ma_dis_d"], src, src.medicalActive2.fields["alg"], src, src.medicalActive2.fields["alg_d"], src, src.medicalActive2.fields["cdi"], src, src.medicalActive2.fields["cdi_d"], src, src.medicalActive2.fields["notes"])
+ /*
+ var/counter = 1
+ while(src.medicalActive2.fields[text("com_[]", counter)])
+ dat += text("[]
Delete Entry
", src.medicalActive2.fields[text("com_[]", counter)], src, counter)
+ counter++
+ */
+ else
+ dat += "Requested medical record not found.
"
+ dat += text("
\nBack
", src)
+ //src << browse(dat, "window=paiMedical")
+ return dat
+
+
+// ****** THIS IS WHERE YOU LEFT OFF. LOOK IN TO FIGURING OUT WHAT medicalActive1 IS AND HOW TO APPROPRIATE IT TO THE PAI *******
+// ALSO CONSIDER ADDING A POWER MONITOR PACKAGE. HEARTBEAT SENSOR MIGHT BE COOL IF IT PULSED AN OVERLAY WITH A ROUGH LOCATION OF WHERE A MOB IS STANDING.
+// REMEMBER THAT YOU STILL NEED TO DO LOGIN AND LOGOUT.DM
+// MAYBE ADD A CORRUPTION (HEALTH) VAR FOR CYBERSPACE STUFF. AND SOME LAWS THAT CAN GET HACKED
+// YOU STILL HAVEN'T ADDED A WAY TO TRACK WHO THE PAI IS BOUND TO, EITHER. GET ON THAT
\ No newline at end of file