From cf41110420d03981136f2936db37cb293e3df17b Mon Sep 17 00:00:00 2001 From: vode-code <65709050+vode-code@users.noreply.github.com> Date: Tue, 9 Sep 2025 15:31:21 -0700 Subject: [PATCH 1/3] Data Core Must Die (https://github.com/discordia-space/CEV-Eris/pull/8594) * the datacore is dead, long live the crew record file list apparently this stuff dates back to may 2012 new savefile version clears out old records preferences reworked security records character name replacer proc updates renamed items reversed records sort polarity reworked respawn character proc adds setup disks for preset console programs reduced security and medical file cabinet data to that which could be reasonably accurate for an entire round deleted unused real rank system fixed potential fake crew arrival runtime cargo positions now named guild positions and JOBS_CARGO is now JOBS_GUILD nonhuman positions now named silicon positions and JOBS_NONHUMAN is now JOBS_SILICON world manifest now checks department rather than preset job names updated PAI general, medical, and security records access program fixed freelancer perk define name added green thumb and neat job perk defines deleted duplicate records customization file numbered 5 pruned record customization WIP * return to default for datacore purge update note: setup disks merged seperately security notes simplified --------- Co-authored-by: Humonitarian <61586732+Humonitarian@users.noreply.github.com> --- cev_eris.dme | 5 +- code/__DEFINES/jobs.dm | 4 +- code/__DEFINES/perks.dm | 4 +- code/__HELPERS/manifest.dm | 6 +- code/__HELPERS/names.dm | 4 +- code/__HELPERS/unsorted.dm | 23 +- code/controllers/subsystems/ticker.dm | 1 - code/datums/datacore.dm | 454 ------------ code/datums/setup_option/backgrounds/fate.dm | 2 +- code/datums/topic/world.dm | 35 +- code/datums/uplink/announcements.dm | 52 +- code/defines/procs/announce.dm | 5 +- code/game/jobs/jobs.dm | 6 +- code/game/machinery/computer/medical.dm | 519 -------------- code/game/machinery/computer/security.dm | 658 ------------------ code/game/machinery/hologram.dm | 5 +- code/game/objects/items/devices/uplink.dm | 8 +- .../circuitboards/computer/computer.dm | 6 - .../admin_secrets/show_crew_manifest.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 24 +- .../asset_cache/assets/legacyuiicons.dm | 5 + .../preference_setup/background/03_records.dm | 114 ++- .../preference_setup/general/05_records.dm | 64 -- .../loadout/lists/accessories.dm | 2 +- .../preference_setup/loadout/lists/suits.dm | 4 +- code/modules/client/preferences.dm | 5 +- code/modules/client/preferences_savefile.dm | 2 +- code/modules/economy/Accounts.dm | 6 +- code/modules/mob/hear_say.dm | 5 +- .../mob/living/carbon/human/examine.dm | 18 +- code/modules/mob/living/carbon/human/human.dm | 265 +++---- .../mob/living/carbon/human/human_defines.dm | 3 - code/modules/mob/living/living.dm | 13 +- code/modules/mob/living/silicon/ai/ai.dm | 4 +- code/modules/mob/living/silicon/pai/pai.dm | 12 +- .../living/silicon/pai/software_modules.dm | 114 ++- code/modules/mob/mob_helpers.dm | 6 +- code/modules/mob/new_player/new_player.dm | 1 - .../computers/modular_computer/core.dm | 2 + .../modular_computers/file_system/program.dm | 5 +- .../file_system/programs/command/card.dm | 2 +- .../file_system/programs/generic/records.dm | 55 +- .../file_system/reports/crew_record.dm | 173 ++++- .../file_system/reports/report.dm | 17 +- .../file_system/reports/report_field.dm | 149 +++- code/modules/nano/modules/tgui_type.dm | 92 +++ code/modules/paperwork/filingcabinet.dm | 45 +- code/modules/research/designs/circuits.dm | 10 - code/modules/research/nodes/biotech.dm | 6 +- icons/ui_icons/dmis/uiicons16.dmi | Bin 0 -> 6642 bytes maps/CEVEris/_CEV_Eris.dmm | 19 +- nano/templates/crew_records.tmpl | 21 + nano/templates/pai_medrecords.tmpl | 54 +- nano/templates/pai_secrecords.tmpl | 34 +- tgui/packages/tgui/interfaces/Computer.tsx | 169 +++++ tgui/packages/tgui/interfaces/CrewRecords.tsx | 332 +++++++++ 56 files changed, 1359 insertions(+), 2292 deletions(-) delete mode 100644 code/datums/datacore.dm delete mode 100644 code/game/machinery/computer/medical.dm delete mode 100644 code/game/machinery/computer/security.dm create mode 100644 code/modules/asset_cache/assets/legacyuiicons.dm delete mode 100644 code/modules/client/preference_setup/general/05_records.dm create mode 100644 code/modules/nano/modules/tgui_type.dm create mode 100644 icons/ui_icons/dmis/uiicons16.dmi create mode 100644 tgui/packages/tgui/interfaces/Computer.tsx create mode 100644 tgui/packages/tgui/interfaces/CrewRecords.tsx diff --git a/cev_eris.dme b/cev_eris.dme index 3069d243330..306aaca93a5 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -357,7 +357,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" @@ -833,14 +832,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" @@ -1559,6 +1556,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" @@ -2404,6 +2402,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 839cbee07d3..d1aa6451fd0 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 = {" - - - - "} - 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 += "" - for(name in bot) - dat += "" - even = !even - - if(heads.len > 0) - dat += "" - for(name in heads) - dat += "" - even = !even - if(sec.len > 0) - dat += "" - for(name in sec) - dat += "" - even = !even - if(eng.len > 0) - dat += "" - for(name in eng) - dat += "" - even = !even - if(med.len > 0) - dat += "" - for(name in med) - dat += "" - even = !even - if(sci.len > 0) - dat += "" - for(name in sci) - dat += "" - even = !even - if(car.len > 0) - dat += "" - for(name in car) - dat += "" - even = !even - if(chr.len > 0) - dat += "" - for(name in chr) - dat += "" - even = !even - if(civ.len > 0) - dat += "" - for(name in civ) - dat += "" - even = !even - if(misc.len > 0) - dat += "" - for(name in misc) - dat += "" - even = !even - - dat += "
NameRankActivity
Silicon
[name][bot[name]][isactive[name]]
Heads
[name][heads[name]][isactive[name]]
Security
[name][sec[name]][isactive[name]]
Engineering
[name][eng[name]][isactive[name]]
Medical
[name][med[name]][isactive[name]]
Science
[name][sci[name]][isactive[name]]
Guild
[name][car[name]][isactive[name]]
Church
[name][chr[name]][isactive[name]]
Civilian
[name][civ[name]][isactive[name]]
Miscellaneous
[name][misc[name]][isactive[name]]
" - 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 9691d597d4b..9597596ce90 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/defines/procs/announce.dm b/code/defines/procs/announce.dm index 3be75945e33..f4fa7fd3537 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -119,4 +119,7 @@ var/datum/announcement/priority/command/command_announcement = new(do_log = 0, d if(issilicon(character)) GLOB.announcer.autosay("A new [rank] [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) else - GLOB.announcer.autosay("[character.real_name], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) + if(istype(character)) + GLOB.announcer.autosay("[character.real_name], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) + else if(istext(character)) + GLOB.announcer.autosay("[character], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) // send the text 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 += "
Name: [active1.fields["name"]] \ - ID: [active1.fields["id"]]
\n \ - Sex: [active1.fields["sex"]]
\n \ - Age: [active1.fields["age"]]
\n \ - Fingerprint: [active1.fields["fingerprint"]]
\n \ - Physical Status: [active1.fields["p_stat"]]
\n \ - Mental Status: [active1.fields["m_stat"]]
\ - Photo:
" - else - dat += "General Record Lost!
" - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += text("
\n
Medical 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
\n
Comments/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("
\n
Medical 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
\n
Comments/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 += {" -

- - - - -
Records:
- - - - - - - -"} - 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 += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - 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 += {" - -
- Name: [active1.fields["name"]]
- ID: [active1.fields["id"]]
- Sex: [active1.fields["sex"]]
- Age: [active1.fields["age"]]
- Rank: [active1.fields["rank"]]
- Fingerprint: [active1.fields["fingerprint"]]
- Physical Status: [active1.fields["p_stat"]]
- Mental Status: [active1.fields["m_stat"]]
Photo:
- -

- Update front photo

- Update side photo
-
- "} - else - dat += "General Record Lost!
" - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - dat += "
\n
Security 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]':
- - - - - - - - - "} - 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 += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - 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 += "" - 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/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 2ef97125f7f..2e04b04f9c3 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 f48f77d295c..6afa52373f7 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 b18473b9030..39709317b75 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -426,21 +426,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")) @@ -453,52 +452,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) @@ -507,32 +504,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)) @@ -540,126 +532,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 e09cf0ff7a3..479fa4bcdaf 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -82,9 +82,6 @@ var/equipment_prescription // Eye prescription granted by equipped items var/list/equipment_overlays = list() // Extra overlays from equipped items - var/med_record = "" - var/sec_record = "" - var/gen_record = "" var/exploit_record = "" var/stance_damage = 0 //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 c15934b2333..84e50b597e2 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -550,8 +550,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..e2a25dd9549 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 @@ -148,20 +146,25 @@ /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)) - var/record[0] - record["name"] = general.fields["name"] - record["ref"] = "\ref[general]" - records[++records.len] = record + var/records[0] + for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records) + var/record[0] + 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 - data["could_not_find"] = user.medical_cannotfind + 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) @@ -172,26 +175,17 @@ 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 + 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 + if(href_list["select"]) + var/datum/computer_file/report/crew_record/record = locate(href_list["select"]) + if(istype(record)) 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 - else - P.medical_cannotfind = 1 - return 1 + P.medicalActive = record + else + P.medical_cannotfind = 1 + return TRUE /* Security records */ /datum/pai_software/sec_records @@ -204,19 +198,19 @@ 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 - data["could_not_find"] = user.security_cannotfind + 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) if(!ui) @@ -231,26 +225,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 354900a99a5..33bfbab68ba 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 8a39be844e9..d488b34daf9 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -329,7 +329,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..a2756ccbd89 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 @@ -41,13 +43,11 @@ ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) 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(mob/user) var/list/user_access = using_access || user.GetAccess() var/obj/item/modular_computer/PC = nano_host() @@ -57,7 +57,7 @@ return user_access -/datum/nano_module/records/proc/edit_field(mob/user, field_ID) +/datum/nano_module/tgui/records/proc/edit_field(mob/user, field_ID) var/datum/computer_file/report/crew_record/R = active_record if(!R) return @@ -69,7 +69,7 @@ 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"]) @@ -113,23 +113,22 @@ 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 += "
\n
Security 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
\n
Comments/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 += "
\n
Medical 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
\n
Comments/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 += "
\n
Medical 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 0000000000000000000000000000000000000000..7b5d90ace41bbb78e4f6fad05779eb75da5deccc GIT binary patch literal 6642 zcmZu$cTf~xmu-R|N>Eht5F{%gSq3EMARvQE&OveS^cV3;;fvS!u1#GvcI*<7pNAQ%I)tTAxNoMxBTH zwbv~PYXTD0t2%oc(-qroLZRH+FHF2r0Gt{dR8=26z4bFL+vKO`vusmu&blWC-*H>* z(%W7XwzN|iN$Tti#Ruwswcpj{~L@svaoMjN!`RjgBe%^gEn0+c%OwDcl+>aZVgV`E!R`Rr(3JK zr{%o3`IgY3@G@QKe2AVbPep)_S$kgb4u3usclUgL;)IL)Dy89`!8Du9-%3AcL)(z}Ti&~~ z`ygFa5TR*Y$S${1GN3(m*YK8ea|fZ`SK8NeAM{7=bM+X=xK{XPqW$wl%ygW#!zj2S z0*dyJiJ)=|`?RT`&U^vwRq=02sR0$j`8vvVjPI#T7DQFWss1E+(zRFeG9@RDFR@$Slr6#6n9YpO=T0zR zOA@IM(=+*&-72}ZLTQLc=Ba-jqh~8#olm}f8d`> z{7S{$jV3e(k_yFrtt z$w5o3ri!xUKU~fcgttF2PsTXDN}u2;J~p55teH&tp0y<;bcpvWz8x|;8u0zh{ky%5 z>i~$L1q7UM@1M~DEn=~AA?7q+7+N~fV`1Y=jrz7U5(D#@=Ze_$w|MiEfCu809MhA#E50?kQ!wx_hE`({{mQ0sDW zf)@J3Vd*;Tc((=YO#y_P)4ZunI}IcTu0O==U($0ZSNTMqu#0UxFQm*vDozq5hCb(G|;3O=|wx7 zEYovZ=_^M(kN6ve>sEg&vk-t26Y&0h$C{0RGn@c883G^s0Vm`DU$}Y0%{uie#$EWR zqPH_W9B?xk(H)D1fEXd{ngC`>-oC@?h$vBQ5Hj-_ajytD%X2I-mUjapFDY^RUiM-D z^|w~#YWMl>_lthYywB^2Nx?MX3-#^%7ev5Stw{w%xVab+%#?>J`uY|OH-Ne(gyELN zuCgpHng?M`S%Wn(>J9NurgGzAt^=1&G~v>wCMH*Oz|D$HftFK?Dm|d3sl#Gd5|}A` zGK(wDfk-eZW!H|}U@fXsV^vPp=J(vl$mmCt9*+rr%kd5RcQTr0p8}OPqlvto&sUDa z9K)viT8W;}4cH#!i|+h7cD{K;?ReyM?LN@twv?R_Fe@^E>NTes19sML!m3+6+0d5h z^1P+b|8pz&n97lSmbwybb2ATLhOX<+7`1l(c|bH`3&_ylx#bwk(CsJH&c8~U?Z2n$ zLQiVxqJJRT!he(&iphZc7jZ9hXG|EwxBpymJWDEebs#dL+)pct$6dIjEc?~}MDJru zXC??N?&cI&rT#!~NBe7Pt(|SqYSWoB5pN;#S{?R8+N<`!TzeC>>0m^5beqfQRpQ>@ z;9v#T5`@`9?N#yhASX6B18yfZ;^~46j%xV~^RMW<4!DFEVWoRo*-}mSyER7dn?5V0 zc>Z;G?t0Wd8QQiiPqX$gD{3PCYj)|-s?NE(xY!=uk$N?L$#SN0wZhT_6Op_}4Y!(T zvPu}g&RI|iZgbO7Oi~hB>btot@WC^Zi+vo=5MernuhH-RUdRo6MISAkBVA93g{y;P zn!ct;NJywp#b@FbX1(?!#C3<|$LM}$?M+Zed#p1X2dhkLs@W4E%9+{zb~zEu;k2~0 zvb&N27=#qgV7+=Bca4M>1k_)}~u0bS=W_yAQ>RSvsiVyH$RxTmhy4^%e# zgdP?>dLMy)*(-4JuJ-+3v+QM9YMWZ;*4ec@IR(XQh6K6tAN({l>S`+o2N)0|Bb9{J zw}C{_PB_zg<#k#L)YHB*83umLzVA_t;H)W&HYrmt-v=i2q;>QvME05a*SXJ#i z+Xq5K=nZ6J*2?Y|iM~oo2bbL|jXm*=CF|fbhJAX@D`))cEx?u((V6kRmmTTl}+ zcB0ZqF1}AwmN4|g;9J8JZS@2UGWA$}{Om}b7wfQBm6d6v0_(4?5~VK46r<)LWO9Ci{ zaInlcJe7X4Zz*haWJ+$$m@)*&gY&Z+>Lg%scX#(t>m)FyelGC*O=JC;0{)ZdHZ4=l zwy_SYbd(vT?hAr38~&(5MrGn-RkJ6DpQd9oiOs;YpZHwPYitM0Q?lTLiK?dn@~`D- zV(cQAxdT}5Lkvfb20PtbBmLFiI+A+2k|Y24rxBm=`o#QAa9+iJXo#(FBW3At{Z(t~ zMxiq4lbxNNuiQA($pB%r<#;FQ-~cZ(uhH##cmx@=MD}LW*JyN)_Nj>0WjM_oX{Q$6 zBw4fB4UdNI|2ugEdq2#eTEP_Q5b-`fX~h{YuVFk0NUJ@vGVT{-{1s!dgP5isBj)WR(CFq^!aAZX8n-6xS1ohlF41? zPBk7*q{Qb}0@#!z7_z#-5N6b*{s7HOya{Thhz~jmM&XqXK0IUqfgWY?H>=K^y?b$@ zy7q421DrIKGO@Ul&Kfe?C8+4t&tu!tkOz;77&zX;s{8CMqg}7B0=zvv32(%fC-=0H zRRmvWSx0<{zJyDPB& z%?A$r2Op%+vi=t*O7l=Up<>5-W*Go$bw zmAsETiz;}rHd!oBl6oPQoz$Uys{b^|$M{0N>aZi4nm=}F=i+pqKFAX4BbnQ8bUHH! z=`C)lwfs_HcCPi3i1nY$pxN{B^n@Sgsv>ey^~uXvkE7UQxeL3G+HgSg`Bvi=a@?db z5bNI_Cmddjql_2-=%*%-oycChqjtGGb@XXnwom&WOr#H zf+-Nz6~{!ead>tX&B?7o%=A-mZOy+*^5Nu6kNq97;FX$yJL&1CTp$)tDOKD;kH=pk z;AB3OVy3kf?}h)#?>|j`)QnR8t5ngq&gjFJTBFmG6Aa6d2;zpxKwhF?1KPyv;;R&+ zkQJp*Z^)R*xW?R@;Zmi1q}f4Nr#rKL+o+1>Gy5Hi&e@>rfMaZmX&$ATdJyEeMH0(i zWk82c%hj~mp9H`@Y*=U19u8(F>*j@g$Du_6d-ES|5pdbzvO<51eJOmS^pf~+ z&AZ#TDO^kX@}TpODe%O6xQM>%Ub>LddcgV;&WB?~N^XUj7Ec`n`yP?ot-dj9IJ=Q* zG1>-opC$(ha|IcErq}+!`me2YRcM|ji`AS$KJOHO!+v;bw`rqDs zolty9FJ}Oiv3oeEE2=$M<4a`TC8`pN{~}RlvlRbA+LfhWs+rmt zECN>j@y_Yj@gy@+wsQFbqU?n^u*_oq5$fWGr^jLCoic(yneb2 znTlvQtgw#NXd;Ybc_zD*V2d<(X*b7PE7}VA?S2c!>r(#CNo8YWek-AO+{P5C5SplrtluQj7 z`!7x9e(YCcRyzWFrZ2p9+@b|Nb^bDzg1%COiNovM<^Qq>Ayxkwt^cX~t`rl+LTDXh z+yr_3=a2yw3Lb?$u~ZM&j56tZV>TB3VKc7^OY-Aa1R6zQ*G+K!c2)GEjzpAx0pGx7 z3@^X8kLqag(0g`$l9_5tlnMF0I$0mnf-{3&_k(3YO5xt$l`JU2toDy-cNN=u&c$8V z6Qith6g+-qWeKKtR?h}=$1=oy&-MRC28lJG)2(u?CTXkt3bl!H-V}T-=xXltV*ys0 z!SGxz8d_^bYZMjI)g6%~`baITiqlbfKu3u+9*j{0HRwQ#G14OYIt+UGai`+%p0RUd zyN+3`yEdiZ+*tn!P55{8Od1y-)6)mj59SDC8MzZ*1EW{NW?^{Ne(6~J^WRO=`z*k4S^w+txeS{kLUMGnTvzq}o)M+HX*1GUh zeJe^sKk}O$HB+5X9g)+6_0+afj|sQ?ZPfUR7>NB^6q{+XE(nJZ!DeO~$b=8vw#;7^ zrINLx66nZjQobRHlWuCf7DdrSy+#biW{r6wQNNhg$r6|L;Cv=byr`|AU@!ufRKUM-ww{HTFvttsi(uzPR5QJg`D+9DHp5`d86^Ae=VgN%ryHsVGT zqH~kQ;>QJ$f2;l!9#_5#n}1cFKat@n^H(WHJE{b?s&-2kvMiUurX5-WwuY~(yUjOj z@umd3wSb@Jx8{$!2>6NxtRM({*-HoJ+DJU^A7)lVSOvz57<={X(+mzrF}YO?V_X@6 zp*W(T@&|}zjCA5-YvE$n!I1P9;v4^qUij#f>d>{EFL-0YKg>0!- z!J?dDQAmN6u=9)8#I^@7(Q2NqAieg}Lh+ISKK9<^@#~G9lJDRIy0@It%TkySK?4y_kNP75<5HxL4b(cJcKBHZ&^4bPq)n$&5_BL z#=pTLZD5G!0-W-r>`wA%pvXG(;aWgaw%M$B1gS1#>q4`VwH~FZGVqJ|sz@*&a=hcjSa6Rvb(nCxrh*EO8{xUCAR!wCW--+Q zRX-*_`K;Z>2&Fe;NDP@v{p?p_=9X6T$W3M*!7wZEPgc(is~yxTgAZ0e7{w^%m{jaC z!$wGu2$?A-j&DH}Y*+^|jSAf-n?T5!Z*{4AuD!T0ecYEg!-%miauK$p1976%5rJ-u zwSkmbaDZ5Z;F->gk8|FAyPry{w1xjaqW-HTR8rogu~?}UBmK-;+I|97K)w_5Bc2&2 zzwIjY(SWt0(wd>5wl4sM8)YxCkuuaW7!S?pxZk4=vG~EGteL3E#w%ePpl9brQ8RcGES?-;3;;B=)zyHLdb*wpnHrSRK(he~HX$0lm7 z5@siK)nrcdy`OAfeRVuZA2uAhKRA==^$}aSN7=X}u2K)6>PVq~+*@>IjR*=@wKLT) z_EaOD4CQ=wm&lFT?-Z_Y0Rt~TV@PlQ5zJ^ig-2Fci8&H9%no0n)D*{us5-F-A0>Vp zqEQf8R(Ik*_bdSOSo&EUZbPo$bTQX>%d}5e^H6sFuSWTQ)ZYJAbE`3Ov98)8#sm9^ z0GDg3!-_!pavM^!inx-LK%Rix>}5H&Qkk`v$VFFny#927O5PEaPTjJnm90#S5l^fU z8u6yuz%({5nW8w@3K&+gDO!&|k|y)dcxfkpw1HL&vRwQ7!C;cK^k;EhZp!}Y#u8JM zKX)9m$6&wcn3D$nB?SvSd#Sd8b+}t^IQyZB_(Rp*9U9|@I!9} zJ3ZHxD}UI3vjrh(8^P_`ahQ#t>97q^!7pnmZ0T;5fU z*9{C%n}8e3+8Fy^{jT77T+tj<>gr@^mV*XVMf=}>6TVh%)8cj3rV>!4%F9$%O*@7W z9JvB^GOiaxTi?fM8|6glA1B|JT~is}4!?cqifzE_7>3PbperAgq6!E)LFJ0t_E9F- zA|3t8HD2xvKjj1ZefCDe7>WKm@oXDsy_m%Qe_mZ=)MjPUOoxm)TzBb*q&RMg#MAB* z9X=Z6CFM^3GeyF#z60-H@mGrdrlP!_Mu7{$vE7OoNKLBOuD!H*%23G(k@yLo53G5F mgGp9d=L@j^mk;m0CeVc?T5V{ReYx4o0aO(=70TtzLjD7{Bk^(o literal 0 HcmV?d00001 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..cd4fa1f534f --- /dev/null +++ b/tgui/packages/tgui/interfaces/Computer.tsx @@ -0,0 +1,169 @@ +import { BooleanLike } from 'common/react'; +import { Button, Box, Table } from '../components'; +import { TableCell, TableRow } from '../components/Table'; +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, context) => { + 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 ( + <> + + { + // Add a template with the key "headerContent" to have it rendered here --> + } + {PC_hasheader} + + + + + + {PC_batteryicon && PC_showbatteryicon && ( + + + + )} + {PC_batterypercent && PC_showbatteryicon && ( + + {PC_batterypercent} + + )} + {PC_ntneticon && ( + + + + )} + {PC_apclinkicon && ( + + + + )} + {PC_stationtime && ( + + {PC_stationtime} + + )} + {PC_programheaders && + PC_programheaders.map((mapped) => ( + + + + ))} + +
+
+
+ + + + {PC_light_name && ( + +
+
+ + {has_gps && ( + + + + + + + {gps_data} + +
+
+ )} +
+
+ + + + {PC_showexitprogram && ( + + + + +
+
+ )} + {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..3cb3f0bc944 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CrewRecords.tsx @@ -0,0 +1,332 @@ +import { BooleanLike } from 'common/react'; +import { useBackend, sendAct } from '../backend'; +import { Button, Box, Divider, Table } from '../components'; +import { GameIcon } from '../components/GameIcon'; +import { Window } from '../layouts'; +import { ComputerInterface, ProgramShell } from './Computer'; +import { classes } from 'common/react'; + +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, context) => { + const { act, data } = useBackend(context); + const { + message, + uid, + fields, + front_pic, + side_pic, + pic_edit, + all_records, + creation, + dnasearch, + fingersearch, + } = data; + return ( + + + {ProgramShell(props, context)} + {message &&