diff --git a/cev_eris.dme b/cev_eris.dme
index 15f72edf42b..f7b9f54bbb9 100644
--- a/cev_eris.dme
+++ b/cev_eris.dme
@@ -359,7 +359,6 @@
#include "code\datums\chat_payload.dm"
#include "code\datums\chatmessage.dm"
#include "code\datums\contract.dm"
-#include "code\datums\datacore.dm"
#include "code\datums\datum.dm"
#include "code\datums\datum_click_handlers.dm"
#include "code\datums\datum_hud.dm"
@@ -832,14 +831,12 @@
#include "code\game\machinery\computer\computer.dm"
#include "code\game\machinery\computer\guestpass.dm"
#include "code\game\machinery\computer\law.dm"
-#include "code\game\machinery\computer\medical.dm"
#include "code\game\machinery\computer\message.dm"
#include "code\game\machinery\computer\Operating.dm"
#include "code\game\machinery\computer\pod.dm"
#include "code\game\machinery\computer\prisoner.dm"
#include "code\game\machinery\computer\prisonshuttle.dm"
#include "code\game\machinery\computer\robot.dm"
-#include "code\game\machinery\computer\security.dm"
#include "code\game\machinery\computer\station_alert.dm"
#include "code\game\machinery\doors\airlock.dm"
#include "code\game\machinery\doors\airlock_control.dm"
@@ -1558,6 +1555,7 @@
#include "code\modules\asset_cache\assets\chat.dm"
#include "code\modules\asset_cache\assets\icon_ref_map.dm"
#include "code\modules\asset_cache\assets\notes.dm"
+#include "code\modules\asset_cache\assets\legacyuiicons.dm"
#include "code\modules\asset_cache\assets\sanity.dm"
#include "code\modules\asset_cache\assets\sheetmaterials.dm"
#include "code\modules\asset_cache\assets\stats.dm"
@@ -2394,6 +2392,7 @@
#include "code\modules\nano\modules\human_appearance.dm"
#include "code\modules\nano\modules\law_manager.dm"
#include "code\modules\nano\modules\nano_module.dm"
+#include "code\modules\nano\modules\tgui_type.dm"
#include "code\modules\onestar\generator.dm"
#include "code\modules\onestar\os_cash.dm"
#include "code\modules\onestar\os_turret.dm"
diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm
index 18a82d9b01c..2bebcf467e3 100644
--- a/code/__DEFINES/jobs.dm
+++ b/code/__DEFINES/jobs.dm
@@ -8,10 +8,10 @@
#define JOBS_MEDICAL "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer"
#define JOBS_SCIENCE "Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist"
#define JOBS_MOEBIUS "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer","Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist"
-#define JOBS_CARGO "Guild Merchant","Guild Technician","Guild Miner",
+#define JOBS_GUILD "Guild Merchant","Guild Technician","Guild Miner",
#define JOBS_CIVILIAN "Club Manager","Club Worker","Club Artist",ASSISTANT_TITLE
#define JOBS_CHURCH "NeoTheology Preacher","NeoTheology Acolyte","NeoTheology Agrolyte","NeoTheology Custodian"
-#define JOBS_NONHUMAN "AI","Robot","pAI"
+#define JOBS_SILICON "AI","Robot","pAI"
#define CREDITS "¢"
#define CREDS "¢"
diff --git a/code/__DEFINES/perks.dm b/code/__DEFINES/perks.dm
index 210eaa70c3e..d6571683e42 100644
--- a/code/__DEFINES/perks.dm
+++ b/code/__DEFINES/perks.dm
@@ -1,6 +1,6 @@
//fate perks
#define PERK_PAPER_WORM /datum/perk/fate/paper_worm
-#define PERK_FREELACER /datum/perk/fate/freelancer
+#define PERK_FREELANCER /datum/perk/fate/freelancer
#define PERK_NIHILIST /datum/perk/fate/nihilist
#define PERK_MORALIST /datum/perk/fate/moralist
#define PERK_ALCOHOLIC /datum/perk/fate/alcoholic
@@ -49,6 +49,8 @@
#define PERK_CODESPEAK_COP /datum/perk/codespeak
#define PERK_CODESPEAK_SERB /datum/perk/codespeak/serbian
#define PERK_TECHNOMANCER /datum/perk/inspiration
+#define PERK_NEAT /datum/perk/neat
+#define PERK_GREEN_THUMB /datum/perk/greenthumb
#define PERK_CLUB /datum/perk/job/club
#define PERK_CHANNELING /datum/perk/channeling
diff --git a/code/__HELPERS/manifest.dm b/code/__HELPERS/manifest.dm
index 66527c5ebc7..135cb4a23fd 100644
--- a/code/__HELPERS/manifest.dm
+++ b/code/__HELPERS/manifest.dm
@@ -142,13 +142,13 @@
"sec" = filtered_nano_crew_manifest(security_positions),\
"eng" = filtered_nano_crew_manifest(engineering_positions),\
"med" = filtered_nano_crew_manifest(medical_positions),\
- "sup" = filtered_nano_crew_manifest(cargo_positions),\
+ "sup" = filtered_nano_crew_manifest(guild_positions),\
"chr" = filtered_nano_crew_manifest(church_positions),\
- "bot" = silicon_nano_crew_manifest(nonhuman_positions),\
+ "bot" = silicon_nano_crew_manifest(silicon_positions),\
"civ" = filtered_nano_crew_manifest(civilian_positions)\
)
/proc/flat_nano_crew_manifest()
. = list()
. += filtered_nano_crew_manifest(null, TRUE)
- . += silicon_nano_crew_manifest(nonhuman_positions)
+ . += silicon_nano_crew_manifest(silicon_positions)
diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm
index 0c6b487f29f..0d3347c4a38 100644
--- a/code/__HELPERS/names.dm
+++ b/code/__HELPERS/names.dm
@@ -110,8 +110,8 @@ var/syndicate_code_response//Code response for contractors.
var/locations[] = SSmapping.teleportlocs.len ? SSmapping.teleportlocs : drinks//if null, defaults to drinks instead.
var/names[] = list()
- for(var/datum/data/record/t in data_core.general)//Picks from crew manifest.
- names += t.fields["name"]
+ for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records)//Picks from crew manifest.
+ names += t.get_name()
var/maxwords = words//Extra var to check for duplicates.
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 775c9806297..26a1f8da684 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -276,26 +276,21 @@ Turf and target are seperate in case you want to teleport some distance from a t
mind.name = newname
if(oldname)
- //update the datacore records! This is goig to be a bit costly.
- for(var/list/L in list(data_core.general, data_core.medical, data_core.security, data_core.locked))
- for(var/datum/data/record/R in L)
- if(R.fields["name"] == oldname)
- R.fields["name"] = newname
- break
+ for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records)
+ if(R.get_name() == oldname)
+ R.set_name(newname)
//update our pda and id if we have them on our person
- var/list/searching = GetAllContents(searchDepth = 3)
- var/search_id = 1
- var/search_pda = 1
-
- for(var/A in searching)
- if( search_id && istype(A,/obj/item/card/id) )
+ for(var/obj/A in GetAllContents(searchDepth = 3))
+ if(istype(A,/obj/item/card/id))
var/obj/item/card/id/ID = A
if(ID.registered_name == oldname)
ID.registered_name = newname
ID.name = "[newname]'s ID Card ([ID.assignment])"
- if(!search_pda) break
- search_id = 0
+ if(istype(A.loc, /obj/item/modular_computer))
+ var/obj/item/modular_computer/tolabel = A.loc
+ tolabel.update_label()
+ break
return 1
diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm
index 7bf4718792f..401d2222ece 100644
--- a/code/controllers/subsystems/ticker.dm
+++ b/code/controllers/subsystems/ticker.dm
@@ -264,7 +264,6 @@ SUBSYSTEM_DEF(ticker)
if(!H.mind || player_is_antag(H.mind, only_offstation_roles = 1) || !SSjob.ShouldCreateRecords(H.mind.assigned_role))
continue
CreateModularRecord(H)
- data_core.manifest()
CHECK_TICK
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
deleted file mode 100644
index 55f2af15562..00000000000
--- a/code/datums/datacore.dm
+++ /dev/null
@@ -1,454 +0,0 @@
-var/global/list/PDA_Manifest = list()
-var/global/ManifestJSON
-
-/hook/startup/proc/createDatacore()
- data_core = new /datum/datacore()
- return 1
-
-/datum/datacore
- var/name = "datacore"
- var/medical[] = list()
- var/general[] = list()
- var/security[] = list()
- //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character().
- var/locked[] = list()
-
-
-/datum/datacore/proc/get_manifest(monochrome, OOC)
- var/list/heads = new()
- var/list/sec = new()
- var/list/eng = new()
- var/list/med = new()
- var/list/sci = new()
- var/list/car = new()
- var/list/chr = new()
- var/list/civ = new()
- var/list/bot = new()
- var/list/misc = new()
- var/list/isactive = new()
- var/dat = {"
-
-
- Name Rank Activity
- "}
- var/even = 0
- // sort mobs
- for(var/datum/data/record/t in data_core.general)
- var/name = t.fields["name"]
- var/rank = t.fields["rank"]
- var/real_rank = make_list_rank(t.fields["real_rank"])
-
- if(OOC)
- var/active = 0
- for(var/mob/M in GLOB.player_list)
- if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10)
- active = 1
- break
- isactive[name] = active ? "Active" : "Inactive"
- else
- isactive[name] = t.fields["p_stat"]
- //world << "[name]: [rank]"
- //cael - to prevent multiple appearances of a player/job combination, add a continue after each line
- var/department = 0
- if(real_rank in command_positions)
- heads[name] = rank
- department = 1
- if(real_rank in security_positions)
- sec[name] = rank
- department = 1
- if(real_rank in engineering_positions)
- eng[name] = rank
- department = 1
- if(real_rank in medical_positions)
- med[name] = rank
- department = 1
- if(real_rank in science_positions)
- sci[name] = rank
- department = 1
- if(real_rank in cargo_positions)
- car[name] = rank
- department = 1
- if(real_rank in church_positions)
- chr[name] = rank
- department = 1
- if(real_rank in civilian_positions)
- civ[name] = rank
- department = 1
- if(!department && !(name in heads))
- misc[name] = rank
-
- // Synthetics don't have actual records, so we will pull them from here.
-/* for(mob/living/silicon/ai/ai in SSmobs.mob_list)
- bot[ai.name] = "Artificial Intelligence"
-
- for(var/mob/living/silicon/robot/robot in SSmobs.mob_list)
- // No combat/syndicate cyborgs, no drones.
- if(robot.module && robot.module.hide_on_manifest)
- continue
-
- bot[robot.name] = "[robot.modtype] [robot.braintype]"*/
-
- if(bot.len > 0)
- dat += "Silicon "
- for(name in bot)
- dat += "[name] [bot[name]] [isactive[name]] "
- even = !even
-
- if(heads.len > 0)
- dat += "Heads "
- for(name in heads)
- dat += "[name] [heads[name]] [isactive[name]] "
- even = !even
- if(sec.len > 0)
- dat += "Security "
- for(name in sec)
- dat += "[name] [sec[name]] [isactive[name]] "
- even = !even
- if(eng.len > 0)
- dat += "Engineering "
- for(name in eng)
- dat += "[name] [eng[name]] [isactive[name]] "
- even = !even
- if(med.len > 0)
- dat += "Medical "
- for(name in med)
- dat += "[name] [med[name]] [isactive[name]] "
- even = !even
- if(sci.len > 0)
- dat += "Science "
- for(name in sci)
- dat += "[name] [sci[name]] [isactive[name]] "
- even = !even
- if(car.len > 0)
- dat += "Guild "
- for(name in car)
- dat += "[name] [car[name]] [isactive[name]] "
- even = !even
- if(chr.len > 0)
- dat += "Church "
- for(name in chr)
- dat += "[name] [chr[name]] [isactive[name]] "
- even = !even
- if(civ.len > 0)
- dat += "Civilian "
- for(name in civ)
- dat += "[name] [civ[name]] [isactive[name]] "
- even = !even
- if(misc.len > 0)
- dat += "Miscellaneous "
- for(name in misc)
- dat += "[name] [misc[name]] [isactive[name]] "
- even = !even
-
- dat += "
"
- dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
- dat = replacetext(dat, "\t", "")
- return dat
-
-/datum/datacore/proc/manifest()
- spawn()
- for(var/mob/living/carbon/human/H in GLOB.player_list)
- manifest_inject(H)
- return
-
-/datum/datacore/proc/manifest_modify(name, assignment)
- ResetPDAManifest()
- var/datum/data/record/foundrecord
- var/real_title = assignment
-
- for(var/datum/data/record/t in data_core.general)
- if (t)
- if(t.fields["name"] == name)
- foundrecord = t
- break
-
- if(foundrecord)
- foundrecord.fields["rank"] = assignment
- foundrecord.fields["real_rank"] = real_title
-
-/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H)
- if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1) && H.job != ASSISTANT_TITLE)
- var/assignment = GetAssignment(H)
-
- var/id = generate_record_id()
- //General Record
- var/datum/data/record/G = CreateGeneralRecord(H, id)
- G.fields["name"] = H.real_name
- G.fields["real_rank"] = H.mind.assigned_role
- G.fields["rank"] = assignment
- G.fields["age"] = H.age
- G.fields["fingerprint"] = H.fingers_trace
- if(H.mind.initial_account)
- G.fields["pay_account"] = H.mind.initial_account.account_number ? H.mind.initial_account.account_number : "N/A"
- G.fields["email"] = H.mind.initial_email_login["login"]
- G.fields["p_stat"] = "Active"
- G.fields["m_stat"] = "Stable"
- G.fields["sex"] = H.gender
- if(H.gen_record && !jobban_isbanned(H, "Records"))
- G.fields["notes"] = H.gen_record
-
- //Medical Record
- var/datum/data/record/M = CreateMedicalRecord(H.real_name, id)
- M.fields["b_type"] = H.b_type
- M.fields["b_dna"] = H.dna_trace
- //M.fields["id_gender"] = gender2text(H.identifying_gender)
- if(H.med_record && !jobban_isbanned(H, "Records"))
- M.fields["notes"] = H.med_record
-
- //Security Record
- var/datum/data/record/S = CreateSecurityRecord(H.real_name, id)
- if(H.sec_record && !jobban_isbanned(H, "Records"))
- S.fields["notes"] = H.sec_record
-
- //Locked Record
- var/datum/data/record/L = new()
- L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]")
- L.fields["name"] = H.real_name
- L.fields["rank"] = H.mind.assigned_role
- L.fields["age"] = H.age
- L.fields["fingerprint"] = H.fingers_trace
- L.fields["sex"] = H.gender
- L.fields["b_type"] = H.b_type
- L.fields["b_dna"] = H.dna_trace
- L.fields["image"] = getFlatIcon(H) //This is god-awful
- if(H.exploit_record && !jobban_isbanned(H, "Records"))
- L.fields["exploit_record"] = H.exploit_record
- else
- L.fields["exploit_record"] = "No additional information acquired."
- locked += L
- return
-
-/proc/generate_record_id()
- return add_zero(num2hex(rand(1, 65535), 5), 4) //no point generating higher numbers because of the limitations of num2hex
-
-/proc/get_id_photo(mob/living/carbon/human/H, assigned_role)
-
- var/icon/preview_icon = new(H.stand_icon)
- var/icon/temp
-
- var/datum/sprite_accessory/hair_style = GLOB.hair_styles_list[H.h_style]
- if(hair_style)
- temp = new/icon(hair_style.icon, hair_style.icon_state)
- temp.Blend(H.hair_color, ICON_ADD)
-
- hair_style = GLOB.facial_hair_styles_list[H.h_style]
- if(hair_style)
- var/icon/facial = new/icon(hair_style.icon, hair_style.icon_state)
- facial.Blend(H.facial_color, ICON_ADD)
- temp.Blend(facial, ICON_OVERLAY)
-
- preview_icon.Blend(temp, ICON_OVERLAY)
-
-
- var/datum/job/J = SSjob.GetJob(H.mind.assigned_role)
- if(J)
- var/t_state
- temp = new /icon('icons/inventory/uniform/mob.dmi', t_state)
-
- temp.Blend(new /icon('icons/inventory/feet/mob.dmi', t_state), ICON_OVERLAY)
- else
- temp = new /icon('icons/inventory/uniform/mob.dmi', "grey")
- temp.Blend(new /icon('icons/inventory/feet/mob.dmi', "black"), ICON_OVERLAY)
-
- preview_icon.Blend(temp, ICON_OVERLAY)
-
- qdel(temp)
-
- return preview_icon
-
-/datum/datacore/proc/CreateGeneralRecord(mob/living/carbon/human/H, id)
- ResetPDAManifest()
- var/icon/front
- var/icon/side
- if(H)
- front = getFlatIcon(H, SOUTH)
- side = getFlatIcon(H, WEST)
- else
- var/mob/living/carbon/human/dummy = new()
- front = new(get_id_photo(dummy), dir = SOUTH)
- side = new(get_id_photo(dummy), dir = WEST)
- qdel(dummy)
-
- if(!id) id = text("[]", add_zero(num2hex(rand(1, 1.6777215E7), 8), 6))
- var/datum/data/record/G = new /datum/data/record()
- G.name = "Employee Record #[id]"
- G.fields["name"] = "New Record"
- G.fields["id"] = id
- G.fields["rank"] = "Unassigned"
- G.fields["real_rank"] = "Unassigned"
- G.fields["sex"] = "Male"
- G.fields["age"] = "Unknown"
- G.fields["fingerprint"] = "Unknown"
- G.fields["p_stat"] = "Active"
- G.fields["m_stat"] = "Stable"
- G.fields["species"] = SPECIES_HUMAN
- G.fields["photo_front"] = front
- G.fields["photo_side"] = side
- G.fields["notes"] = "No notes found."
- general += G
-
- return G
-
-/datum/datacore/proc/CreateSecurityRecord(name, id)
- ResetPDAManifest()
- var/datum/data/record/R = new /datum/data/record()
- R.name = "Security Record #[id]"
- R.fields["name"] = name
- R.fields["id"] = id
- R.fields["criminal"] = "None"
- R.fields["mi_crim"] = "None"
- R.fields["mi_crim_d"] = "No minor crime convictions."
- R.fields["ma_crim"] = "None"
- R.fields["ma_crim_d"] = "No major crime convictions."
- R.fields["notes"] = "No notes."
- R.fields["notes"] = "No notes."
- data_core.security += R
-
- return R
-
-/datum/datacore/proc/CreateMedicalRecord(name, id)
- ResetPDAManifest()
- var/datum/data/record/M = new()
- M.name = "Medical Record #[id]"
- M.fields["id"] = id
- M.fields["name"] = name
- M.fields["b_type"] = "AB+"
- M.fields["b_dna"] = md5(name)
- M.fields["mi_dis"] = "None"
- M.fields["mi_dis_d"] = "No minor disabilities have been declared."
- M.fields["ma_dis"] = "None"
- M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
- M.fields["alg"] = "None"
- M.fields["alg_d"] = "No allergies have been detected in this patient."
- M.fields["cdi"] = "None"
- M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
- M.fields["notes"] = "No notes found."
- data_core.medical += M
-
- return M
-
-/datum/datacore/proc/ResetPDAManifest()
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
-
-/proc/find_general_record(field, value)
- return find_record(field, value, data_core.general)
-
-/proc/find_medical_record(field, value)
- return find_record(field, value, data_core.medical)
-
-/proc/find_security_record(field, value)
- return find_record(field, value, data_core.security)
-
-/proc/find_record(field, value, list/L)
- for(var/datum/data/record/R in L)
- if(R.fields[field] == value)
- return R
-
-/*/proc/GetAssignment(mob/living/carbon/human/H)
- if(H.mind.assigned_role)
- return H.mind.assigned_role
- else if(H.job)
- return H.job
- else
- return "Unassigned"
-*/
-var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional")
-
-/proc/make_list_rank(rank)
- for(var/prefix in acting_rank_prefixes)
- if(findtext(rank, "[prefix] ", 1, 2+length(prefix)))
- return copytext(rank, 2+length(prefix))
- return rank
-
-/datum/datacore/proc/get_manifest_json()
- if(PDA_Manifest.len)
- return
- var/heads[0]
- var/sec[0]
- var/eng[0]
- var/med[0]
- var/sci[0]
- var/chr[0]
- var/civ[0]
- var/bot[0]
- var/misc[0]
- for(var/datum/data/record/t in data_core.general)
- var/name = sanitize(t.fields["name"])
- var/rank = sanitize(t.fields["rank"])
- var/real_rank = make_list_rank(t.fields["real_rank"])
-
- var/isactive = t.fields["p_stat"]
- var/department = 0
- var/depthead = 0 // Department Heads will be placed at the top of their lists.
- if(real_rank in command_positions)
- heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- depthead = 1
- if(rank=="Captain" && heads.len != 1)
- heads.Swap(1, heads.len)
-
- if(real_rank in security_positions)
- sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && sec.len != 1)
- sec.Swap(1, sec.len)
-
- if(real_rank in engineering_positions)
- eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && eng.len != 1)
- eng.Swap(1, eng.len)
-
- if(real_rank in medical_positions)
- med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && med.len != 1)
- med.Swap(1, med.len)
-
- if(real_rank in science_positions)
- sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && sci.len != 1)
- sci.Swap(1, sci.len)
-
- if(real_rank in church_positions)
- chr[++chr.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && chr.len != 1)
- chr.Swap(1, chr.len)
-
- if(real_rank in civilian_positions)
- civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
- if(depthead && civ.len != 1)
- civ.Swap(1, civ.len)
-
- if(real_rank in nonhuman_positions)
- bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive)
- department = 1
-
- if(!department && !(name in heads))
- misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
-
-
- PDA_Manifest = list(
- "heads" = heads,
- "sec" = sec,
- "eng" = eng,
- "med" = med,
- "sci" = sci,
- "chr" = chr,
- "civ" = civ,
- "bot" = bot,
- "misc" = misc
- )
- ManifestJSON = json_encode(PDA_Manifest)
- return
diff --git a/code/datums/setup_option/backgrounds/fate.dm b/code/datums/setup_option/backgrounds/fate.dm
index 8093c95bbc3..3cda4c9d8e7 100644
--- a/code/datums/setup_option/backgrounds/fate.dm
+++ b/code/datums/setup_option/backgrounds/fate.dm
@@ -26,7 +26,7 @@
You were always on the move, looking for a brighter future on the other side. \
And because of that you never specialised as much as you should, but have broader array of other skills."
- perks = list(PERK_FREELACER)
+ perks = list(PERK_FREELANCER)
/datum/category_item/setup_option/background/fate/nihilist
name = "Nihilist"
diff --git a/code/datums/topic/world.dm b/code/datums/topic/world.dm
index 2fe29f219d7..795bf628537 100644
--- a/code/datums/topic/world.dm
+++ b/code/datums/topic/world.dm
@@ -94,31 +94,16 @@
/datum/world_topic/manifest/Run(list/input)
var/list/positions = list()
- var/list/set_names = list(
- "heads" = command_positions,
- "sec" = security_positions,
- "eng" = engineering_positions,
- "med" = medical_positions,
- "sci" = science_positions,
- "car" = cargo_positions,
- "civ" = civilian_positions,
- "chr" = church_positions,
- "bot" = nonhuman_positions
- )
-
- for(var/datum/data/record/t in data_core.general)
- var/name = t.fields["name"]
- var/rank = t.fields["rank"]
- var/real_rank = make_list_rank(t.fields["real_rank"])
-
- var/department = FALSE
- for(var/k in set_names)
- if(real_rank in set_names[k])
- if(!positions[k])
- positions[k] = list()
- positions[k][name] = rank
- department = TRUE
- if(!department)
+
+ for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records)
+ var/name = t.get_name()
+ var/rank = t.get_job()
+
+ var/department = t.get_department()
+
+ if(department && department != "Unset")
+ positions[department][name] = rank
+ else
if(!positions["misc"])
positions["misc"] = list()
positions["misc"][name] = rank
diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm
index 2b4a4fdb212..e2ee0a4dc3a 100644
--- a/code/datums/uplink/announcements.dm
+++ b/code/datums/uplink/announcements.dm
@@ -38,48 +38,42 @@
return 0
var/obj/item/card/id/I = user.GetIdCard()
- var/datum/data/record/random_general_record
- var/datum/data/record/random_medical_record
- if(data_core.general.len)
- random_general_record = pick(data_core.general)
- random_medical_record = find_medical_record("id", random_general_record.fields["id"])
+ var/datum/computer_file/report/crew_record/random_record
+ if(GLOB.all_crew_records.len)
+ random_record = pick(GLOB.all_crew_records)
- var/datum/data/record/general = data_core.CreateGeneralRecord(user)
+ var/datum/computer_file/report/crew_record/general = new()
if(I)
- general.fields["age"] = I.age
- general.fields["rank"] = I.assignment
- general.fields["real_rank"] = I.assignment
- general.fields["name"] = I.registered_name
- general.fields["sex"] = I.sex
+ general.set_age(I.age)
+ general.set_job(I.assignment)
+ general.set_name(I.registered_name)
+ general.set_sex(I.sex)
else
var/mob/living/carbon/human/H
if(ishuman(user))
H = user
- general.fields["age"] = H.age
+ general.set_age(H.age)
else
- general.fields["age"] = initial(H.age)
+ general.set_age(initial(H.age))
var/assignment = GetAssignment(user)
- general.fields["rank"] = assignment
- general.fields["real_rank"] = assignment
- general.fields["name"] = user.real_name
- general.fields["sex"] = capitalize(user.gender)
+ general.set_job(assignment)
+ general.set_department(args["department"])
+ general.set_name(user.real_name)
+ general.set_sex(capitalize(user.gender))
- general.fields["species"] = user.get_species()
- var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"])
- data_core.CreateSecurityRecord(general.fields["name"], general.fields["id"])
+ general.set_species(user.get_species())
- if(!random_general_record)
- general.fields["fingerprint"] = random_general_record.fields["fingerprint"]
- if(random_medical_record)
- medical.fields["b_type"] = random_medical_record.fields["b_type"]
- medical.fields["b_dna"] = random_medical_record.fields["b_type"]
+ if(random_record)
+ general.set_fingerprint(random_record.get_fingerprint())
+ general.set_bloodtype(random_record.get_bloodtype())
+ general.set_dna(random_record.get_bloodtype())
if(I)
- general.fields["fingerprint"] = I.fingerprint_hash
- medical.fields["b_type"] = I.blood_type
- medical.fields["b_dna"] = I.dna_hash
+ general.set_fingerprint(I.fingerprint_hash)
+ general.set_bloodtype(I.blood_type)
+ general.set_dna(I.dna_hash)
- AnnounceArrival(general.fields["name"], general.fields["rank"], "has completed cryogenic revival")
+ AnnounceArrival(general.get_name(), general.get_job(), "has completed cryogenic revival")
return 1
/datum/uplink_item/abstract/announcements/fake_ion_storm
diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm
index aaeac96e804..deb597d4d4b 100644
--- a/code/game/jobs/jobs.dm
+++ b/code/game/jobs/jobs.dm
@@ -78,7 +78,7 @@ var/list/science_positions = list(JOBS_SCIENCE)
var/list/moebius_positions = list(JOBS_MOEBIUS)
//BS12 EDIT
-var/list/cargo_positions = list(JOBS_CARGO)
+var/list/guild_positions = list(JOBS_GUILD)
var/list/church_positions = list(JOBS_CHURCH)
@@ -90,7 +90,7 @@ var/list/civilian_positions = list(JOBS_CIVILIAN)
var/list/security_positions = list(JOBS_SECURITY)
var/list/armory_positions = list(JOBS_ARMORY)
-var/list/nonhuman_positions = list(JOBS_NONHUMAN)
+var/list/silicon_positions = list(JOBS_SILICON)
/proc/guest_jobbans(var/job)
- return ((job in command_positions) || (job in nonhuman_positions) || (job in armory_positions))
+ return ((job in command_positions) || (job in silicon_positions) || (job in armory_positions))
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
deleted file mode 100644
index c59fa2806ce..00000000000
--- a/code/game/machinery/computer/medical.dm
+++ /dev/null
@@ -1,519 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
-/obj/machinery/computer/med_data//TODO:SANITY
- name = "medical records console"
- desc = "Used to view, edit and maintain medical records."
- icon_keyboard = "med_key"
- icon_screen = "medcomp"
- light_color = COLOR_LIGHTING_GREEN_MACHINERY
- req_one_access = list(access_moebius, access_forensics_lockers)
- circuit = /obj/item/electronics/circuitboard/med_data
- var/obj/item/card/id/scan
- var/authenticated
- var/rank
- var/screen
- var/datum/data/record/active1
- var/datum/data/record/active2
- var/a_id
- var/temp
- var/printing
-
-/obj/machinery/computer/med_data/verb/eject_id()
- set category = "Object"
- set name = "Eject ID Card"
- set src in oview(1)
-
- if(!usr || usr.stat || usr.lying) return
-
- if(scan)
- to_chat(usr, "You remove \the [scan] from \the [src].")
- scan.loc = get_turf(src)
- if(!usr.get_active_held_item() && ishuman(usr))
- usr.put_in_hands(scan)
- scan = null
- else
- to_chat(usr, "There is nothing to remove from the console.")
- return
-
-/obj/machinery/computer/med_data/attackby(obj/item/O, mob/user)
- if(istype(O, /obj/item/card/id) && !scan && user.unEquip(O))
- O.loc = src
- scan = O
- to_chat(user, "You insert \the [O].")
- else
- ..()
-
-/obj/machinery/computer/med_data/attack_hand(mob/user as mob)
- if(..())
- return
- nano_ui_interact(user)
-
-/obj/machinery/computer/med_data/nano_ui_interact(mob/user)
- var/dat
- if (src.temp)
- dat = text("[src.temp] Clear Screen ")
- else
- dat = text("Confirm Identity: [] ", src, (src.scan ? text("[]", src.scan.name) : "----------"))
- if (src.authenticated)
- switch(src.screen)
- if(1)
- dat += {"
-Search Records
-List Records
-Medbot Tracking
-
-Record Maintenance
-{Log Out}
-"}
- if(2)
- dat += "Record List : "
- if(!isnull(data_core.general))
- for(var/datum/data/record/R in sortRecord(data_core.general))
- dat += text("[]: [] ", src, R, R.fields["id"], R.fields["name"])
- //Foreach goto(132)
- dat += text(" Back ", src)
- if(3)
- dat += text("Records Maintenance \nBackup To Disk \nUpload From disk \nDelete All Records \n \nBack ", src, src, src, src)
- if(4)
- var/icon/front = active1.fields["photo_front"]
- var/icon/side = active1.fields["photo_side"]
- user << browse_rsc(front, "front.png")
- user << browse_rsc(side, "side.png")
- dat += "Medical Record "
- if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
- dat += ""
- else
- dat += "General Record Lost! "
- if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
- 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.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"]))
- var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
- dat += text("[]Delete Entry ", src.active2.fields[text("com_[]", counter)], src, counter)
- counter++
- dat += text("Add Entry ", src)
- dat += text("Delete Record (Medical Only) ", src)
- else
- dat += "Medical Record Lost! "
- dat += text("New Record ")
- dat += text("\nPrint Record \nBack ", src, src)
- if(6)
- dat += "Medical Robot Monitor "
- dat += "Back "
- dat += "Medical Robots: "
- var/bdat
- for(var/mob/living/bot/medbot/M in world)
-
- if(M.z != src.z) continue //only find medibots on the same z-level as the computer
- var/turf/bl = get_turf(M)
- if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up
- bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"] "
- if((!isnull(M.reagent_glass)) && M.use_beaker)
- bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\] "
- else
- bdat += "Using Internal Synthesizer. "
- if(!bdat)
- dat += "None detected "
- else
- dat += " [bdat]"
-
- else
- else
- dat += text("{Log In} ", src)
- user << browse(HTML_SKELETON_TITLE("Medical Records", "[dat] "), "window=med_rec")
- onclose(user, "med_rec")
- return
-
-/obj/machinery/computer/med_data/Topic(href, href_list)
- if(..())
- return 1
-
- if (!( data_core.general.Find(src.active1) ))
- src.active1 = null
-
- if (!( data_core.medical.Find(src.active2) ))
- src.active2 = null
-
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (issilicon(usr)))
- usr.set_machine(src)
-
- if (href_list["temp"])
- src.temp = null
-
- if (href_list["scan"])
- if (src.scan)
-
- if(ishuman(usr))
- scan.loc = usr.loc
-
- if(!usr.get_active_held_item())
- usr.put_in_hands(scan)
-
- scan = null
-
- else
- src.scan.loc = src.loc
- src.scan = null
-
- else
- var/obj/item/I = usr.get_active_held_item()
- if (istype(I, /obj/item/card/id))
- usr.drop_item()
- I.loc = src
- src.scan = I
-
- else if (href_list["logout"])
- src.authenticated = null
- src.screen = null
- src.active1 = null
- src.active2 = null
-
- else if (href_list["login"])
-
- if (isAI(usr))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
- src.rank = "AI"
- src.screen = 1
-
- else if (isrobot(usr))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
- var/mob/living/silicon/robot/R = usr
- src.rank = "[R.modtype] [R.braintype]"
- src.screen = 1
-
- else if (istype(src.scan, /obj/item/card/id))
- src.active1 = null
- src.active2 = null
-
- if (src.check_access(src.scan))
- src.authenticated = src.scan.registered_name
- src.rank = src.scan.assignment
- src.screen = 1
-
- if (src.authenticated)
-
- if(href_list["screen"])
- src.screen = text2num(href_list["screen"])
- if(src.screen < 1)
- src.screen = 1
-
- src.active1 = null
- src.active2 = null
-
- if (href_list["del_all"])
- src.temp = text("Are you sure you wish to delete all records? \n\tYes \n\tNo ", src, src)
-
- if (href_list["del_all2"])
- for(var/datum/data/record/R in data_core.medical)
- //R = null
- qdel(R)
- //Foreach goto(494)
- src.temp = "All records deleted."
-
- if (href_list["field"])
- var/a1 = src.active1
- var/a2 = src.active2
- switch(href_list["field"])
- if("fingerprint")
- if (istype(src.active1, /datum/data/record))
- var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active1 != a1))
- return
- src.active1.fields["fingerprint"] = t1
- if("sex")
- if (istype(src.active1, /datum/data/record))
- if (src.active1.fields["sex"] == "Male")
- src.active1.fields["sex"] = "Female"
- else
- src.active1.fields["sex"] = "Male"
- if("age")
- if (istype(src.active1, /datum/data/record))
- var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active1 != a1))
- return
- src.active1.fields["age"] = t1
- if("mi_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["mi_dis"] = t1
- if("mi_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["mi_dis_d"] = t1
- if("ma_dis")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["ma_dis"] = t1
- if("ma_dis_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["ma_dis_d"] = t1
- if("alg")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["alg"] = t1
- if("alg_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["alg_d"] = t1
- if("cdi")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["cdi"] = t1
- if("cdi_d")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["cdi_d"] = t1
- if("notes")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["notes"] = t1
- if("p_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Physical Condition: \n\t*Deceased* \n\t*SSD* \n\tActive \n\tPhysically Unfit \n\tDisabled ", src, src, src, src, src)
- if("m_stat")
- if (istype(src.active1, /datum/data/record))
- src.temp = text("Mental Condition: \n\t*Insane* \n\t*Unstable* \n\t*Watch* \n\tStable ", src, src, src, src)
- if("b_type")
- if (istype(src.active2, /datum/data/record))
- src.temp = text("Blood Type: \n\tA- A+ \n\tB- B+ \n\tAB- AB+ \n\tO- O+ ", src, src, src, src, src, src, src, src)
- if("b_dna")
- if (istype(src.active2, /datum/data/record))
- var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- src.active2.fields["b_dna"] = t1
- else
-
- if (href_list["p_stat"])
- if (src.active1)
- switch(href_list["p_stat"])
- if("deceased")
- src.active1.fields["p_stat"] = "*Deceased*"
- if("ssd")
- src.active1.fields["p_stat"] = "*SSD*"
- if("active")
- src.active1.fields["p_stat"] = "Active"
- if("unfit")
- src.active1.fields["p_stat"] = "Physically Unfit"
- if("disabled")
- src.active1.fields["p_stat"] = "Disabled"
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
-
- if (href_list["m_stat"])
- if (src.active1)
- switch(href_list["m_stat"])
- if("insane")
- src.active1.fields["m_stat"] = "*Insane*"
- if("unstable")
- src.active1.fields["m_stat"] = "*Unstable*"
- if("watch")
- src.active1.fields["m_stat"] = "*Watch*"
- if("stable")
- src.active1.fields["m_stat"] = "Stable"
-
-
- if (href_list["b_type"])
- if (src.active2)
- switch(href_list["b_type"])
- if("an")
- src.active2.fields["b_type"] = "A-"
- if("bn")
- src.active2.fields["b_type"] = "B-"
- if("abn")
- src.active2.fields["b_type"] = "AB-"
- if("on")
- src.active2.fields["b_type"] = "O-"
- if("ap")
- src.active2.fields["b_type"] = "A+"
- if("bp")
- src.active2.fields["b_type"] = "B+"
- if("abp")
- src.active2.fields["b_type"] = "AB+"
- if("op")
- src.active2.fields["b_type"] = "O+"
-
-
- if (href_list["del_r"])
- if (src.active2)
- src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)? \n\tYes \n\tNo ", src, src)
-
- if (href_list["del_r2"])
- if (src.active2)
- //src.active2 = null
- qdel(src.active2)
-
- if (href_list["d_rec"])
- var/datum/data/record/R = locate(href_list["d_rec"])
- var/datum/data/record/M = locate(href_list["d_rec"])
- if (!( data_core.general.Find(R) ))
- src.temp = "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
- else
- //Foreach continue //goto(2540)
- src.active1 = R
- src.active2 = M
- src.screen = 4
-
- if (href_list["new"])
- if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) )))
- var/datum/data/record/R = new /datum/data/record( )
- R.fields["name"] = src.active1.fields["name"]
- R.fields["id"] = src.active1.fields["id"]
- R.name = text("Medical Record #[]", R.fields["id"])
- R.fields["b_type"] = "Unknown"
- R.fields["b_dna"] = "Unknown"
- R.fields["mi_dis"] = "None"
- R.fields["mi_dis_d"] = "No minor disabilities have been declared."
- R.fields["ma_dis"] = "None"
- R.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
- R.fields["alg"] = "None"
- R.fields["alg_d"] = "No allergies have been detected in this patient."
- R.fields["cdi"] = "None"
- R.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
- R.fields["notes"] = "No notes."
- data_core.medical += R
- src.active2 = R
- src.screen = 4
-
- if (href_list["add_c"])
- if (!( istype(src.active2, /datum/data/record) ))
- return
- var/a2 = src.active2
- var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message)
- if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2))
- return
- var/counter = 1
- while(src.active2.fields[text("com_[]", counter)])
- counter++
- src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [CURRENT_SHIP_YEAR] [t1]")
-
- if (href_list["del_c"])
- if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
- src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted "
-
- if (href_list["search"])
- var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text
- if ((!( t1 ) || usr.stat || !( src.authenticated ) || usr.restrained() || ((!in_range(src, usr)) && (!issilicon(usr)))))
- return
- src.active1 = null
- src.active2 = null
- t1 = lowertext(t1)
- for(var/datum/data/record/R in data_core.medical)
- if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"])))
- src.active2 = R
- else
- //Foreach continue //goto(3229)
- if (!( src.active2 ))
- src.temp = text("Could not locate record [].", t1)
- else
- for(var/datum/data/record/E in data_core.general)
- if ((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"]))
- src.active1 = E
- else
- //Foreach continue //goto(3334)
- src.screen = 4
-
- if (href_list["print_p"])
- if (!( src.printing ))
- src.printing = 1
- var/datum/data/record/record1
- var/datum/data/record/record2
- if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
- record1 = active1
- if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
- record2 = active2
- sleep(50)
- var/obj/item/paper/P = new /obj/item/paper( src.loc )
- P.info = "Medical Record "
- if (record1)
- P.info += text("Name: [] ID: [] \nSex: [] \nAge: [] \nFingerprint: [] \nPhysical Status: [] \nMental Status: [] ", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"])
- P.name = text("Medical Record ([])", record1.fields["name"])
- else
- P.info += "General Record Lost! "
- P.name = "Medical Record"
- if (record2)
- P.info += 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 ", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"]))
- var/counter = 1
- while(record2.fields[text("com_[]", counter)])
- P.info += text("[] ", record2.fields[text("com_[]", counter)])
- counter++
- else
- P.info += "Medical Record Lost! "
- P.info += ""
- src.printing = null
-
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
-
-/obj/machinery/computer/med_data/emp_act(severity)
- if(stat & (BROKEN|NOPOWER))
- ..(severity)
- return
-
- for(var/datum/data/record/R in data_core.medical)
- if(prob(10/severity))
- switch(rand(1,6))
- if(1)
- R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]"
- if(2)
- R.fields["sex"] = pick("Male", "Female")
- if(3)
- R.fields["age"] = rand(5, 85)
- if(4)
- R.fields["b_type"] = pick("A-", "B-", "AB-", "O-", "A+", "B+", "AB+", "O+")
- if(5)
- R.fields["p_stat"] = pick("*SSD*", "Active", "Physically Unfit", "Disabled")
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
- if(6)
- R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
- continue
-
- else if(prob(1))
- qdel(R)
- continue
-
- ..(severity)
-
-
-/obj/machinery/computer/med_data/laptop
- name = "Medical Laptop"
- desc = "A cheap laptop."
- icon_state = "laptop"
- icon_keyboard = "laptop_key"
- icon_screen = "medlaptop"
- CheckFaceFlag = 0
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
deleted file mode 100644
index 36e2ee0983c..00000000000
--- a/code/game/machinery/computer/security.dm
+++ /dev/null
@@ -1,658 +0,0 @@
-/obj/machinery/computer/secure_data
- name = "security records console"
- desc = "Used to view, edit and maintain security records"
- icon_keyboard = "security_key"
- icon_screen = "security"
- light_color = COLOR_LIGHTING_SCI_BRIGHT
- req_one_access = list(access_security)
- circuit = /obj/item/electronics/circuitboard/secure_data
- var/obj/item/card/id/scan
- var/authenticated
- var/rank
- var/screen
- var/datum/data/record/active1
- var/datum/data/record/active2
- var/a_id
- var/temp
- var/printing
- var/can_change_id = 0
- var/list/Perp
- var/tempname
- //Sorting Variables
- var/sortBy = "name"
- var/order = 1 // -1 = Descending - 1 = Ascending
-
-/obj/machinery/computer/secure_data/verb/eject_id()
- set category = "Object"
- set name = "Eject ID Card"
- set src in oview(1)
-
- if(!usr || usr.stat || usr.lying) return
-
- if(scan)
- to_chat(usr, "You remove \the [scan] from \the [src].")
- scan.loc = get_turf(src)
- if(!usr.get_active_held_item() && ishuman(usr))
- usr.put_in_hands(scan)
- scan = null
- else
- to_chat(usr, "There is nothing to remove from the console.")
- return
-
-/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob)
- if(istype(O, /obj/item/card/id) && !scan)
- usr.drop_item()
- O.loc = src
- scan = O
- to_chat(user, "You insert [O].")
- ..()
-
-//Someone needs to break down the dat += into chunks instead of long ass lines.
-/obj/machinery/computer/secure_data/attack_hand(mob/user)
- if(..())
- return
- nano_ui_interact(user)
-
-/obj/machinery/computer/secure_data/nano_ui_interact(user)
- if (src.z > 6)
- to_chat(user, "[span_warning("Unable to establish a connection:")] You're too far away from the station!")
- return
-
- var/dat
- if (temp)
- dat = text("[] Clear Screen ", temp, src)
- else
- dat = text("Confirm Identity: [] ", src, (scan ? text("[]", scan.name) : "----------"))
- if (authenticated)
- switch(screen)
- if(1)
- dat += {""}
- dat += text("Search Records ", src)
- dat += text("New Record ", src)
- dat += {"
-
-
-
-
-Name
-ID
-Rank
-Fingerprints
-Criminal Status
- "}
- if(!isnull(data_core.general))
- for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order))
- var/crimstat = ""
- for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
- crimstat = E.fields["criminal"]
- var/background
- switch(crimstat)
- if("*Arrest*")
- background = "'background-color:#DC143C;'"
- if("Incarcerated")
- background = "'background-color:#CD853F;'"
- if("Parolled")
- background = "'background-color:#CD853F;'"
- if("Released")
- background = "'background-color:#3BB9FF;'"
- if("None")
- background = "'background-color:#00FF7F;'"
- if("")
- background = "'background-color:#FFFFFF;'"
- crimstat = "No Record."
- dat += text("[] ", background, src, R, R.fields["name"])
- dat += text("[] ", R.fields["id"])
- dat += text("[] ", R.fields["rank"])
- dat += text("[] ", R.fields["fingerprint"])
- dat += text("[] ", crimstat)
- dat += "
"
- dat += text("Record Maintenance ", src)
- dat += text("{Log Out} ",src)
- if(2)
- dat += "Records Maintenance "
- dat += "Delete All Records Back "
- if(3)
- dat += "Security Record "
- if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
- user << browse_rsc(active1.fields["photo_front"], "front.png")
- user << browse_rsc(active1.fields["photo_side"], "side.png")
- dat += {"
-
- "}
- else
- dat += "General Record Lost! "
- if ((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
- dat += " \nSecurity Data \nCriminal Status: \
- [active2.fields["criminal"]] \n \n \
- Minor Crimes: [active2.fields["mi_crim"]] \n \
- Details: [active2.fields["mi_crim_d"]] \n \n\
- Major Crimes: [active2.fields["ma_crim"]] \n \
- Details: [active2.fields["ma_crim_d"]] \n \n \
- Important Notes: \n\t[decode(active2.fields["notes"])] \n \n\
- Comments/Log "
- var/counter = 1
- while(active2.fields["com_[counter]"])
- dat += text("[]Delete Entry ", active2.fields["com_[counter]"], src, counter)
- counter++
- dat += "Add Entry "
- dat += "Delete Record (Security Only) "
- else
- dat += "Security Record Lost! "
- dat += "New Security Record "
- dat += "Delete Record (ALL) \
- Print Record \
- Print Wanted Poster \
- Back "
- if(4)
- if(!Perp.len)
- dat += text("ERROR. String could not be located.Back ", src)
- else
- dat += {"
-
- Search Results for '[tempname]':
-
-
- Name
- ID
- Rank
- Fingerprints
- Criminal Status
-
- "}
- for(var/i=1, i<=Perp.len, i += 2)
- var/crimstat = ""
- var/datum/data/record/R = Perp[i]
- if(istype(Perp[i+1],/datum/data/record/))
- var/datum/data/record/E = Perp[i+1]
- crimstat = E.fields["criminal"]
- var/background
- switch(crimstat)
- if("*Arrest*")
- background = "'background-color:#DC143C;'"
- if("Incarcerated")
- background = "'background-color:#CD853F;'"
- if("Parolled")
- background = "'background-color:#CD853F;'"
- if("Released")
- background = "'background-color:#3BB9FF;'"
- if("None")
- background = "'background-color:#00FF7F;'"
- if("")
- background = "'background-color:#FFFFFF;'"
- crimstat = "No Record."
- dat += text("[] ", background, src, R, R.fields["name"])
- dat += text("[] ", R.fields["id"])
- dat += text("[] ", R.fields["rank"])
- dat += text("[] ", R.fields["fingerprint"])
- dat += text("[] ", crimstat)
- dat += "
"
- dat += text("Return to index. ", src)
- else
- else
- dat += text("{Log In} ", src)
- user << browse(HTML_SKELETON_TITLE("Security Records", "[dat] "), "window=secure_rec;size=600x400")
- onclose(user, "secure_rec")
- return
-
-/*Revised /N
-I can't be bothered to look more of the actual code outside of switch but that probably needs revising too.
-What a mess.*/
-/obj/machinery/computer/secure_data/Topic(href, href_list)
- if(..())
- return 1
- if (!( data_core.general.Find(active1) ))
- active1 = null
- if (!( data_core.security.Find(active2) ))
- active2 = null
- if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (issilicon(usr)))
- usr.set_machine(src)
- switch(href_list["choice"])
-// SORTING!
- if("Sorting")
- // Reverse the order if clicked twice
- if(sortBy == href_list["sort"])
- if(order == 1)
- order = -1
- else
- order = 1
- else
- // New sorting order!
- sortBy = href_list["sort"]
- order = initial(order)
-//BASIC FUNCTIONS
- if("Clear Screen")
- temp = null
-
- if ("Return")
- screen = 1
- active1 = null
- active2 = null
-
- if("Confirm Identity")
- if (scan)
- if(ishuman(usr) && !usr.get_active_held_item())
- usr.put_in_hands(scan)
- else
- scan.loc = get_turf(src)
- scan = null
- else
- var/obj/item/I = usr.get_active_held_item()
- if (istype(I, /obj/item/card/id) && usr.unEquip(I))
- I.loc = src
- scan = I
-
- if("Log Out")
- authenticated = null
- screen = null
- active1 = null
- active2 = null
-
- if("Log In")
- if (isAI(usr))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
- src.rank = "AI"
- src.screen = 1
- else if (isrobot(usr))
- src.active1 = null
- src.active2 = null
- src.authenticated = usr.name
- var/mob/living/silicon/robot/R = usr
- src.rank = "[R.modtype] [R.braintype]"
- src.screen = 1
- else if (istype(scan, /obj/item/card/id))
- active1 = null
- active2 = null
- if(check_access(scan))
- authenticated = scan.registered_name
- rank = scan.assignment
- screen = 1
-//RECORD FUNCTIONS
- if("Search Records")
- var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text
- if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr)))
- return
- Perp = new/list()
- t1 = lowertext(t1)
- var/list/components = splittext(t1, " ")
- if(components.len > 5)
- return //Lets not let them search too greedily.
- for(var/datum/data/record/R in data_core.general)
- var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"]
- for(var/i = 1, i<=components.len, i++)
- if(findtext(temptext,components[i]))
- var/prelist = new/list(2)
- prelist[1] = R
- Perp += prelist
- for(var/i = 1, i<=Perp.len, i+=2)
- for(var/datum/data/record/E in data_core.security)
- var/datum/data/record/R = Perp[i]
- if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"]))
- Perp[i+1] = E
- tempname = t1
- screen = 4
-
- if("Record Maintenance")
- screen = 2
- active1 = null
- active2 = null
-
- if ("Browse Record")
- var/datum/data/record/R = locate(href_list["d_rec"])
- var/S = locate(href_list["d_rec"])
- if (!( data_core.general.Find(R) ))
- temp = "Record Not Found!"
- else
- for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
- S = E
- active1 = R
- active2 = S
- screen = 3
-
-/* if ("Search Fingerprints")
- var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text
- if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!issilicon(usr))))
- return
- active1 = null
- active2 = null
- t1 = lowertext(t1)
- for(var/datum/data/record/R in data_core.general)
- if (lowertext(R.fields["fingerprint"]) == t1)
- active1 = R
- if (!( active1 ))
- temp = text("Could not locate record [].", t1)
- else
- for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"]))
- active2 = E
- screen = 3 */
-
- if ("Print Record")
- if (!( printing ))
- printing = 1
- var/datum/data/record/record1 = null
- var/datum/data/record/record2 = null
- if ((istype(active1, /datum/data/record) && data_core.general.Find(active1)))
- record1 = active1
- if ((istype(active2, /datum/data/record) && data_core.security.Find(active2)))
- record2 = active2
- sleep(50)
- var/obj/item/paper/P = new /obj/item/paper( loc )
- P.info = "Security Record "
- if (record1)
- P.info += {"
- Name: [record1.fields["name"]] ID: [record1.fields["id"]]
- Sex: [record1.fields["sex"]]
- Age: [record1.fields["age"]]
- Fingerprint: [record1.fields["fingerprint"]]
- Physical Status: [record1.fields["p_stat"]]
- Mental Status: [record1.fields["m_stat"]]
- "}
- P.name = "Security Record ([record1.fields["name"]])"
- else
- P.info += "General Record Lost! "
- P.name = "Security Record"
- if (record2)
- P.info += {"
- Security Data
- Criminal Status: [record2.fields["criminal"]]
- Minor Crimes: [record2.fields["mi_crim"]]
- Details: [record2.fields["mi_crim_d"]]
- Major Crimes: [record2.fields["ma_crim"]]
- Details: [record2.fields["ma_crim_d"]]
- Important Notes:
- \t[decode(record2.fields["notes"])]
- Comments/Log
- "}
- var/counter = 1
- while(record2.fields[text("com_[]", counter)])
- P.info += text("[] ", record2.fields[text("com_[]", counter)])
- counter++
- else
- P.info += "Security Record Lost! "
- P.info += ""
- printing = null
- updateUsrDialog()
-
- if ("Print Poster")
- if(!printing)
- var/wanted_name = sanitizeName(input("Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"]) as text, MAX_NAME_LEN, 1)
- if(wanted_name)
- var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately."
- var/major_crimes = active2.fields["ma_crim"]
- var/minor_crimes = active2.fields["mi_crim"]
- default_description += "\n[wanted_name] is wanted for the following crimes:\n"
- default_description += "\nMinor Crimes:\n[minor_crimes]\n[active2.fields["mi_crim_d"]]\n"
- default_description += "\nMajor Crimes:\n[major_crimes]\n[active2.fields["ma_crim_d"]]\n"
- printing = 1
- spawn(30)
- playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1)
- if((istype(active1, /datum/data/record) && data_core.general.Find(active1)))//make sure the record still exists.
- new /obj/item/contraband/poster/wanted(src.loc, active1.fields["photo_front"], wanted_name, default_description)
- printing = 0
-//RECORD DELETE
- if ("Delete All Records")
- temp = ""
- temp += "Are you sure you wish to delete all Security records? "
- temp += "Yes "
- temp += "No "
-
- if ("Purge All Records")
- for(var/datum/data/record/R in data_core.security)
- qdel(R)
- temp = "All Security records deleted."
-
- if ("Add Entry")
- if (!( istype(active2, /datum/data/record) ))
- return
- var/a2 = active2
- var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message)
- if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || active2 != a2))
- return
- var/counter = 1
- while(active2.fields[text("com_[]", counter)])
- counter++
- active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD", NO_TIMEZONE)] [stationtime2text()], [CURRENT_SHIP_YEAR] [t1]")
-
- if ("Delete Record (ALL)")
- if (active1)
- temp = "Are you sure you wish to delete the record (ALL)? "
- temp += "Yes "
- temp += "No "
-
- if ("Delete Record (Security)")
- if (active2)
- temp = "Are you sure you wish to delete the record (Security Portion Only)? "
- temp += "Yes "
- temp += "No "
-
- if ("Delete Entry")
- if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
- active2.fields[text("com_[]", href_list["del_c"])] = "Deleted "
-//RECORD CREATE
- if ("New Record (Security)")
- if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) )))
- active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"])
- screen = 3
-
- if ("New Record (General)")
- active1 = data_core.CreateGeneralRecord()
- active2 = null
-
-//FIELD FUNCTIONS
- if ("Edit")
- if (is_not_allowed(usr))
- return
- var/a1 = active1
- var/a2 = active2
- switch(href_list["field"])
- if("name")
- if (istype(active1, /datum/data/record))
- var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text)
- if (!t1 || active1 != a1)
- return
- active1.fields["name"] = t1
- if("id")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text)
- if (!t1 || active1 != a1)
- return
- active1.fields["id"] = t1
- if("fingerprint")
- if (istype(active1, /datum/data/record))
- var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text)
- if (!t1 || active1 != a1)
- return
- active1.fields["fingerprint"] = t1
- if("sex")
- if (istype(active1, /datum/data/record))
- if (active1.fields["sex"] == "Male")
- active1.fields["sex"] = "Female"
- else
- active1.fields["sex"] = "Male"
- if("age")
- if (istype(active1, /datum/data/record))
- var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num
- if (!t1 || active1 != a1)
- return
- active1.fields["age"] = t1
- if("mi_crim")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text)
- if (!t1 || active2 != a2)
- return
- active2.fields["mi_crim"] = t1
- if("mi_crim_d")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message)
- if (!t1 || active2 != a2)
- return
- active2.fields["mi_crim_d"] = t1
- if("ma_crim")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text)
- if (!t1 || active2 != a2)
- return
- active2.fields["ma_crim"] = t1
- if("ma_crim_d")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message)
- if (!t1 || active2 != a2)
- return
- active2.fields["ma_crim_d"] = t1
- if("notes")
- if (istype(active2, /datum/data/record))
- var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0)
- if (!t1 || active2 != a2)
- return
- active2.fields["notes"] = t1
- if("criminal")
- if (istype(active2, /datum/data/record))
- temp = "Criminal Status: "
- temp += ""
- if("rank")
- var/list/L = list( "First Officer", "Captain", "AI" )
- //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N
- if ((istype(active1, /datum/data/record) && L.Find(rank)))
- temp = "Rank: "
- temp += ""
- for(var/rank in GLOB.joblist)
- temp += "[rank] "
- temp += " "
- else
- alert(usr, "You do not have the required rank to do this!")
- if("species")
- if (istype(active1, /datum/data/record))
- var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message)
- if (!t1 || active1 != a1)
- return
- active1.fields["species"] = t1
- if("photo front")
- var/icon/photo = get_photo(usr)
- if(photo)
- active1.fields["photo_front"] = photo
- if("photo side")
- var/icon/photo = get_photo(usr)
- if(photo)
- active1.fields["photo_side"] = photo
-
-
-//TEMPORARY MENU FUNCTIONS
- else//To properly clear as per clear screen.
- temp=null
- switch(href_list["choice"])
- if ("Change Rank")
- if (active1)
- active1.fields["rank"] = href_list["rank"]
- if(href_list["rank"] in GLOB.joblist)
- active1.fields["real_rank"] = href_list["real_rank"]
-
- if ("Change Criminal Status")
- if (active2)
- for(var/mob/living/carbon/human/H in GLOB.player_list)
- BITSET(H.hud_updateflag, WANTED_HUD)
- switch(href_list["criminal2"])
- if("none")
- active2.fields["criminal"] = "None"
- if("arrest")
- active2.fields["criminal"] = "*Arrest*"
- if("incarcerated")
- active2.fields["criminal"] = "Incarcerated"
- if("parolled")
- active2.fields["criminal"] = "Parolled"
- if("released")
- active2.fields["criminal"] = "Released"
-
- if ("Delete Record (Security) Execute")
- if (active2)
- qdel(active2)
-
- if ("Delete Record (ALL) Execute")
- if (active1)
- for(var/datum/data/record/R in data_core.medical)
- if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"]))
- qdel(R)
- else
- qdel(active1)
- if (active2)
- qdel(active2)
- else
- temp = "This function does not appear to be working at the moment. Our apologies."
-
- add_fingerprint(usr)
- updateUsrDialog()
- return
-
-/obj/machinery/computer/secure_data/proc/is_not_allowed(mob/user)
- return !src.authenticated || user.stat || user.restrained() || (!in_range(src, user) && (!issilicon(user)))
-
-/obj/machinery/computer/secure_data/proc/get_photo(mob/user)
- if(istype(user.get_active_held_item(), /obj/item/photo))
- var/obj/item/photo/photo = user.get_active_held_item()
- return photo.img
- if(issilicon(user))
- var/mob/living/silicon/tempAI = usr
- var/obj/item/photo/selection = tempAI.GetPicture()
- if (selection)
- return selection.img
-
-/obj/machinery/computer/secure_data/emp_act(severity)
- if(stat & (BROKEN|NOPOWER))
- ..(severity)
- return
-
- for(var/datum/data/record/R in data_core.security)
- if(prob(10/severity))
- switch(rand(1,6))
- if(1)
- R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]"
- if(2)
- R.fields["sex"] = pick("Male", "Female")
- if(3)
- R.fields["age"] = rand(5, 85)
- if(4)
- R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Released")
- if(5)
- R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit")
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
- if(6)
- R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable")
- continue
-
- else if(prob(1))
- qdel(R)
- continue
-
- ..(severity)
-
-/obj/machinery/computer/secure_data/detective_computer
- icon = 'icons/obj/computer.dmi'
- icon_state = "messyfiles"
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 8b457cc5402..58e06db8b24 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -241,9 +241,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
var/obj/effect/overlay/hologram = new(T)//Spawn a blank effect at the location.
if(caller_id)
var/icon/tempicon = new
- for(var/datum/data/record/t in data_core.locked)
- if(t.fields["name"]==caller_id.name)
- tempicon = t.fields["image"]
+ var/datum/computer_file/report/crew_record/t = get_crewmember_record(caller_id.name)
+ tempicon = t.photo_front
hologram.overlays += getHologramIcon(icon(tempicon)) // Add the callers image as an overlay to keep coloration!
else
hologram.overlays += A.holo_icon // Add the AI's configured holo Icon
diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm
index 677a0888c4c..e6c3c13efd6 100644
--- a/code/game/objects/items/devices/uplink.dm
+++ b/code/game/objects/items/devices/uplink.dm
@@ -234,14 +234,14 @@ A list of items and costs is stored under the datum of every game mode, alongsid
nanoui_data["items"] = items
else if(nanoui_menu == 2)
var/permanentData[0]
- for(var/datum/data/record/L in sortRecord(data_core.locked))
- permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"])
+ for(var/datum/computer_file/report/crew_record/L in GLOB.all_crew_records)
+ permanentData[++permanentData.len] = list(Name = L.get_name(), "id" = jointext(L.get_name(), L.get_job()))
nanoui_data["exploit_records"] = permanentData
else if(nanoui_menu == 21)
nanoui_data["exploit_exists"] = 0
- for(var/datum/data/record/L in data_core.locked)
- if(L.fields["id"] == exploit_id)
+ for(var/datum/computer_file/report/crew_record/L in GLOB.all_crew_records)
+ if(jointext(L.get_name(), L.get_job()) == exploit_id) // datacore used name and job to make their IDs, so this would be the same level of specificity as it was in datacore
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/weapons/circuitboards/computer/computer.dm
index 60a702577cd..311da9ff96f 100644
--- a/code/game/objects/items/weapons/circuitboards/computer/computer.dm
+++ b/code/game/objects/items/weapons/circuitboards/computer/computer.dm
@@ -18,9 +18,6 @@
build_path = /obj/machinery/computer/borgupload
origin_tech = list(TECH_DATA = 4)
-/obj/item/electronics/circuitboard/med_data
- name = T_BOARD("medical records console")
- build_path = /obj/machinery/computer/med_data
/obj/item/electronics/circuitboard/communications
name = T_BOARD("command and communications console")
@@ -33,9 +30,6 @@
build_path = /obj/machinery/computer/teleporter
origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 2)
-/obj/item/electronics/circuitboard/secure_data
- name = T_BOARD("security records console")
- build_path = /obj/machinery/computer/secure_data
/obj/item/electronics/circuitboard/atmos_alert
rarity_value = 13.3
diff --git a/code/game/say.dm b/code/game/say.dm
index 1c82ea2f3d7..f9f58f0e0f1 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -40,7 +40,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/virtualspeaker)
if(ishuman(M))
// Humans use their job as seen on the crew manifest. This is so the AI
// can know their job even if they don't carry an ID.
- var/record_rank = find_record(name, "rank")
+ #warn fix this this wont work!
+ var/record_rank = get_crewmember_record(name)
if(record_rank)
job = record_rank
else
diff --git a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm
index 0d7f0d248d7..aa42e71e02f 100644
--- a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm
+++ b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm
@@ -7,6 +7,6 @@
return
var/dat
dat += "Crew Manifest "
- dat += data_core.get_manifest()
+ dat += html_crew_manifest(TRUE)
user << browse(HTML_SKELETON_TITLE("Crew Manifest", dat), "window=manifest;size=370x420;can_close=1")
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index fdf2f4674dd..534fe5c71bf 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -319,23 +319,8 @@ Contractors and the like can also be revived with the previous role mostly intac
var/mob/living/carbon/human/new_character = new()//The mob being spawned.
- var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
- if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- /*Try and locate a record for the person being respawned through data_core.
- This isn't an exact science but it does the trick more often than not.*/
- var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
- for(var/datum/data/record/t in data_core.locked)
- if(t.fields["id"]==id)
- record_found = t//We shall now reference the record.
- break
-
- if(record_found)//If they have a record we can determine a few things.
- new_character.real_name = record_found.fields["name"]
- new_character.gender = record_found.fields["sex"]
- new_character.age = record_found.fields["age"]
- new_character.b_type = record_found.fields["b_type"]
- new_character.dna_trace = record_found.fields["b_dna"]
- new_character.fingers_trace = record_found.fields["fingerprint"]
+ if(G_found.client?.prefs)//If they have a record we can determine a few things.
+ G_found.client?.prefs.copy_to(new_character)
else
new_character.gender = pick(MALE,FEMALE)
var/datum/preferences/A = new()
@@ -376,12 +361,13 @@ Contractors and the like can also be revived with the previous role mostly intac
//Now for special roles and equipment.
SSjob.EquipRank(new_character, new_character.mind.assigned_role)
+ var/datum/computer_file/report/crew_record/record_found = get_crewmember_record(new_character.name)
//Announces the character on all the systems, based on the record.
if(!issilicon(new_character))//If they are not a cyborg/AI.
if(!record_found && !player_is_antag(new_character.mind, only_offstation_roles = 1)) //If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
//Power to the user!
- if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
- data_core.manifest_inject(new_character)
+ if(alert(new_character,"Warning: No record entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
+ CreateModularRecord(new_character)
if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
call(/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role)
diff --git a/code/modules/asset_cache/assets/legacyuiicons.dm b/code/modules/asset_cache/assets/legacyuiicons.dm
new file mode 100644
index 00000000000..5051a76d70a
--- /dev/null
+++ b/code/modules/asset_cache/assets/legacyuiicons.dm
@@ -0,0 +1,5 @@
+/datum/asset/spritesheet/legacyicons
+ name = "oldicons"
+
+/datum/asset/spritesheet/legacyicons/create_spritesheets()
+ InsertAll("", 'icons/ui_icons/dmis/uiicons16.dmi')
diff --git a/code/modules/client/preference_setup/background/03_records.dm b/code/modules/client/preference_setup/background/03_records.dm
index cc694cf9528..54084ff6555 100644
--- a/code/modules/client/preference_setup/background/03_records.dm
+++ b/code/modules/client/preference_setup/background/03_records.dm
@@ -9,15 +9,9 @@
sort_order = 5
/datum/category_item/player_setup_item/background/records/load_character(savefile/S)
- from_file(S["med_record"],pref.med_record)
- from_file(S["sec_record"],pref.sec_record)
- from_file(S["gen_record"],pref.gen_record)
from_file(S["memory"],pref.memory)
-/datum/category_item/player_setup_item/background/records/save_character(savefile/S)
- to_file(S["med_record"],pref.med_record)
- to_file(S["sec_record"],pref.sec_record)
- to_file(S["gen_record"],pref.gen_record)
+/datum/category_item/player_setup_item/background/records/save_character(var/savefile/S)
to_file(S["memory"],pref.memory)
/datum/category_item/player_setup_item/background/records/content(mob/user)
@@ -26,33 +20,30 @@
if(jobban_isbanned(user, "Records"))
. += "[span_danger("You are banned from using character records.")] "
else
- . += "Medical Records: "
- . += "[TextPreview(pref.med_record,40)] "
- . += "Employment Records: "
- . += "[TextPreview(pref.gen_record,40)] "
- . += "Security Records: "
- . += "[TextPreview(pref.sec_record,40)] "
+ if(pref.med_record)
+ . += "Medical Records: "
+ . += "[TextPreview(pref.med_record,40)] "
+ if(pref.gen_record)
+ . += "Employment Records: "
+ . += "[TextPreview(pref.gen_record,40)] "
+ if(pref.sec_record)
+ . += "Security Records: "
+ . += "[TextPreview(pref.sec_record,40)] "
. += "Memory: "
. += "[TextPreview(pref.memory,40)] "
. = jointext(.,null)
/datum/category_item/player_setup_item/background/records/OnTopic(href,list/href_list, mob/user)
if(href_list["set_medical_records"])
- var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.med_record = new_medical
+ input(user,"Read medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null
return TOPIC_REFRESH
else if(href_list["set_general_records"])
- var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.gen_record = new_general
+ input(user,"Read employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null
return TOPIC_REFRESH
else if(href_list["set_security_records"])
- var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.sec_record = sec_medical
+ input(user,"Read security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null
return TOPIC_REFRESH
else if(href_list["set_memory"])
@@ -62,3 +53,82 @@
return TOPIC_REFRESH
. = ..()
+
+/datum/category_item/player_setup_item/background/records/proc/load_record(savefile/S, recordtype)
+ var/recordgiven = S["[recordtype]"]
+ if(S["version"] >= 19)
+ if(!recordgiven || !(recordtype in pref.vars))
+ return FALSE
+
+ if(istype(recordgiven, /datum/storedrecord))
+ pref.vars[recordtype] = recordgiven
+ else
+ if(istext(recordgiven) && (recordtype in pref.vars))
+ pref.vars[recordtype] = recordgiven
+
+
+
+/datum/storedrecord
+
+/datum/storedrecord/proc/transfertocomputer(datum/report_field/tofile)
+ // nobody here.
+/datum/storedrecord/security
+ var/list/crimes = list()
+ var/list/evidence = list()
+ var/list/locations = list()
+
+
+/datum/storedrecord/security/transfertocomputer(datum/report_field/tofile)
+ if(!istype(tofile, /datum/report_field/arraylinkage))
+ return FALSE
+ var/datum/report_field/arraylinkage/toset = tofile
+ toset.arrays = list()
+ toset.arrays["crimes"] = crimes // edit these appropriately on any changes
+ toset.arrays["evidence"] = evidence // don't forget to synch these indexes
+ toset.arrays["locations"] = locations
+
+/datum/storedrecord/security/default // used by default
+ crimes = list("No crimes on record.")
+ evidence = list("N/A.")
+ locations = list("N/A.")
+
+
+/datum/storedrecord/medical
+ var/list/prosthetics = list()
+ var/list/wounds = list()
+ var/list/bodystate = list()
+ var/list/chemhistory = list()
+ var/list/psychological = list()
+
+
+/datum/storedrecord/medical/transfertocomputer(datum/report_field/tofile)
+ if(!istype(tofile, /datum/report_field/arrayclump))
+ return FALSE
+ var/datum/report_field/arrayclump/toset = tofile
+ var/list/tochange = toset.value
+ tochange["prosthetics"] = prosthetics // change these appropriately as well
+ tochange["wounds"] = wounds // but as an arrayclump, they don't need synchronized indexing
+ tochange["Body state"] = bodystate
+ tochange["chemhistory"] = chemhistory
+ tochange["psychological"] = psychological
+
+
+/datum/storedrecord/medical/default // used by default
+ prosthetics = list("No prosthetics on record.")
+ wounds = list("No wounds on record.")
+ bodystate = list("Alive at time of writing.")
+ chemhistory = list("Chemical record is clean.")
+ psychological = list("No psychological profiling has been done at time of writing.")
+
+
+/datum/storedrecord/general
+ var/background // background is defined by fates
+ var/origin // origin is defined by origin
+
+
+
+
+/datum/storedrecord/general/default // used by default
+ background = list("Unremarkable.")
+ origin = list("Origin unknown.")
+
diff --git a/code/modules/client/preference_setup/general/05_records.dm b/code/modules/client/preference_setup/general/05_records.dm
deleted file mode 100644
index 5a246b16f99..00000000000
--- a/code/modules/client/preference_setup/general/05_records.dm
+++ /dev/null
@@ -1,64 +0,0 @@
-/datum/preferences
- var/med_record = ""
- var/sec_record = ""
- var/gen_record = ""
- var/memory = ""
-
-/datum/category_item/player_setup_item/physical/records
- name = "Records"
- sort_order = 5
-
-/datum/category_item/player_setup_item/physical/records/load_character(savefile/S)
- from_file(S["med_record"],pref.med_record)
- from_file(S["sec_record"],pref.sec_record)
- from_file(S["gen_record"],pref.gen_record)
- from_file(S["memory"],pref.memory)
-
-/datum/category_item/player_setup_item/physical/records/save_character(savefile/S)
- to_file(S["med_record"],pref.med_record)
- to_file(S["sec_record"],pref.sec_record)
- to_file(S["gen_record"],pref.gen_record)
- to_file(S["memory"],pref.memory)
-
-/datum/category_item/player_setup_item/physical/records/content(mob/user)
- . = list()
- . += "Records : "
- if(jobban_isbanned(user, "Records"))
- . += "[span_danger("You are banned from using character records.")] "
- else
- . += "Medical Records: "
- . += "[TextPreview(pref.med_record,40)] "
- . += "Employment Records: "
- . += "[TextPreview(pref.gen_record,40)] "
- . += "Security Records: "
- . += "[TextPreview(pref.sec_record,40)] "
- . += "Memory: "
- . += "[TextPreview(pref.memory,40)] "
- . = jointext(.,null)
-
-/datum/category_item/player_setup_item/physical/records/OnTopic(href,list/href_list, mob/user)
- if(href_list["set_medical_records"])
- var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.med_record = new_medical
- return TOPIC_REFRESH
-
- else if(href_list["set_general_records"])
- var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.gen_record = new_general
- return TOPIC_REFRESH
-
- else if(href_list["set_security_records"])
- var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
- pref.sec_record = sec_medical
- return TOPIC_REFRESH
-
- else if(href_list["set_memory"])
- var/memes = sanitize(input(user,"Enter memorized information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.memory)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
- if(!isnull(memes) && CanUseTopic(user))
- pref.memory = memes
- return TOPIC_REFRESH
-
- . = ..()
diff --git a/code/modules/client/preference_setup/loadout/lists/accessories.dm b/code/modules/client/preference_setup/loadout/lists/accessories.dm
index 8ef7c68fba2..939ae4b7dae 100644
--- a/code/modules/client/preference_setup/loadout/lists/accessories.dm
+++ b/code/modules/client/preference_setup/loadout/lists/accessories.dm
@@ -43,7 +43,7 @@
/datum/gear/accessory/guild
display_name = "armband, Aster's Guild"
path = /obj/item/clothing/accessory/armband/cargo
- allowed_roles = list(JOBS_CARGO)
+ allowed_roles = list(JOBS_GUILD)
/datum/gear/accessory/engineering
display_name = "armband, Technomancer League"
diff --git a/code/modules/client/preference_setup/loadout/lists/suits.dm b/code/modules/client/preference_setup/loadout/lists/suits.dm
index aae61f2a909..2915bdfa18f 100644
--- a/code/modules/client/preference_setup/loadout/lists/suits.dm
+++ b/code/modules/client/preference_setup/loadout/lists/suits.dm
@@ -137,10 +137,10 @@
/datum/gear/suit/guild/black
display_name = "black guild coat"
path = /obj/item/clothing/suit/storage/cargo_jacket/black
- allowed_roles = list(JOBS_CARGO)
+ allowed_roles = list(JOBS_GUILD)
/datum/gear/suit/guild/black/old
display_name = "old black guild coat"
path = /obj/item/clothing/suit/storage/cargo_jacket/black/old
- allowed_roles = list(JOBS_CARGO)
+ allowed_roles = list(JOBS_GUILD)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index eb54efa9128..30422fa437d 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -239,10 +239,7 @@
for(var/lang in alternate_languages)
character.add_language(lang)
-
- character.med_record = med_record
- character.sec_record = sec_record
- character.gen_record = gen_record
+
character.exploit_record = exploit_record
if(!character.isSynthetic())
character.nutrition = rand(250, 450)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index d7d82c168db..3002912be54 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -1,5 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
-#define SAVEFILE_VERSION_MAX 18
+#define SAVEFILE_VERSION_MAX 19
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey) return
diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm
index dbf3eeaa6a2..d0a84e987e6 100644
--- a/code/modules/economy/Accounts.dm
+++ b/code/modules/economy/Accounts.dm
@@ -37,8 +37,12 @@
return owner_name
//Attempts to return the associated data record for this account
+// expensive to run, store the result from this.
/datum/money_account/proc/get_record()
- return find_general_record("pay_account", account_number)
+ for(var/datum/computer_file/report/crew_record/CR in GLOB.all_crew_records)
+ var/accountnum = CR.get_account()
+ if(account_number == accountnum)
+ return CR
/datum/transaction
var/target_name = ""
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index d295a3712f3..c3fe3de3adc 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -118,9 +118,8 @@
var/mob/living/carbon/human/H = speaker
if(H.voice)
speaker_name = H.voice
- for(var/datum/data/record/G in data_core.general)
- if(G.fields["name"] == speaker_name)
- return H.rank_prefix_name(speaker_name)
+ if(get_crewmember_record(speaker_name))
+ return H.rank_prefix_name(speaker_name)
return voice_name ? voice_name : speaker_name
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 3f1a9e16042..8bc4de7c34f 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -303,9 +303,10 @@
if(perpname)
var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname)
criminal = R ? R.get_criminalStatus() : "None"
- msg += "\n"
- msg += "Criminal status: \[[criminal]\] \n"
- msg += "Security records: \[View\] \[Add comment\] \n"
+
+ msg += "Criminal status: \[[criminal]\] \n"
+ msg += {"Security records: \[View\] \[View Brief\]
+ \[Add Note\] \n"}
if(hasHUD(user, "medical"))
var/perpname = "wot"
@@ -317,16 +318,11 @@
perpname = id_card.registered_name
else
perpname = src.name
+ var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname)
+ medical = E.get_status()
- for (var/datum/data/record/E in data_core.general)
- if (E.fields["name"] == perpname)
- for (var/datum/data/record/R in data_core.general)
- if (R.fields["id"] == E.fields["id"])
- medical = R.fields["p_stat"]
-
- msg += "\n"
msg += "Physical status: \[[medical]\] \n"
- msg += "Medical records: \[View\] \[Add comment\] \n"
+ msg += "Medical records: \[View\] \n"
var/obj/item/clothing/under/U = w_uniform
if(U && istype(U) && U.sensor_mode >= 2)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 42f79d430e8..c44d9367e7f 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -429,21 +429,20 @@ var/list/rank_prefix = list(\
if(perpname)
var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname)
if(R)
+ modified = TRUE
var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.get_criminalStatus()) in GLOB.security_statuses + "Cancel"
- if(hasHUD(usr, "security"))
- if(setcriminal != "Cancel")
- R.set_criminalStatus(setcriminal)
- modified = TRUE
- BITSET(hud_updateflag, WANTED_HUD)
- if(ishuman(usr))
- var/mob/living/carbon/human/U = usr
- U.handle_regular_hud_updates()
- if(isrobot(usr))
- var/mob/living/silicon/robot/U = usr
- U.handle_regular_hud_updates()
+ if(setcriminal != "Cancel")
+ R.set_criminalStatus(setcriminal)
+ BITSET(hud_updateflag, WANTED_HUD)
+ if(ishuman(usr))
+ var/mob/living/carbon/human/U = usr
+ U.handle_regular_hud_updates()
+ if(isrobot(usr))
+ var/mob/living/silicon/robot/U = usr
+ U.handle_regular_hud_updates()
if(!modified)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
+ to_chat(usr, span_red("Unable to locate a criminal record for this person."))
if(href_list["secrecord"])
if(hasHUD(usr,"security"))
@@ -456,52 +455,50 @@ var/list/rank_prefix = list(\
else
perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.security)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"security"))
- to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]")
- to_chat(usr, "Minor Crimes: [R.fields["mi_crim"]]")
- to_chat(usr, "Details: [R.fields["mi_crim_d"]]")
- to_chat(usr, "Major Crimes: [R.fields["ma_crim"]]")
- to_chat(usr, "Details: [R.fields["ma_crim_d"]]")
- to_chat(usr, "Notes: [R.fields["notes"]]")
- to_chat(usr, "\[View Comment Log\] ")
- read = 1
+ var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname)
+ if(CR)
+ to_chat(usr, "Name: [CR.get_name()] Criminal Status: [CR.get_criminalStatus()]")
+ var/datum/report_field/array/tofetch = CR.get_linkage_secNotes()
+ var/list/Briefing = tofetch.value_list
+ if(Briefing.len > 0)
+ var/list/combined = list()
+ for(var/iterator = min(Briefing.len-1, 3), iterator > -1, iterator -= 1)
+ combined.Add(Briefing[Briefing.len - iterator])
+ to_chat(usr, "Briefing latest: "+combined.Join(", "))
+ to_chat(usr, "\[Add to Brief\] ")
+ to_chat(usr, "\[View Full Brief\] ")
+ read = 1
if(!read)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
+ to_chat(usr, span_red("Unable to locate a criminal record for this person."))
- if(href_list["secrecordComment"])
+ if(href_list["viewbrief"])
if(hasHUD(usr,"security"))
var/perpname = "wot"
- var/read = 0
- var/obj/item/card/id/id = GetIdCard()
- if(istype(id))
- perpname = id.registered_name
+ if(wear_id)
+ var/obj/item/card/id/id
+ if(istype(wear_id, /obj/item/modular_computer/pda))
+ id = wear_id.GetIdCard()
+ if(!id)
+ id = get_idcard()
+ if(id)
+ perpname = id.registered_name
else
perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.security)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"security"))
- read = 1
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- to_chat(usr, text("[]", R.fields[text("com_[]", counter)]))
- counter++
- if(counter == 1)
- to_chat(usr, "No comment found")
- to_chat(usr, "\[Add comment\] ")
-
- if(!read)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
+ var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname)
+ if(!E)
+ to_chat(usr, span_danger("Unable to locate a record for this person."))
+ return
+ var/datum/report_field/array/tofetch = E.get_linkage_secNotes()
+ var/list/Briefing = tofetch.value_list
+ if(Briefing.len > 0)
+ to_chat(usr, span_notice("Brief: " + Briefing.Join(", ")))
+ else
+ to_chat(usr, span_notice("[perpname] does not have a brief."))
- if(href_list["secrecordadd"])
+ if(href_list["secnoteadd"])
if(hasHUD(usr,"security"))
var/perpname = "wot"
if(wear_id)
@@ -510,32 +507,27 @@ var/list/rank_prefix = list(\
id = wear_id.GetIdCard()
if(!id)
id = get_idcard()
- if(id)
- perpname = id.registered_name
+ if(id)
+ perpname = id.registered_name
else
perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.security)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"security"))
- var/t1 = sanitize(input("Add Comment:", "Sec. records", null, null) as message)
- if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) )
- return
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- counter++
- if(ishuman(usr))
- var/mob/living/carbon/human/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR] [t1]")
- if(isrobot(usr))
- var/mob/living/silicon/robot/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR] [t1]")
+
+ var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname)
+ if(!E)
+ to_chat(usr, span_warning("Record for [perpname] not found!"))
+ return
+ var/t1 = sanitize(input("Add to Brief:", "Sec. records", null, null) as text)
+ if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) )
+ return
+
+ var/datum/report_field/array/recordnote = E.get_linkage_secNotes()
+
+ if(recordnote)
+ recordnote.add_value(t1)
if(href_list["medical"])
if(hasHUD(usr,"medical"))
var/perpname = "wot"
- var/modified = 0
var/obj/item/card/id/id = GetIdCard()
if(istype(id))
@@ -543,126 +535,49 @@ var/list/rank_prefix = list(\
else
perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.general)
- if(R.fields["id"] == E.fields["id"])
-
- var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*SSD*", "*Deceased*", "Physically Unfit", "Active", "Disabled", "Cancel")
-
- if(hasHUD(usr,"medical"))
- if(setmedical != "Cancel")
- R.fields["p_stat"] = setmedical
- modified = 1
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
+ var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname)
+ if(E)
+ var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", E.get_status()) in GLOB.physical_statuses
- spawn()
- if(ishuman(usr))
- var/mob/living/carbon/human/U = usr
- U.handle_regular_hud_updates()
- if(isrobot(usr))
- var/mob/living/silicon/robot/U = usr
- U.handle_regular_hud_updates()
+ if(hasHUD(usr,"medical"))
+ if(setmedical != "Cancel")
+ E.set_status(setmedical)
- if(!modified)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
-
- if(href_list["medrecord"])
- if(hasHUD(usr,"medical"))
- var/perpname = "wot"
- var/read = 0
+ spawn()
+ if(ishuman(usr))
+ var/mob/living/carbon/human/U = usr
+ U.handle_regular_hud_updates()
+ if(isrobot(usr))
+ var/mob/living/silicon/robot/U = usr
+ U.handle_regular_hud_updates()
- if(wear_id)
- var/obj/item/card/id/id
- if(istype(wear_id, /obj/item/modular_computer/pda))
- id = wear_id.GetIdCard()
- if(!id)
- id = get_idcard()
- if(id)
- perpname = id.registered_name
else
- perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.medical)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"medical"))
- to_chat(usr, "Name: [R.fields["name"]] Blood Type: [R.fields["b_type"]]")
- to_chat(usr, "DNA: [R.fields["b_dna"]]")
- to_chat(usr, "Minor Disabilities: [R.fields["mi_dis"]]")
- to_chat(usr, "Details: [R.fields["mi_dis_d"]]")
- to_chat(usr, "Major Disabilities: [R.fields["ma_dis"]]")
- to_chat(usr, "Details: [R.fields["ma_dis_d"]]")
- to_chat(usr, "Notes: [R.fields["notes"]]")
- to_chat(usr, "\[View Comment Log\] ")
- read = 1
-
- if(!read)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
+ to_chat(usr, span_red("Unable to locate a medical record for this person."))
- if(href_list["medrecordComment"])
+ if(href_list["medrecord"])
if(hasHUD(usr,"medical"))
var/perpname = "wot"
var/read = 0
- if(wear_id)
- var/obj/item/card/id/id
- if(istype(wear_id, /obj/item/modular_computer/pda))
- id = wear_id.GetIdCard()
- if(!id)
- id = get_idcard()
- if(id)
- perpname = id.registered_name
+ var/obj/item/card/id/id = GetIdCard()
+ if(istype(id))
+ perpname = id.registered_name
else
perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.medical)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"medical"))
- read = 1
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- to_chat(usr, text("[]", R.fields[text("com_[]", counter)]))
- counter++
- if(counter == 1)
- to_chat(usr, "No comment found")
- to_chat(usr, "\[Add comment\] ")
+ var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname)
+ var/datum/report_field/arrayclump/M = E.get_linkage_medRecord()
+ if(E)
+ to_chat(usr, "Name: [E.get_name()] Blood Type: [E.get_bloodtype()]")
+ to_chat(usr, "DNA: [E.get_dna()]")
+ to_chat(usr, "Prosthetics: [M.value["prosthetics"]]")
+ to_chat(usr, "Recorded Wounds: [M.value["wounds"]]")
+ to_chat(usr, "Autopsy: [M.value["Body state"]]")
+ to_chat(usr, "Psychological Profile: [M.value["psychological"]]")
+ to_chat(usr, "Chemical History: [M.value["chemhistory"]]")
+ read = 1
if(!read)
- to_chat(usr, span_red("Unable to locate a data core entry for this person."))
-
- if(href_list["medrecordadd"])
- if(hasHUD(usr,"medical"))
- var/perpname = "wot"
- if(wear_id)
- var/obj/item/card/id/id
- if(istype(wear_id, /obj/item/modular_computer/pda))
- id = wear_id.GetIdCard()
- if(!id)
- id = get_idcard()
- if(id)
- perpname = id.registered_name
- else
- perpname = src.name
- for(var/datum/data/record/E in data_core.general)
- if(E.fields["name"] == perpname)
- for(var/datum/data/record/R in data_core.medical)
- if(R.fields["id"] == E.fields["id"])
- if(hasHUD(usr,"medical"))
- var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message)
- if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) )
- return
- var/counter = 1
- while(R.fields[text("com_[]", counter)])
- counter++
- if(ishuman(usr))
- var/mob/living/carbon/human/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR] [t1]")
- if(isrobot(usr))
- var/mob/living/silicon/robot/U = usr
- R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR] [t1]")
+ to_chat(usr, span_red("Unable to locate a medical record for this person."))
if(href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 66bba58d9aa..fd29cff4472 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -105,9 +105,6 @@
/// Extra overlays from equipped items
var/list/equipment_overlays = list()
- var/med_record = ""
- var/sec_record = ""
- var/gen_record = ""
var/exploit_record = ""
/// Whether this mob's ability to stand has been affected
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 43434ed760f..1881ffe5887 100755
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -500,17 +500,8 @@ default behaviour is:
// Delete them from datacore.
- if(PDA_Manifest.len)
- PDA_Manifest.Cut()
- for(var/datum/data/record/R in data_core.medical)
- if ((R.fields["name"] == src.real_name))
- qdel(R)
- for(var/datum/data/record/T in data_core.security)
- if ((T.fields["name"] == src.real_name))
- qdel(T)
- for(var/datum/data/record/G in data_core.general)
- if ((G.fields["name"] == src.real_name))
- qdel(G)
+ var/datum/todelete = get_crewmember_record(name)
+ qdel(todelete)
//This should guarantee that ghosts don't spawn.
src.ckey = null
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 6181156b527..b5626805c2a 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -543,8 +543,8 @@ var/list/ai_verbs_default = list(
var/personnel_list[] = list()
- for(var/datum/data/record/t in data_core.locked)//Look in data core locked.
- personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image.
+ for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records)
+ personnel_list["[t.get_name()]: [t.get_job()]"] = t.photo_front//Pull names, rank, and image.
if(personnel_list.len)
input = input("Select a crew member:") as null|anything in personnel_list
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 50c307c0653..f0256ca095e 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -58,12 +58,10 @@
var/medHUD = FALSE // Toggles whether the Medical HUD is active or not
var/medical_cannotfind = 0
- var/datum/data/record/medicalActive1 // Datacore record declarations for record software
- var/datum/data/record/medicalActive2
+ var/datum/data/record/medicalActive // Datacore record declarations for record software
var/security_cannotfind = 0
- var/datum/data/record/securityActive1 // Could probably just combine all these into one
- var/datum/data/record/securityActive2
+ var/datum/data/record/securityActive
var/obj/machinery/door/hackdoor // The airlock being hacked
var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check
@@ -158,11 +156,9 @@
set category = "pAI Commands"
set name = "Reset Records Software"
- securityActive1 = null
- securityActive2 = null
+ securityActive = null
security_cannotfind = 0
- medicalActive1 = null
- medicalActive2 = null
+ medicalActive = null
medical_cannotfind = 0
SSnano.update_uis(src)
to_chat(usr, span_notice("You reset your record-viewing software."))
diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm
index 9bc461a4e0d..ecd75855088 100644
--- a/code/modules/mob/living/silicon/pai/software_modules.dm
+++ b/code/modules/mob/living/silicon/pai/software_modules.dm
@@ -122,21 +122,19 @@
ram_cost = 5
id = "manifest"
toggle = 0
+ var/datum/nano_module/crew_manifest/manifestmodule
+ var/datum/topic_manager/program/mandatorymanager
-/datum/pai_software/crew_manifest/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1)
- data_core.get_manifest_json()
+/datum/pai_software/crew_manifest/New()
+ mandatorymanager = new()
+ manifestmodule = new(src, mandatorymanager)
- var/data[0]
- // This is dumb, but NanoUI breaks if it has no data to send
- data["manifest"] = list("__json_cache" = ManifestJSON)
+/datum/pai_software/crew_manifest/Destroy()
+ . = ..()
+ QDEL_NULL(manifestmodule)
- ui = SSnano.try_update_ui(user, user, id, ui, data, force_open)
- if(!ui)
- // Don't copy-paste this unless you're making a pAI software module!
- ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
+/datum/pai_software/crew_manifest/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=NANOUI_REINITIALIZE)
+ manifestmodule.nano_ui_interact(user, ui, "main", force_open) // transfers applicable vars to manifestmodule
/* Medical Records */
/datum/pai_software/med_records
@@ -147,51 +145,40 @@
/datum/pai_software/med_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1)
var/data[0]
-
var/records[0]
- for(var/datum/data/record/general in sortRecord(data_core.general))
+ for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records)
var/record[0]
- record["name"] = general.fields["name"]
+ record["name"] = general.get_name()
record["ref"] = "\ref[general]"
records[++records.len] = record
data["records"] = records
- var/datum/data/record/G = user.medicalActive1
- var/datum/data/record/M = user.medicalActive2
- data["general"] = G ? G.fields : null
- data["medical"] = M ? M.fields : null
+ var/datum/computer_file/report/crew_record/G = user.securityActive
+ var/datum/report_field/arrayclump/M = G?.get_linkage_medRecord()
+ data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \
+"job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "bloodtype" = G.get_bloodtype()) : null
+ data["prosthetics"] = M ? M.value["prosthetics"] : null
+ data["wounds"] = M ? M.value["wounds"] : null
+ data["Body state"] = M ? M.value["body state"] : null
+ data["chemhistory"] = M ? M.value["chemhistory"] : null
+ data["psychological"] = M ? M.value["psychological"] : null
data["could_not_find"] = user.medical_cannotfind
ui = SSnano.try_update_ui(user, user, id, ui, data, force_open)
- if(!ui)
- // Don't copy-paste this unless you're making a pAI software module!
- ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
/datum/pai_software/med_records/Topic(href, href_list)
var/mob/living/silicon/pai/P = usr
if(!istype(P)) return
if(href_list["select"])
- var/datum/data/record/record = locate(href_list["select"])
- if(record)
- var/datum/data/record/R = record
- var/datum/data/record/M = null
- if (!( data_core.general.Find(R) ))
- P.medical_cannotfind = 1
- else
- P.medical_cannotfind = 0
- 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
- P.medicalActive1 = R
- P.medicalActive2 = M
+ var/datum/computer_file/report/crew_record/record = locate(href_list["select"])
+ if(istype(record))
+ P.medical_cannotfind = 0
+ P.medicalActive = record
else
P.medical_cannotfind = 1
- return 1
+ return TRUE
/* Security records */
/datum/pai_software/sec_records
@@ -202,20 +189,19 @@
/datum/pai_software/sec_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1)
var/data[0]
-
var/records[0]
- for(var/datum/data/record/general in sortRecord(data_core.general))
+ for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records)
var/record[0]
- record["name"] = general.fields["name"]
+ record["name"] = general.get_name()
record["ref"] = "\ref[general]"
records[++records.len] = record
data["records"] = records
- var/datum/data/record/G = user.securityActive1
- var/datum/data/record/S = user.securityActive2
- data["general"] = G ? G.fields : null
- data["security"] = S ? S.fields : null
+ var/datum/computer_file/report/crew_record/G = user.securityActive
+ data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \
+ "job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "criminalStatus" = G.get_criminalStatus(), \
+ "secNotes" = G.get_linkage_secNotes()) : null
data["could_not_find"] = user.security_cannotfind
ui = SSnano.try_update_ui(user, user, id, ui, data, force_open)
@@ -231,26 +217,14 @@
if(!istype(P)) return
if(href_list["select"])
- var/datum/data/record/record = locate(href_list["select"])
- if(record)
- var/datum/data/record/R = record
- var/datum/data/record/S = null
- if (!( data_core.general.Find(R) ))
- P.securityActive1 = null
- P.securityActive2 = null
- P.security_cannotfind = 1
- else
- P.security_cannotfind = 0
- for(var/datum/data/record/E in data_core.security)
- if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
- S = E
- P.securityActive1 = R
- P.securityActive2 = S
+ var/datum/computer_file/report/crew_record/record = locate(href_list["select"])
+ if(istype(record))
+ P.security_cannotfind = 0
+ P.securityActive = record
else
- P.securityActive1 = null
- P.securityActive2 = null
+ P.securityActive = null
P.security_cannotfind = 1
- return 1
+ return TRUE
/* Door Jack */
/datum/pai_software/door_jack
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 70ad56658c0..fc5182f7f9b 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -448,11 +448,11 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
if(id)
perpname = id.registered_name
- var/datum/data/record/R = find_security_record("name", perpname)
- if(check_records && !R)
+ var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname)
+ if(check_records && !CR)
threatcount += 4
- if(check_arrest && R && (R.fields["criminal"] == "*Arrest*"))
+ if(check_arrest && CR && (CR?.get_criminalStatus() == "*Arrest*")) // why is paperwork's folly being translated to electronic format?
threatcount += 4
return threatcount
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index d4f9396b4fe..e47ecf75d29 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -332,7 +332,6 @@
if(SSjob.ShouldCreateRecords(job.title))
if(character.mind.assigned_role != "Robot")
CreateModularRecord(character)
- data_core.manifest_inject(character)
matchmaker.do_matchmaking()
SSticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm
index a60b9c5d019..677cd0dacce 100644
--- a/code/modules/modular_computers/computers/modular_computer/core.dm
+++ b/code/modules/modular_computers/computers/modular_computer/core.dm
@@ -308,6 +308,8 @@
SetName(initial(name))
/obj/item/modular_computer/proc/update_uis()
+ if(active_program && istype(active_program?.nanomodule_path, /datum/nano_module/tgui))
+ return FALSE
if(active_program) //Should we update program ui or computer ui?
SSnano.update_uis(active_program)
if(active_program.NM)
diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
index e9cb4fa6618..6efb8fbc1b9 100644
--- a/code/modules/modular_computers/file_system/program.dm
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -195,7 +195,10 @@
if(ui)
ui.close()
return computer.nano_ui_interact(user)
- if(istype(NM))
+ if(istype(NM, /datum/nano_module/tgui))
+ NM.ui_interact(user)
+ return FALSE
+ else if(istype(NM))
NM.nano_ui_interact(user, ui_key, null, force_open)
return 0
return 1
diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm
index 50a46be6b0e..4e949a6c588 100644
--- a/code/modules/modular_computers/file_system/programs/command/card.dm
+++ b/code/modules/modular_computers/file_system/programs/command/card.dm
@@ -62,7 +62,7 @@
data["security_jobs"] = format_jobs(security_positions)
//data["exploration_jobs"] = format_jobs(exploration_positions)
data["service_jobs"] = format_jobs(civilian_positions)
- data["supply_jobs"] = format_jobs(cargo_positions)
+ data["supply_jobs"] = format_jobs(guild_positions)
data["church_jobs"] = format_jobs(church_positions)
//data["civilian_jobs"] = format_jobs(civilian_positions)
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
diff --git a/code/modules/modular_computers/file_system/programs/generic/records.dm b/code/modules/modular_computers/file_system/programs/generic/records.dm
index 72bb6bdb81a..0cddabd2af0 100644
--- a/code/modules/modular_computers/file_system/programs/generic/records.dm
+++ b/code/modules/modular_computers/file_system/programs/generic/records.dm
@@ -1,3 +1,5 @@
+
+#define NULL_RECORD list("name" = null, "uid" = null, "creator" = null, "file_time" = null, "fields" = null, "access" = null, "access_edit" = null)
/datum/computer_file/program/records
filename = "crewrecords"
filedesc = "Crew Records"
@@ -7,22 +9,22 @@
size = 14
requires_ntnet = TRUE
available_on_ntnet = TRUE
- nanomodule_path = /datum/nano_module/records
+ nanomodule_path = /datum/nano_module/tgui/records
usage_flags = PROGRAM_ALL
-/datum/nano_module/records
+/datum/nano_module/tgui/records
name = "Crew Records"
var/datum/computer_file/report/crew_record/active_record
var/message = null
-/datum/nano_module/records/nano_ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = NANOUI_FOCUS, state = GLOB.default_state)
+/datum/nano_module/tgui/records/ui_data(mob/user)
var/list/data = host.initial_data()
var/list/user_access = get_record_access(user)
data["message"] = message
if(active_record)
- user << browse_rsc(active_record.photo_front, "front_[active_record.uid].png")
- user << browse_rsc(active_record.photo_side, "side_[active_record.uid].png")
+ data["front_pic"] = icon2base64html(active_record.photo_front)
+ data["side_pic"] = icon2base64html(active_record.photo_side)
data["pic_edit"] = check_access(user, access_heads) || check_access(user, access_security)
data += active_record.generate_nano_data(user_access)
else
@@ -38,16 +40,20 @@
data["creation"] = check_access(user, access_heads)
data["dnasearch"] = check_access(user, access_moebius) || check_access(user, access_forensics_lockers)
data["fingersearch"] = check_access(user, access_security)
+ data += NULL_RECORD
+ return data
+#undef NULL_RECORD
+
+
- ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open)
+/datum/nano_module/tgui/records/ui_interact(mob/user, datum/tgui/ui = null)
+ ui = SStgui.try_update_ui(user, src, ui || currentui)
if (!ui)
- ui = new(user, src, ui_key, "crew_records.tmpl", name, 700, 540, state = state)
- ui.auto_update_layout = 1
- ui.set_initial_data(data)
- ui.open()
+ currentui = new(user, src, "CrewRecords", name)
+ currentui.open()
-/datum/nano_module/records/proc/get_record_access(mob/user)
+/datum/nano_module/tgui/records/proc/get_record_access(var/mob/user)
var/list/user_access = using_access || user.GetAccess()
var/obj/item/modular_computer/PC = nano_host()
@@ -57,7 +63,7 @@
return user_access
-/datum/nano_module/records/proc/edit_field(mob/user, field_ID)
+/datum/nano_module/tgui/records/proc/edit_field(var/mob/user, var/field_ID)
var/datum/computer_file/report/crew_record/R = active_record
if(!R)
return
@@ -65,71 +71,72 @@
if(!F)
return
if(!F.verify_access_edit(get_record_access(user)))
- to_chat(user, span_notice("\The [nano_host()] flashes an \"Access Denied\" warning."))
+ to_chat(user, span_notice("The [nano_host()] flashes an \"Access Denied\" warning."))
return
F.ask_value(user)
-/datum/nano_module/records/Topic(href, href_list)
+/datum/nano_module/tgui/records/ui_act(action, params)
if(..())
return 1
- if(href_list["clear_active"])
- active_record = null
- return 1
- if(href_list["clear_message"])
- message = null
- return 1
- if(href_list["set_active"])
- var/ID = text2num(href_list["set_active"])
- for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records)
- if(R.uid == ID)
- active_record = R
- break
- return 1
- if(href_list["new_record"])
- if(!check_access(usr, access_heads))
- to_chat(usr, "Access Denied.")
- return
- active_record = new/datum/computer_file/report/crew_record()
- GLOB.all_crew_records.Add(active_record)
- return 1
- if(href_list["print_active"])
- if(!active_record)
- return
- print_text(record_to_html(active_record, get_record_access(usr)), usr)
- return 1
- if(href_list["search"])
- var/field_name = href_list["search"]
- var/search = sanitize(input("Enter the value for search for.") as null|text)
- if(!search)
+ switch(action)
+
+ if("clear_active")
+ active_record = null
return 1
- for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records)
- var/datum/report_field/field = R.field_from_name(field_name)
- if(lowertext(field.get_value()) == lowertext(search))
- active_record = R
+ if("clear_message")
+ message = null
+ return 1
+ if("set_active")
+ var/ID = text2num(params["set_active"])
+ for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records)
+ if(R.uid == ID)
+ active_record = R
+ break
+ return 1
+ if("new_record")
+ if(!check_access(usr, access_heads))
+ to_chat(usr, "Access Denied.")
+ return
+ active_record = new/datum/computer_file/report/crew_record()
+ GLOB.all_crew_records.Add(active_record)
+ return 1
+ if("print_active")
+ if(!active_record)
+ return
+ print_text(record_to_html(active_record, get_record_access(usr)), usr)
+ return 1
+ if("search")
+ var/field_name = params["search"]
+ var/search = sanitize(input("Enter the value for search for.") as null|text)
+ if(!search)
return 1
- message = "Unable to find record containing '[search]'"
- return 1
+ for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records)
+ var/datum/report_field/field = R.field_from_name(field_name)
+ if(lowertext(field.get_value()) == lowertext(search))
+ active_record = R
+ return 1
+ message = "Unable to find record containing '[search]'"
+ return 1
var/datum/computer_file/report/crew_record/R = active_record
if(!istype(R))
return 1
- if(href_list["edit_photo_front"])
- var/photo = get_photo(usr)
- if(photo && active_record)
- active_record.photo_front = photo
- nano_ui_interact(usr)
- return 1
- if(href_list["edit_photo_side"])
- var/photo = get_photo(usr)
- if(photo && active_record)
- active_record.photo_side = photo
- nano_ui_interact(usr)
- return 1
- if(href_list["edit_field"])
- edit_field(usr, text2num(href_list["edit_field"]))
- return 1
+ switch(action)
+ if("edit_photo_front")
+ var/photo = get_photo(usr)
+ if(photo && active_record)
+ active_record.photo_front = photo
+ return 1
+ if("edit_photo_side")
+ var/photo = get_photo(usr)
+ if(photo && active_record)
+ active_record.photo_side = photo
+ return 1
+ if("edit_field")
+ edit_field(usr, text2num(params["edit_field"]))
+ return 1
-/datum/nano_module/records/proc/get_photo(mob/user)
+/datum/nano_module/tgui/records/proc/get_photo(var/mob/user)
if(istype(user.get_active_held_item(), /obj/item/photo))
var/obj/item/photo/photo = user.get_active_held_item()
return photo.img
diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm
index a158121b5c7..c6fb06b2825 100644
--- a/code/modules/modular_computers/file_system/reports/crew_record.dm
+++ b/code/modules/modular_computers/file_system/reports/crew_record.dm
@@ -53,34 +53,131 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest")
// Medical record
set_bloodtype(H ? H.b_type : "Unset")
- set_medRecord((H && H.med_record && !jobban_isbanned(H.ckey, "Records") ? html_decode(H.med_record) : "No record supplied"))
+ var/datum/preferences/loadedprefs = H?.client?.prefs
+ var/datum/report_field/arrayclump/medRecord = get_linkage_medRecord()
+ if(H)
+ var/list/wounds = list()
+ var/list/prosthetics = list()
+ var/list/scannedlimbs = list()
+ for(var/datum/organ_description/OD in H.species.has_limbs) // default limbs for species
+ if(H.organs_by_name[OD.organ_tag])
+ if(istype(H.organs_by_name[OD.organ_tag], OD.default_type)) // these lists contain abnormalilities, so normalities are skipped.
+ continue
+ else
+ var/obj/item/organ/external/organthing = H.organs_by_name[OD.organ_tag]
+ if(organthing.is_stump())
+ wounds.Add("[organthing.name] instead of [OD.name]")
+ else
+ prosthetics.Add(organthing.name)
+
+ scannedlimbs.Add(organthing)
+ // TODO: add organ checks once FBPs are better coded
+ else
+ wounds.Add("Missing [OD.name]")
+ var/list/addictions = list()
+ for(var/datum/reagent/addicted in H.metabolism_effects.addiction_list)
+ addictions.Add("Observed addicted to [addicted.name]")
+
+ var/bodystate
+ switch(H.stat)
+ if(DEAD)
+ bodystate = list("Dead at time of writing")
+ if(UNCONSCIOUS)
+ if(H.getOxyLoss() > H.species.total_health/2)
+ bodystate = list("Comatose at time of writing")
+ else
+ bodystate = list("Alive at time of writing")
+ if(CONSCIOUS)
+ bodystate = list("Alive at time of writing")
+
+ medRecord.value["wounds"] = wounds.len ? wounds : list("No wounds on record.")
+ medRecord.value["prosthetics"] = prosthetics.len ? prosthetics : list("No prosthetics on record.")
+ medRecord.value["Body state"] = bodystate ? bodystate : list("\[Data Missing\]")
+ medRecord.value["chemhistory"] = addictions.len ? addictions : list("Chemical record is clean.")
+
+ var/list/psychological = list()
+ for(var/datum/perk/profile in H.stats.perks)
+ switch(profile.type)
+ if(PERK_NIHILIST)
+ psychological.Add("Has an empty outlook on life.")
+ if(PERK_MORALIST)
+ psychological.Add("High morale in groups.")
+ if(PERK_DRUG_ADDICT)
+ psychological.Add("Easily addicted, remains addicted indefinitely.")
+ if(PERK_ALCOHOLIC)
+ psychological.Add("Psychologically dependent on alcohol.")
+ if(PERK_REJECTED_GENIUS, PERK_NOBLE)
+ psychological.Add("Mentally destabilized by minor stressing factors.")
+ if(PERK_RAT)
+ psychological.Add("Innately stressed by environments, to some degree.")
+ if(PERK_PAPER_WORM)
+ psychological.Add("Accustomed to over-stress.")
+ if(PERK_OBORIN_SYNDROME)
+ psychological.Add("Innately resilient to mental harm.")
+ if(PERK_LOWBORN, PERK_VAGABOND)
+ psychological |= "Accustomed to bad living conditions."
+ if(PERK_SURVIVOR)
+ psychological.Add("Accustomed to the presence of death.")
+ if(PERK_NEAT)
+ psychological.Add("Accustomed to the presence of grime, and comforted by its removal.")
+ if(PERK_GREEN_THUMB)
+ psychological.Add("Comforted by gardening.")
+ if(PERK_CLUB)
+ psychological.Add("Provides a comfortingly professional presence.")
+ if(PERK_CHAINGUN_SMOKER)
+ psychological.Add("Invigorated by smoking.")
+ if(PERK_CHARMING_PERSONALITY)
+ psychological.Add("Provides a comfortingly charming presence.")
+ if(PERK_HORRIBLE_DEEDS)
+ psychological.Add("UNSETTLING.")
+ if(PERK_TERRIBLE_FATE)
+ psychological.Add("More afraid of death than usual.")
+ if(PERK_BALLS_OF_PLASTEEL)
+ psychological.Add("Higher pain tolerance than otherwise indicated.")
+ if(PERK_ARTIST)
+ psychological.Add("Looks at life as art.")
+
+ medRecord.value["psychological"] = psychological.len ? psychological : list("No psychological abnormality at time of writing.")
+ else // if there isn't a human
+ var/datum/storedrecord/medical/default/medrecord = new() // just use the defaults
+ medrecord.transfertocomputer(medRecord)
+ qdel(medrecord)
// Security record
set_criminalStatus(GLOB.default_security_status)
set_dna(H ? H.dna_trace : "")
set_fingerprint(H ? H.fingers_trace : "")
- set_secRecord(H && H.sec_record && !jobban_isbanned(H.ckey, "Records") ? html_decode(H.sec_record) : "No record supplied")
- // Employment record
- var/employment_record = "No record supplied"
if(H)
- if(H.gen_record && !jobban_isbanned(H.ckey, "Records"))
- employment_record = html_decode(H.gen_record)
- if(H.client && H.client.prefs)
- var/list/qualifications
- if(LAZYLEN(qualifications))
- employment_record = "[employment_record ? "[employment_record]\[br\]" : ""][jointext(qualifications, "\[br\]>")]"
- set_emplRecord(employment_record)
-
-
- if(H)
- var/stats = list()
- for(var/statName in ALL_STATS)
- var/points = H.stats.getStat(statName,pure = TRUE)
- if(points > STAT_LEVEL_NONE)
- stats += "[statName]: [points] ([statPointsToLevel(points)])"
+ for(var/datum/perk/fate/profile in H.stats.perks)
+ switch(profile)
+ if(PERK_PAPER_WORM)
+ set_emplRecord("Experienced in bureacracy.")
+ if(PERK_FREELANCER)
+ set_emplRecord("Wide variety of employments.")
+ if(PERK_DRUG_ADDICT)
+ set_emplRecord("Has a history of drug addiction.")
+ if(PERK_ALCOHOLIC)
+ set_emplRecord("Is an alcoholic.")
+ if(PERK_NOBLE)
+ set_emplRecord("Is of noble origin.")
+ if(PERK_LOWBORN)
+ set_emplRecord("Was hired from poverty.")
+ if(!get_emplRecord())
+ set_emplRecord("Standard background.")
+ else
+ set_emplRecord("No record supplied.")
- set_skillset(jointext(stats,"\n"))
+ if(loadedprefs)
+ var/originfound
+ for(var/datum/category_group/setup_option_category/background/origin/OriginBG in loadedprefs.setup_options)
+ if(loadedprefs.loaded_character[OriginBG.name])
+ originfound = OriginBG.name
+ break
+ if(originfound)
+ set_origin(originfound)
+ else
+ set_origin("Origin not on record.")
// Antag record
set_antagRecord(H && H.exploit_record && !jobban_isbanned(H, "Records") ? html_decode(H.exploit_record) : "")
@@ -96,16 +193,16 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest")
/proc/SortModularRecords()
// improved bubble sort
- if(GLOB.all_crew_records.len > 1)
- for(var/i = 1; i <= GLOB.all_crew_records.len; i++)
- var/flag = FALSE
- for(var/j = 1; j <= GLOB.all_crew_records.len - 1; j++)
- var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j]
- var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1]
- if(sorttext(CR.get_name(), CR_NEXT.get_name()) == -1)
- flag = TRUE
- GLOB.all_crew_records.Swap(j,j+1)
- if(!flag)
+ if(GLOB.all_crew_records.len > 1) // if list is big enough to sort
+ for(var/i = 1, i <= GLOB.all_crew_records.len, i++) // for each entry in list
+ var/flag = FALSE // define a var as false
+ for(var/j = GLOB.all_crew_records.len-1, j >= 1, j--) // cycle through all entries,
+ var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j] // starting from the one before the last
+ var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1] // and the last
+ if(sorttext(CR.get_name(), CR_NEXT.get_name()) == 1) // if the one before the last is bigger than the last
+ flag = TRUE // reset the var to true
+ GLOB.all_crew_records.Swap(j,j+1) // and swap the last and the one before the last
+ if(!flag) // if no work was done, stop
break
// Gets crew records filtered by set of positions
@@ -161,9 +258,13 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest")
#define GETTER_SETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_##KEY(){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) return F.get_value()} \
/datum/computer_file/report/crew_record/proc/set_##KEY(given_value){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) F.set_value(given_value)}
+#define SELF_GETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_linkage_##KEY(){return locate(/datum/report_field/##PATH/##KEY) in fields}
#define SETUP_FIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) GETTER_SETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\
/datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\
KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)}
+#define SETUP_ARRAYFIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) SELF_GETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\
+/datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\
+KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)}
// Fear not the preprocessor, for it is a friend. To add a field, use one of these, depending on value type and if you need special access to see it.
// It will also create getter/setter procs for record datum, named like /get_[key here]() /set_[key_here](value) e.g. get_name() set_name(value)
@@ -174,6 +275,8 @@ KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)}
#define FIELD_LIST(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT)
#define FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) SETUP_FIELD(NAME, KEY, options/crew_record, ACCESS, ACCESS_EDIT);\
/datum/report_field/options/crew_record/##KEY/get_options(){return OPTIONS}
+#define ARRAYFIELD_SINGLE(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, array/crew_record, ACCESS, ACCESS_EDIT)
+#define ARRAYFIELD_CLUMP(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, arrayclump/crew_record, ACCESS, ACCESS_EDIT)
// GENERIC RECORDS
FIELD_SHORT("Name", name, null, access_change_ids)
@@ -189,17 +292,17 @@ FIELD_NUM("Account",account, null, access_change_ids)
// MEDICAL RECORDS
FIELD_LIST("Blood Type", bloodtype, GLOB.blood_types, access_moebius, access_moebius)
-FIELD_LONG("Medical Record", medRecord, access_moebius, access_moebius)
+ARRAYFIELD_CLUMP("Medical Record", medRecord, access_moebius, access_moebius)
// SECURITY RECORDS
FIELD_LIST("Criminal Status", criminalStatus, GLOB.security_statuses, access_security, access_security)
-FIELD_LONG("Security Record", secRecord, access_security, access_security)
+ARRAYFIELD_SINGLE("Brief", secNotes, access_security, access_security)
FIELD_SHORT("DNA", dna, access_security, access_security)
FIELD_SHORT("Fingerprint", fingerprint, access_security, access_security)
// EMPLOYMENT RECORDS
FIELD_LONG("Employment Record", emplRecord, access_heads, access_heads)
-FIELD_LONG("Qualifications", skillset, access_heads, access_heads)
+FIELD_LONG("Place of origin", origin, access_heads, access_heads)
// ANTAG RECORDS
FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_syndicate)
@@ -240,9 +343,13 @@ FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_synd
. |= BR.name
*/
#undef GETTER_SETTER
+#undef SELF_GETTER
#undef SETUP_FIELD
+#undef SETUP_ARRAYFIELD
#undef FIELD_SHORT
#undef FIELD_LONG
#undef FIELD_NUM
#undef FIELD_LIST
#undef FIELD_LIST_EDIT
+#undef ARRAYFIELD_SINGLE
+#undef ARRAYFIELD_CLUMP
diff --git a/code/modules/modular_computers/file_system/reports/report.dm b/code/modules/modular_computers/file_system/reports/report.dm
index 2be0080d016..94fe1ded684 100644
--- a/code/modules/modular_computers/file_system/reports/report.dm
+++ b/code/modules/modular_computers/file_system/reports/report.dm
@@ -133,7 +133,22 @@ If the override option is set to 0, the access supplied will instead be added as
dat["access"] = field.verify_access(given_access)
dat["access_edit"] = field.verify_access_edit(given_access)
dat["name"] = field.display_name()
- dat["value"] = field.get_value()
+
+ if(istype(field, /datum/report_field/array))
+ var/datum/report_field/array/arrayfield = field
+ dat["list_value"] = arrayfield.value_list.Copy()
+ dat["list_clumps"] = null // must override with null values or else react gets weird
+ dat["value"] = null
+ else if(istype(field, /datum/report_field/arrayclump))
+ var/datum/report_field/arrayclump/clumpfield = field
+ dat["list_value"] = null
+ dat["list_clumps"] = clumpfield.value
+ dat["value"] = null
+ else
+ dat["list_value"] = null
+ dat["list_clumps"] = null
+ dat["value"] = field.get_value()
+
dat["can_edit"] = field.can_edit
dat["needs_big_box"] = field.needs_big_box
dat["ignore_value"] = field.ignore_value
diff --git a/code/modules/modular_computers/file_system/reports/report_field.dm b/code/modules/modular_computers/file_system/reports/report_field.dm
index f453d8c2f9a..b09fb51db6f 100644
--- a/code/modules/modular_computers/file_system/reports/report_field.dm
+++ b/code/modules/modular_computers/file_system/reports/report_field.dm
@@ -211,4 +211,151 @@ Basic field subtypes.
value_list.Remove(given_value)
/datum/report_field/array/ask_value(mob/user)
- add_value(input(user, "Add value", "") as null|text)
+ var/inputchoice = input(user, "Add or Remove value", "Field Edit", "Add") in list("Add", "Remove")
+ if(inputchoice == "Add")
+ var/toadd = input(user, "Add value", "Field Input") as null|text
+ if(!isnull(toadd))
+ add_value(toadd)
+ else if(inputchoice == "Remove")
+ remove_value(input(user, "Choose value to remove", "Field Reduce") as null|anything in value_list )
+
+
+
+/datum/report_field/arraylinkage
+ var/list/arrays = list()
+ ignore_value = TRUE // value is too generic to use
+
+// retrieves index of key
+// can retrieve additional entries of same index using additionalarrays param
+/datum/report_field/arraylinkage/proc/retrieve_index_of_array(key, index = 0, additionalarrays = list())
+ if(!(key && (arrays.len > 0) && index > 0)) // can we access?
+ return FALSE
+ var/primeretrieved = arrays[key] // key's array
+ if(!(index && primeretrieved && length(primeretrieved) >= index)) // can we access the index asked for using the key?
+ return FALSE
+ var/list/toreturn = list(primeretrieved[index])
+ for(var/arrayexists in additionalarrays) // all linked arrays we also want index of
+ if((arrayexists in arrays) && length(arrays[arrayexists]) >= index)
+ var/list/toadd = arrays[arrayexists]
+ toreturn.Add(toadd[index])
+ else
+ return FALSE // we really don't want input from bad sources.
+ . = toreturn // succeeded all the checks? caller's will be done.
+
+// adds one index to the end of each list
+// sets the contents of each list for the created index on demand using either keys or arrangement of any given input of proper size
+/datum/report_field/arraylinkage/proc/add_index(list/new_entries, keyed = FALSE)
+ if(!new_entries || new_entries.len > arrays.len)
+ return FALSE
+ if(new_entries.len != arrays.len) // only accept using list-order based indexing when it has a 1 to 1 ratio
+ keyed = TRUE
+ var/count = 1
+ if(keyed)
+ for(var/key in arrays) // unfitting keys are discarded, but can still disqualify a list.
+ var/list/currentarray = arrays[key]
+ if(new_entries[key])
+ currentarray.Add(new_entries[key])
+ else
+ currentarray.Add(null) // all arrays must have the same indexing for the linkage to work.
+ . = TRUE
+ else
+ for(var/entry in new_entries) // sanitize before it's t oo late
+ if(new_entries[entry])
+ CRASH("keyed outside of key mode in add_index")
+ for(var/entry in new_entries)
+ var/list/currentarray = arrays?[count]
+ if(!currentarray) // in case a check breaks
+ return
+ count ++
+ currentarray.Add(entry)
+ . = TRUE
+
+// set one entry in one list
+/datum/report_field/arraylinkage/proc/edit_index(key, setto, index)
+ if(!arrays[key] || length(arrays[key]) < index || !islist(arrays[key]))
+ return FALSE
+ var/list/accessed = arrays[key]
+ if(accessed)
+ accessed[index] = setto
+ . = TRUE
+
+// delete one index of all lists in arraylinkage
+/datum/report_field/arraylinkage/proc/remove_index(index)
+ if(!length(arrays) || length(arrays[1]) < index) // check if there are arrays and the first one is long enough
+ return FALSE // hopefully all arrays have the same length as the first one
+ for(var/list/arraytocut in arrays)
+ arraytocut.Cut(index, index+1)
+ . = TRUE
+
+/datum/report_field/arraylinkage/ask_value(mob/user)
+
+/datum/report_field/arrayclump // these arrays are explicitly unlinked and are stored here for categorization
+ value = list() // only input key=array as entry
+
+/datum/report_field/arrayclump/set_value(given_value)
+ if(!islist(given_value))
+ return FALSE
+ . = ..()
+
+/datum/report_field/arrayclump/ask_value(mob/user)
+ . = TRUE
+ var/list/clumpvalue = value
+ if(!istype(clumpvalue))
+ return FALSE
+ var/list/entries = clumpvalue.Copy()
+ entries.Add("")
+
+ var/entrychoice = input(user, "Choose Entry Category", "Entry Category") as null | anything in entries
+ if(entrychoice == "" )
+ var/entryname = input(user, "Choose Entry Name", "Entry Name") as text | null
+ entryname = sanitizeSafe(entryname)
+ if(!istext(entryname))
+ to_chat(user, SPAN_NOTICE("Edit canceled successfully."))
+ return FALSE
+ if(clumpvalue[entryname]) // only replace entry with alert
+ if(alert(user, "Replace old entry?", "Entry Replacement", "Yes", "No") == "No")
+ to_chat(user, SPAN_NOTICE("Edit canceled successfully."))
+ return FALSE
+ var/startingvalue = input(user, "Create Entry", "Entry Creation") as text | null
+ startingvalue = sanitizeSafe(startingvalue)
+ if(!istext(startingvalue))
+ to_chat(user, SPAN_NOTICE("Edit canceled successfully."))
+ return FALSE
+ to_chat(user, SPAN_NOTICE("You have successfully added an entry to [name]."))
+ value[entryname] = list(startingvalue)
+
+ else if(entrychoice)
+ var/list/selections = clumpvalue[entrychoice]
+ selections = selections.Copy() // don't edit the original list
+ selections.Add("")
+ var/selectionchoice = input(user, "Select Entry", "Entry") as null | anything in selections
+ if(!istext(selectionchoice))
+ return FALSE
+ if(selectionchoice == "")
+ var/nextvalue = input(user, "Add Value", "Value") as text | null
+ nextvalue = sanitizeSafe(nextvalue)
+ if(!istext(nextvalue))
+ to_chat(user, SPAN_NOTICE("Addition canceled successfully."))
+ return FALSE
+ else
+ var/list/entrytoaddto = clumpvalue[entrychoice]
+ if(istype(entrytoaddto))
+ entrytoaddto.Add(nextvalue)
+ else
+ CRASH("Type Mismatch in clump list")
+
+ else
+ var/newvalue = input(user, "New Value", "Value") as text | null
+ newvalue = sanitizeSafe(newvalue)
+ if(!istext(newvalue))
+ to_chat(user, SPAN_NOTICE("Replacement canceled successfully."))
+ return FALSE
+ var/list/intermediaryvalue = clumpvalue[entrychoice]
+ if(istype(intermediaryvalue))
+ var/indexhound = clumpvalue.Find(intermediaryvalue) // the Hound finds the value we splice
+ intermediaryvalue.Splice(indexhound, indexhound+1, newvalue)
+ else
+ CRASH("Type Mismatch in clump list")
+
+
+
diff --git a/code/modules/nano/modules/tgui_type.dm b/code/modules/nano/modules/tgui_type.dm
new file mode 100644
index 00000000000..e605715301b
--- /dev/null
+++ b/code/modules/nano/modules/tgui_type.dm
@@ -0,0 +1,92 @@
+/datum/nano_module/tgui
+ var/datum/tgui/currentui // gotta save it, we can't get it any other way
+ var/show_map ; var/map_z_level // the sins of our predecessors, brought to the present by the sins of our own
+
+/datum/nano_module/tgui/ui_host(mob/user)
+ return nano_host()
+
+/datum/nano_module/tgui/ui_close(mob/user)
+ . = ..()
+ currentui = null // must clear reference to ui
+
+/datum/nano_module/tgui/ui_assets(mob/user)
+ return list(
+ get_asset_datum(/datum/asset/spritesheet/legacyicons)
+ )
+
+
+/datum/nano_module/tgui/ui_act(action, params)
+ . = ..()
+
+ if(istype(host, /datum/computer_file/program))
+ var/datum/computer_file/program/program = host
+ switch(action)
+ if("PC_exit")
+ program.computer.kill_program()
+ return TRUE
+ if("PC_enable_component")
+ var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"])
+ if(istype(H) && !H.enabled)
+ H.enabled = TRUE
+ H.enabled()
+ . = TRUE
+ if("PC_disable_component")
+ var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"])
+ if(istype(H) && H.enabled)
+ H.enabled = FALSE
+ H.disabled()
+ . = TRUE
+ if("PC_toggle_component")
+ var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"])
+ if(istype(H))
+ H.enabled = !H.enabled
+ if(H.enabled)
+ H.enabled()
+ else
+ H.disabled()
+ . = TRUE
+ if("PC_shutdown")
+ program.computer.shutdown_computer()
+ return TRUE
+ if("PC_minimize")
+ var/mob/user = usr
+ program.computer.minimize_program(user)
+
+ if("PC_killprogram")
+ var/prog_name = params["PC_killprogram"]
+ var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer
+ if(!prog_disk)
+ return TRUE
+
+ for(var/p in program.computer.all_threads)
+ var/datum/computer_file/program/PRG = p
+ if(PRG.program_state == PROGRAM_STATE_KILLED)
+ continue
+
+ if(PRG.filename == prog_name && (PRG in prog_disk.stored_files))
+ PRG.kill_program(forced=TRUE)
+ to_chat(usr, SPAN_NOTICE("Program [PRG.filename].[PRG.filetype] has been killed."))
+ . = TRUE
+
+ if("PC_runprogram")
+ var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer
+ return program.computer.run_program(params["PC_runprogram"], prog_disk)
+
+ if("PC_setautorun")
+ if(!program.computer.hard_drive)
+ return
+ program.computer.set_autorun(params["PC_setautorun"])
+ if("PC_terminal")
+ program.computer.open_terminal(usr)
+ return TRUE
+
+/datum/nano_module/tgui/ui_status(mob/user, datum/ui_state/state)
+ . = ..(user, state ? state : GLOB.default_state)
+ if(. > UI_DISABLED && istype(host, /datum/computer_file/program))
+ var/datum/computer_file/program/relevant = host
+ if(relevant.program_state == PROGRAM_STATE_KILLED)
+ . = UI_CLOSE
+ else if(relevant.program_state == PROGRAM_STATE_BACKGROUND)
+ . = min(., UI_UPDATE) // theoretically might be necessary with a new system, if redundant just collapse this with the killing check.
+
+
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index da13f74c193..2e347f91a1d 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -107,22 +107,12 @@
/obj/structure/filingcabinet/security/populate()
if(virgin)
- for(var/datum/data/record/G in data_core.general)
- var/datum/data/record/S
- for(var/datum/data/record/R in data_core.security)
- if((R.fields["name"] == G.fields["name"] || R.fields["id"] == G.fields["id"]))
- S = R
- break
+ for(var/datum/computer_file/report/crew_record/G in GLOB.all_crew_records)
var/obj/item/paper/P = new /obj/item/paper(src)
P.info = "Security Record "
- P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]] \nSex: [G.fields["sex"]] \nAge: [G.fields["age"]] \nFingerprint: [G.fields["fingerprint"]] \nPhysical Status: [G.fields["p_stat"]] \nMental Status: [G.fields["m_stat"]] "
- P.info += " \nSecurity Data \nCriminal Status: [S.fields["criminal"]] \n \nMinor Crimes: [S.fields["mi_crim"]] \nDetails: [S.fields["mi_crim_d"]] \n \nMajor Crimes: [S.fields["ma_crim"]] \nDetails: [S.fields["ma_crim_d"]] \n \nImportant Notes: \n\t[S.fields["notes"]] \n \nComments/Log "
- var/counter = 1
- while(S.fields["com_[counter]"])
- P.info += "[S.fields["com_[counter]"]] "
- counter++
+ P.info += "Name: [G.get_name()] \nSex: [G.get_sex()] \nAge: [G.get_age()] \nFingerprint: [G.get_fingerprint()] "
P.info += ""
- P.name = "Security Record ([G.fields["name"]])"
+ P.name = "Security Record ([G.get_name()])"
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
//before the records have been generated, so we do this inside the loop.
@@ -142,24 +132,21 @@
/obj/structure/filingcabinet/medical/populate()
if(virgin)
- for(var/datum/data/record/G in data_core.general)
- var/datum/data/record/M
- for(var/datum/data/record/R in data_core.medical)
- if((R.fields["name"] == G.fields["name"] || R.fields["id"] == G.fields["id"]))
- M = R
- break
+ for(var/datum/computer_file/report/crew_record/G in GLOB.all_crew_records)
+ var/datum/report_field/arrayclump/M = G.get_linkage_medRecord()
if(M)
var/obj/item/paper/P = new /obj/item/paper(src)
- P.info = "Medical Record "
- P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]] \nSex: [G.fields["sex"]] \nAge: [G.fields["age"]] \nFingerprint: [G.fields["fingerprint"]] \nPhysical Status: [G.fields["p_stat"]] \nMental Status: [G.fields["m_stat"]] "
-
- P.info += " \nMedical Data \nBlood Type: [M.fields["b_type"]] \nDNA: [M.fields["b_dna"]] \n \nMinor Disabilities: [M.fields["mi_dis"]] \nDetails: [M.fields["mi_dis_d"]] \n \nMajor Disabilities: [M.fields["ma_dis"]] \nDetails: [M.fields["ma_dis_d"]] \n \nAllergies: [M.fields["alg"]] \nDetails: [M.fields["alg_d"]] \n \nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section) \nDetails: [M.fields["cdi_d"]] \n \nImportant Notes: \n\t[M.fields["notes"]] \n \nComments/Log "
- var/counter = 1
- while(M.fields["com_[counter]"])
- P.info += "[M.fields["com_[counter]"]] "
- counter++
- P.info += ""
- P.name = "Medical Record ([G.fields["name"]])"
+ var/list/infostoadd = list()
+ infostoadd += "Medical Record "
+ infostoadd += "Name: [G.get_name()] \nSex: [G.get_sex()] \nAge: [G.get_age()] "
+
+ infostoadd += " \nMedical Data \nBlood Type: [G.get_bloodtype()] \nDNA: [G.get_dna()] "
+ infostoadd += " \nProsthetics: [M.value["prosthetics"]] \nWounds: [M.value["wounds"]] \n \nAutopsy: [M.value["Body state"]] "
+ infostoadd +=" \nChemical History: [M.value["chemhistory"]] \nPsychological Profile: [M.value["psychological"]] "
+
+ infostoadd += ""
+ P.name = "Medical Record ([G.get_name()])"
+ P.info = infostoadd.Join() // minor optimization
virgin = 0 //tabbing here is correct- it's possible for people to try and use it
//before the records have been generated, so we do this inside the loop.
diff --git a/code/modules/research/designs/circuits.dm b/code/modules/research/designs/circuits.dm
index f5c38fe0f0e..d424223f6d9 100644
--- a/code/modules/research/designs/circuits.dm
+++ b/code/modules/research/designs/circuits.dm
@@ -36,11 +36,6 @@
sort_string = "MABBA"
category = CAT_MISC
-/datum/design/research/circuit/secdata
- name = "security records console"
- build_path = /obj/item/electronics/circuitboard/secure_data
- sort_string = "DABAA"
- category = CAT_COMP
/datum/design/research/circuit/prisonmanage
name = "prisoner management console"
@@ -48,11 +43,6 @@
sort_string = "DACAA"
category = CAT_COMP
-/datum/design/research/circuit/med_data
- name = "medical records console"
- build_path = /obj/item/electronics/circuitboard/med_data
- sort_string = "FAAAA"
- category = CAT_COMP
/datum/design/research/circuit/operating
name = "patient monitoring console"
diff --git a/code/modules/research/nodes/biotech.dm b/code/modules/research/nodes/biotech.dm
index bdc911109c2..12140281da2 100644
--- a/code/modules/research/nodes/biotech.dm
+++ b/code/modules/research/nodes/biotech.dm
@@ -17,7 +17,7 @@
/datum/technology/basic_med_machines
name = "Basic Medical Machines"
- desc = "Basic medical databases and surgical monitoring."
+ desc = "Basic surgical monitoring."
tech_type = RESEARCH_BIOTECH
x = 0.25
@@ -28,9 +28,7 @@
required_tech_levels = list()
cost = 200
- unlocks_designs = list( /datum/design/research/circuit/med_data,
- /datum/design/research/circuit/operating
- )
+ unlocks_designs = list(/datum/design/research/circuit/operating)
/*
/datum/technology/virology
name = "Virology"
diff --git a/icons/ui_icons/dmis/uiicons16.dmi b/icons/ui_icons/dmis/uiicons16.dmi
new file mode 100644
index 00000000000..7b5d90ace41
Binary files /dev/null and b/icons/ui_icons/dmis/uiicons16.dmi differ
diff --git a/maps/CEVEris/_CEV_Eris.dmm b/maps/CEVEris/_CEV_Eris.dmm
index 7cb20aa7fbd..0518d04520b 100644
--- a/maps/CEVEris/_CEV_Eris.dmm
+++ b/maps/CEVEris/_CEV_Eris.dmm
@@ -102878,6 +102878,14 @@
},
/turf/floor/plating/under,
/area/eris/maintenance/sorter)
+"qmi" = (
+/obj/item/cell/medium,
+/obj/item/cell/medium,
+/obj/item/computer_hardware/processor_unit,
+/obj/item/computer_hardware/tesla_link,
+/obj/item/computer_hardware/tesla_link,
+/turf/floor/hull,
+/area/space)
"qmJ" = (
/obj/machinery/door/blast/shutters{
dir = 4;
@@ -104987,6 +104995,13 @@
},
/turf/floor/plating/under,
/area/eris/maintenance/section3deck5port)
+"tZv" = (
+/obj/item/computer_hardware/network_card/wired,
+/obj/item/computer_hardware/network_card/wired,
+/obj/item/computer_hardware/scanner/paper,
+/obj/item/computer_hardware/scanner/paper,
+/turf/floor/hull,
+/area/space)
"tZw" = (
/obj/structure/cable/green{
d1 = 4;
@@ -205277,7 +205292,7 @@ iEk
cBO
cwU
abF
-abF
+qmi
abF
cwU
cwU
@@ -205479,7 +205494,7 @@ cBO
cos
cwU
abF
-abF
+tZv
abF
abF
cwU
diff --git a/nano/templates/crew_records.tmpl b/nano/templates/crew_records.tmpl
index 543879ebe0d..009496403e1 100644
--- a/nano/templates/crew_records.tmpl
+++ b/nano/templates/crew_records.tmpl
@@ -28,6 +28,27 @@
{{if value.needs_big_box}}
{{:value.value}}
+ {{else}}
+ {{if value.list_value}}
+ {{for value.list_value}}
+ {{:value}}
+ {{/for}}
+ {{else}}
+ {{if value.list_clumps}}
+ {{for value.list_clumps}}
+ {{for value}}
+ {{:value}}
+ {{/for}}
+ {{/for}}
+ {{else}}
+ {{if value.links}}
+ {{for 1 to value.links.len}}
+ {{for value.links}}
+
+ {{/if}}
+ {{/if}}
+ {{/if}}
+ {{/if}}
{{else}}
{{:value.value}}
diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl
index 37b1d7061ca..b45d66cd2c9 100644
--- a/nano/templates/pai_medrecords.tmpl
+++ b/nano/templates/pai_medrecords.tmpl
@@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,50 +28,52 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
=Status
+
{{:data.general.status}}
-
Mental Status
-
{{:data.general.m_stat}}
+
Blood Type
+
{{:data.general.bloodtype}}
{{/if}}
{{if data.medical}}
-
Blood Type
-
{{:data.medical.b_type}}
-
-
-
Minor Disabilities
-
{{:data.medical.mi_dis}}
-
{{:data.medical.mi_dis_d}}
+
Prosthetics
+ {{for data.medical.value.prosthetics}}
+
{{:value}}
+ {{/for}}
-
Major Disabilities
-
{{:data.medical.ma_dis}}
-
{{:data.medical.ma_dis_d}}
+
Wounds
+ {{for data.medical.value.wounds}}
+
{{:value}}
+ {{/for}}
-
Allergies
-
{{:data.medical.alg}}
-
{{:data.medical.alg_d}}
+
Body State
+ {{for data.medical.value.body state}}
+
{{:value}}
+ {{/for}}
-
Current Diseases
-
{{:data.medical.cdi}}
-
{{:data.medical.cdi_d}}
+
Chemical History
+ {{for data.medical.value.chemhistory}}
+
{{:value}}
+ {{/for}}
-
Important Notes
-
{{:data.medical.notes}}
+
Psychological Profile
+ {{for data.medical.value.psychological}}
+
{{:value}}
+ {{/for}}
{{/if}}
diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl
index e139034c0de..cdb3321a07c 100644
--- a/nano/templates/pai_secrecords.tmpl
+++ b/nano/templates/pai_secrecords.tmpl
@@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,40 +28,24 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
Status
+
{{:data.general.status}}
-
-
Mental Status
-
{{:data.general.m_stat}}
-
-{{/if}}
-{{if data.security}}
Criminal Status
-
{{:data.security.criminal}}
-
-
-
Minor Crimes
-
{{:data.security.mi_crim}}
-
{{:data.security.mi_crim_d}}
-
-
-
Major Crimes
-
{{:data.security.ma_crim}}
-
{{:data.security.ma_crim_d}}
-
+ {{:data.general.criminalStatus }}
+
Important Notes
-
{{:data.security.notes}}
+
{{:data.general.secNotes}}
{{/if}}
diff --git a/tgui/packages/tgui/interfaces/Computer.tsx b/tgui/packages/tgui/interfaces/Computer.tsx
new file mode 100644
index 00000000000..9da923a2ae7
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Computer.tsx
@@ -0,0 +1,173 @@
+import { Box, Button, Table } from 'tgui-core/components';
+import { BooleanLike } from 'tgui-core/react';
+
+import { sendAct } from '../backend';
+
+export interface ComputerInterface {
+ PC_batteryicon: string;
+ PC_batterypercent: string;
+ PC_showbatteryicon: BooleanLike;
+ PC_light_name: string;
+ PC_light_on: BooleanLike;
+ PC_apclinkicon: string;
+ PC_ntneticon: string;
+ has_gps: BooleanLike;
+ gps_icon: string;
+ gps_data: string;
+ PC_programheaders: Programheader[];
+ PC_stationtime: string;
+ PC_hasheader: BooleanLike;
+ PC_showexitprogram: BooleanLike;
+ mapZLevels: number[];
+ mapZLevel: number;
+}
+
+type Programheader = {
+ icon: string;
+};
+
+export const ProgramShell = (props: ComputerInterface) => {
+ const {
+ PC_batteryicon,
+ PC_batterypercent,
+ PC_showbatteryicon,
+ PC_light_name,
+ PC_light_on,
+ PC_apclinkicon,
+ PC_ntneticon,
+ has_gps,
+ gps_icon,
+ gps_data,
+ PC_programheaders,
+ PC_stationtime,
+ PC_hasheader,
+ PC_showexitprogram,
+ mapZLevels,
+ mapZLevel,
+ } = props;
+ const act = sendAct;
+ return (
+ <>
+
+
+
+
+ {PC_showexitprogram && (
+
+
+
+
+ act('PC_exit')}
+ />
+
+
+ act('PC_minimize')}
+ />
+
+
+
+
+ )}
+ {PC_showexitprogram || }
+
+
+ Initiating...
+
+ >
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/CrewRecords.tsx b/tgui/packages/tgui/interfaces/CrewRecords.tsx
new file mode 100644
index 00000000000..1609553f36c
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/CrewRecords.tsx
@@ -0,0 +1,344 @@
+import { Box, Button, Divider, Table } from 'tgui-core/components';
+import { BooleanLike } from 'tgui-core/react';
+import { classes } from 'tgui-core/react';
+
+import { sendAct, useBackend } from '../backend';
+import { GameIcon } from '../components/GameIcon';
+import { Window } from '../layouts';
+import { ComputerInterface, ProgramShell } from './Computer';
+
+interface CrewRecordsInterface extends RecordConcrete, ComputerInterface {
+ message: string;
+ front_pic: string;
+ side_pic: string;
+ pic_edit: BooleanLike;
+ all_records: RecordAbstract[];
+ creation: BooleanLike;
+ dnasearch: BooleanLike;
+ fingersearch: BooleanLike;
+}
+
+interface RecordConcrete {
+ name: string;
+ uid: number;
+ creator: string;
+ filetime: string;
+ fields: RecordField[];
+ access: BooleanLike;
+ access_edit: BooleanLike;
+}
+type RecordField = {
+ access: BooleanLike;
+ access_edit: BooleanLike;
+ name: string;
+ value: string | number | object;
+ list_value: any[];
+ list_clumps: object[];
+ can_edit: BooleanLike;
+ needs_big_box: BooleanLike;
+ ignore_value: BooleanLike;
+ ID: number;
+};
+
+type RecordAbstract = {
+ name: string;
+ rank: string;
+ id: number;
+};
+
+export const CrewRecords = (props: ComputerInterface) => {
+ const { act, data } = useBackend();
+ const {
+ message,
+ uid,
+ fields,
+ front_pic,
+ side_pic,
+ pic_edit,
+ all_records,
+ creation,
+ dnasearch,
+ fingersearch,
+ } = data;
+ return (
+
+
+ {ProgramShell(props)}
+ {message && act('clear_message')} />}
+ {message}
+
+ {uid &&
+ CurrentRecord(
+ { uid, fields, front_pic, side_pic, pic_edit }
+ )}
+ {Boolean(uid) || (
+ <>
+ {Boolean(creation) && (
+ <>
+
+ act('new_record')}
+ />
+ >
+ )}
+ <>
+
+ act('search', { search: 'Name' })}
+ />
+ >
+ {Boolean(dnasearch) && (
+ <>
+
+ act('search', { search: 'DNA' })}
+ />
+ >
+ )}
+ {Boolean(fingersearch) && (
+ <>
+
+ act('search', { search: 'Fingerprint' })}
+ />
+ >
+ )}
+
+
+ Available records:
+
+
+
+ NamePosition
+
+
+ {all_records.map((mapped) => {
+ return (
+ <>
+
+
+
+ act('set_active', { set_active: mapped.id })
+ }
+ />
+
+
+ {mapped.rank}
+ >
+ );
+ })}
+
+ >
+ )}
+
+
+ );
+};
+
+interface CurrentRecordProps {
+ uid: number;
+ fields: RecordField[];
+ front_pic: string;
+ side_pic: string;
+ pic_edit: BooleanLike;
+}
+
+const CurrentRecord = (props: CurrentRecordProps) => {
+ const act = sendAct;
+ const { uid, fields, front_pic, side_pic, pic_edit } = props;
+ return (
+ <>
+ act('clear_active')} />
+ act('print_active')} />
+
+
+ GENERIC INFORMATION
+
+
+
+
+
+
+ {Boolean(pic_edit) && (
+
+
+
+ act('edit_photo_front')}
+ />
+
+ act('edit_photo_side')} />
+
+ )}
+ {fields &&
+ fields.map((mapped) => {
+ return DisplayField(mapped);
+ })}
+ >
+ );
+};
+
+const DisplayField = (props: RecordField) => {
+ const act = sendAct;
+ const {
+ access,
+ access_edit,
+ name,
+ value,
+ list_value,
+ list_clumps,
+ can_edit,
+ needs_big_box,
+ ignore_value,
+ ID,
+ } = props;
+ return (
+ <>
+ {access && access_edit && (
+
+
+ act('edit_field', { edit_field: ID })}
+ />
+
+ )}
+ {access && (Boolean(access_edit) || name)}
+ {access && (
+
+ {typeof value === 'string' || typeof value === 'number'
+ ? value
+ : value !== null && value !== undefined
+ ? JSON.stringify(value)
+ : ''}
+ {list_value &&
+ (Object.values(list_value).length
+ ? list_value.join(', ')
+ : 'Unset')}
+ {list_clumps &&
+ (Object.keys(list_clumps)
+ ? Object.keys(list_clumps).map((mapped, count) => {
+ return (
+ <>
+ {mapped}
+ {': '}
+ {returnlist(
+ { origin: list_clumps, whichlist: count },
+ )}
+
+ >
+ );
+ })
+ : 'Unset')}
+
+ )}
+ >
+ );
+};
+
+const returnlist = (props) => {
+ const { origin, whichlist } = props;
+ let toreturn: any;
+ if (
+ Object.values(origin) &&
+ typeof Object.values(origin)[whichlist] !== 'undefined' &&
+ Array.isArray(Object.values(origin)[whichlist])
+ ) {
+ let unfoldthis1: any = Object.values(origin)[whichlist];
+ let unfoldthis2: any[] = unfoldthis1;
+ toreturn = unfoldthis2.toString();
+ } else toreturn = 'Sadness';
+ return toreturn;
+};
+
+/**/
+/*
+{{if data.message}}
+{{:helper.link('X', null, {'clear_message' : 1})}}{{:data.message}}
+{{/if}}
+{{if data.uid}}
+{{:helper.link('BACK', '', {'clear_active' : 1})}}{{:helper.link('PRINT', '', {'print_active' : 1})}}
+
+
+
GENERIC INFORMATION
+
+
+
+
+
+ {{if data.pic_edit}}
+
+
 
+
{{:helper.link('Edit Front', 'pencil', {'edit_photo_front' : 1}, null)}}{{:helper.link('Edit Side', 'pencil', {'edit_photo_side' : 1}, null)}}
+
+ {{/if}}
+ {{for data.fields}}
+ {{if value.access}}
+
+ {{if value.access_edit}}
+
{{:helper.link(value.name, 'pencil', {'edit_field' : value.ID}, null)}}
+ {{else}}
+
{{:value.name}}:
+ {{/if}}
+ {{if value.needs_big_box}}
+
+ {{if value.value}}
+ {{:value.value}}
+ {{else}}
+ {{if value.list_value}}
+ {{for value.list_value}}
+ {{:value}}
+ {{/for}}
+ {{else}}
+ {{if value.list_clumps}}
+ {{for value.list_clumps}}
+ {{for value}}
+ {{:value}}
+ {{/for}}
+ {{/for}}
+ {{else}}
+ {{if value.links}}
+ {{for 1 to value.links.len}}
+ {{for value.links}}
+
+ {{/if}}
+ {{/if}}
+ {{/if}}
+ {{/if}}
+
+ {{else}}
+
{{:value.value}}
+ {{/if}}
+
+ {{/if}}
+ {{/for}}
+
+{{else}}
+{{if data.creation}}
+ {{:helper.link('New Record', 'document', {'new_record' : 1}, null)}}
+{{/if}}
+{{:helper.link('Name Search', 'search', {'search' : 'Name'}, null)}}
+{{if data.dnasearch}}
+ {{:helper.link('DNA Search', 'search', {'search' : 'DNA'}, null)}}
+{{/if}}
+{{if data.fingersearch}}
+ {{:helper.link('Fingerprint Search', 'search', {'search' : 'Fingerprint'}, null)}}
+{{/if}}
+
+Available records:
+
+Name Position
+{{for data.all_records}}
+ {{:helper.link(value.name, '', {'set_active' : value.id})}}
+ {{:value.rank}}
+{{/for}}
+
+{{/if}}
+*/