diff --git a/cev_eris.dme b/cev_eris.dme index 15f72edf42b..f7b9f54bbb9 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -359,7 +359,6 @@ #include "code\datums\chat_payload.dm" #include "code\datums\chatmessage.dm" #include "code\datums\contract.dm" -#include "code\datums\datacore.dm" #include "code\datums\datum.dm" #include "code\datums\datum_click_handlers.dm" #include "code\datums\datum_hud.dm" @@ -832,14 +831,12 @@ #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\guestpass.dm" #include "code\game\machinery\computer\law.dm" -#include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\message.dm" #include "code\game\machinery\computer\Operating.dm" #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\prisoner.dm" #include "code\game\machinery\computer\prisonshuttle.dm" #include "code\game\machinery\computer\robot.dm" -#include "code\game\machinery\computer\security.dm" #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_control.dm" @@ -1558,6 +1555,7 @@ #include "code\modules\asset_cache\assets\chat.dm" #include "code\modules\asset_cache\assets\icon_ref_map.dm" #include "code\modules\asset_cache\assets\notes.dm" +#include "code\modules\asset_cache\assets\legacyuiicons.dm" #include "code\modules\asset_cache\assets\sanity.dm" #include "code\modules\asset_cache\assets\sheetmaterials.dm" #include "code\modules\asset_cache\assets\stats.dm" @@ -2394,6 +2392,7 @@ #include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\law_manager.dm" #include "code\modules\nano\modules\nano_module.dm" +#include "code\modules\nano\modules\tgui_type.dm" #include "code\modules\onestar\generator.dm" #include "code\modules\onestar\os_cash.dm" #include "code\modules\onestar\os_turret.dm" diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 18a82d9b01c..2bebcf467e3 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -8,10 +8,10 @@ #define JOBS_MEDICAL "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer" #define JOBS_SCIENCE "Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist" #define JOBS_MOEBIUS "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer","Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist" -#define JOBS_CARGO "Guild Merchant","Guild Technician","Guild Miner", +#define JOBS_GUILD "Guild Merchant","Guild Technician","Guild Miner", #define JOBS_CIVILIAN "Club Manager","Club Worker","Club Artist",ASSISTANT_TITLE #define JOBS_CHURCH "NeoTheology Preacher","NeoTheology Acolyte","NeoTheology Agrolyte","NeoTheology Custodian" -#define JOBS_NONHUMAN "AI","Robot","pAI" +#define JOBS_SILICON "AI","Robot","pAI" #define CREDITS "¢" #define CREDS "¢" diff --git a/code/__DEFINES/perks.dm b/code/__DEFINES/perks.dm index 210eaa70c3e..d6571683e42 100644 --- a/code/__DEFINES/perks.dm +++ b/code/__DEFINES/perks.dm @@ -1,6 +1,6 @@ //fate perks #define PERK_PAPER_WORM /datum/perk/fate/paper_worm -#define PERK_FREELACER /datum/perk/fate/freelancer +#define PERK_FREELANCER /datum/perk/fate/freelancer #define PERK_NIHILIST /datum/perk/fate/nihilist #define PERK_MORALIST /datum/perk/fate/moralist #define PERK_ALCOHOLIC /datum/perk/fate/alcoholic @@ -49,6 +49,8 @@ #define PERK_CODESPEAK_COP /datum/perk/codespeak #define PERK_CODESPEAK_SERB /datum/perk/codespeak/serbian #define PERK_TECHNOMANCER /datum/perk/inspiration +#define PERK_NEAT /datum/perk/neat +#define PERK_GREEN_THUMB /datum/perk/greenthumb #define PERK_CLUB /datum/perk/job/club #define PERK_CHANNELING /datum/perk/channeling diff --git a/code/__HELPERS/manifest.dm b/code/__HELPERS/manifest.dm index 66527c5ebc7..135cb4a23fd 100644 --- a/code/__HELPERS/manifest.dm +++ b/code/__HELPERS/manifest.dm @@ -142,13 +142,13 @@ "sec" = filtered_nano_crew_manifest(security_positions),\ "eng" = filtered_nano_crew_manifest(engineering_positions),\ "med" = filtered_nano_crew_manifest(medical_positions),\ - "sup" = filtered_nano_crew_manifest(cargo_positions),\ + "sup" = filtered_nano_crew_manifest(guild_positions),\ "chr" = filtered_nano_crew_manifest(church_positions),\ - "bot" = silicon_nano_crew_manifest(nonhuman_positions),\ + "bot" = silicon_nano_crew_manifest(silicon_positions),\ "civ" = filtered_nano_crew_manifest(civilian_positions)\ ) /proc/flat_nano_crew_manifest() . = list() . += filtered_nano_crew_manifest(null, TRUE) - . += silicon_nano_crew_manifest(nonhuman_positions) + . += silicon_nano_crew_manifest(silicon_positions) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 0c6b487f29f..0d3347c4a38 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -110,8 +110,8 @@ var/syndicate_code_response//Code response for contractors. var/locations[] = SSmapping.teleportlocs.len ? SSmapping.teleportlocs : drinks//if null, defaults to drinks instead. var/names[] = list() - for(var/datum/data/record/t in data_core.general)//Picks from crew manifest. - names += t.fields["name"] + for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records)//Picks from crew manifest. + names += t.get_name() var/maxwords = words//Extra var to check for duplicates. diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 775c9806297..26a1f8da684 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -276,26 +276,21 @@ Turf and target are seperate in case you want to teleport some distance from a t mind.name = newname if(oldname) - //update the datacore records! This is goig to be a bit costly. - for(var/list/L in list(data_core.general, data_core.medical, data_core.security, data_core.locked)) - for(var/datum/data/record/R in L) - if(R.fields["name"] == oldname) - R.fields["name"] = newname - break + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + if(R.get_name() == oldname) + R.set_name(newname) //update our pda and id if we have them on our person - var/list/searching = GetAllContents(searchDepth = 3) - var/search_id = 1 - var/search_pda = 1 - - for(var/A in searching) - if( search_id && istype(A,/obj/item/card/id) ) + for(var/obj/A in GetAllContents(searchDepth = 3)) + if(istype(A,/obj/item/card/id)) var/obj/item/card/id/ID = A if(ID.registered_name == oldname) ID.registered_name = newname ID.name = "[newname]'s ID Card ([ID.assignment])" - if(!search_pda) break - search_id = 0 + if(istype(A.loc, /obj/item/modular_computer)) + var/obj/item/modular_computer/tolabel = A.loc + tolabel.update_label() + break return 1 diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 7bf4718792f..401d2222ece 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -264,7 +264,6 @@ SUBSYSTEM_DEF(ticker) if(!H.mind || player_is_antag(H.mind, only_offstation_roles = 1) || !SSjob.ShouldCreateRecords(H.mind.assigned_role)) continue CreateModularRecord(H) - data_core.manifest() CHECK_TICK diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm deleted file mode 100644 index 55f2af15562..00000000000 --- a/code/datums/datacore.dm +++ /dev/null @@ -1,454 +0,0 @@ -var/global/list/PDA_Manifest = list() -var/global/ManifestJSON - -/hook/startup/proc/createDatacore() - data_core = new /datum/datacore() - return 1 - -/datum/datacore - var/name = "datacore" - var/medical[] = list() - var/general[] = list() - var/security[] = list() - //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/locked[] = list() - - -/datum/datacore/proc/get_manifest(monochrome, OOC) - var/list/heads = new() - var/list/sec = new() - var/list/eng = new() - var/list/med = new() - var/list/sci = new() - var/list/car = new() - var/list/chr = new() - var/list/civ = new() - var/list/bot = new() - var/list/misc = new() - var/list/isactive = new() - var/dat = {" - - - - "} - 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 2b4a4fdb212..e2ee0a4dc3a 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -38,48 +38,42 @@ return 0 var/obj/item/card/id/I = user.GetIdCard() - var/datum/data/record/random_general_record - var/datum/data/record/random_medical_record - if(data_core.general.len) - random_general_record = pick(data_core.general) - random_medical_record = find_medical_record("id", random_general_record.fields["id"]) + var/datum/computer_file/report/crew_record/random_record + if(GLOB.all_crew_records.len) + random_record = pick(GLOB.all_crew_records) - var/datum/data/record/general = data_core.CreateGeneralRecord(user) + var/datum/computer_file/report/crew_record/general = new() if(I) - general.fields["age"] = I.age - general.fields["rank"] = I.assignment - general.fields["real_rank"] = I.assignment - general.fields["name"] = I.registered_name - general.fields["sex"] = I.sex + general.set_age(I.age) + general.set_job(I.assignment) + general.set_name(I.registered_name) + general.set_sex(I.sex) else var/mob/living/carbon/human/H if(ishuman(user)) H = user - general.fields["age"] = H.age + general.set_age(H.age) else - general.fields["age"] = initial(H.age) + general.set_age(initial(H.age)) var/assignment = GetAssignment(user) - general.fields["rank"] = assignment - general.fields["real_rank"] = assignment - general.fields["name"] = user.real_name - general.fields["sex"] = capitalize(user.gender) + general.set_job(assignment) + general.set_department(args["department"]) + general.set_name(user.real_name) + general.set_sex(capitalize(user.gender)) - general.fields["species"] = user.get_species() - var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"]) - data_core.CreateSecurityRecord(general.fields["name"], general.fields["id"]) + general.set_species(user.get_species()) - if(!random_general_record) - general.fields["fingerprint"] = random_general_record.fields["fingerprint"] - if(random_medical_record) - medical.fields["b_type"] = random_medical_record.fields["b_type"] - medical.fields["b_dna"] = random_medical_record.fields["b_type"] + if(random_record) + general.set_fingerprint(random_record.get_fingerprint()) + general.set_bloodtype(random_record.get_bloodtype()) + general.set_dna(random_record.get_bloodtype()) if(I) - general.fields["fingerprint"] = I.fingerprint_hash - medical.fields["b_type"] = I.blood_type - medical.fields["b_dna"] = I.dna_hash + general.set_fingerprint(I.fingerprint_hash) + general.set_bloodtype(I.blood_type) + general.set_dna(I.dna_hash) - AnnounceArrival(general.fields["name"], general.fields["rank"], "has completed cryogenic revival") + AnnounceArrival(general.get_name(), general.get_job(), "has completed cryogenic revival") return 1 /datum/uplink_item/abstract/announcements/fake_ion_storm diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index aaeac96e804..deb597d4d4b 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -78,7 +78,7 @@ var/list/science_positions = list(JOBS_SCIENCE) var/list/moebius_positions = list(JOBS_MOEBIUS) //BS12 EDIT -var/list/cargo_positions = list(JOBS_CARGO) +var/list/guild_positions = list(JOBS_GUILD) var/list/church_positions = list(JOBS_CHURCH) @@ -90,7 +90,7 @@ var/list/civilian_positions = list(JOBS_CIVILIAN) var/list/security_positions = list(JOBS_SECURITY) var/list/armory_positions = list(JOBS_ARMORY) -var/list/nonhuman_positions = list(JOBS_NONHUMAN) +var/list/silicon_positions = list(JOBS_SILICON) /proc/guest_jobbans(var/job) - return ((job in command_positions) || (job in nonhuman_positions) || (job in armory_positions)) + return ((job in command_positions) || (job in silicon_positions) || (job in armory_positions)) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm deleted file mode 100644 index c59fa2806ce..00000000000 --- a/code/game/machinery/computer/medical.dm +++ /dev/null @@ -1,519 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/obj/machinery/computer/med_data//TODO:SANITY - name = "medical records console" - desc = "Used to view, edit and maintain medical records." - icon_keyboard = "med_key" - icon_screen = "medcomp" - light_color = COLOR_LIGHTING_GREEN_MACHINERY - req_one_access = list(access_moebius, access_forensics_lockers) - circuit = /obj/item/electronics/circuitboard/med_data - var/obj/item/card/id/scan - var/authenticated - var/rank - var/screen - var/datum/data/record/active1 - var/datum/data/record/active2 - var/a_id - var/temp - var/printing - -/obj/machinery/computer/med_data/verb/eject_id() - set category = "Object" - set name = "Eject ID Card" - set src in oview(1) - - if(!usr || usr.stat || usr.lying) return - - if(scan) - to_chat(usr, "You remove \the [scan] from \the [src].") - scan.loc = get_turf(src) - if(!usr.get_active_held_item() && ishuman(usr)) - usr.put_in_hands(scan) - scan = null - else - to_chat(usr, "There is nothing to remove from the console.") - return - -/obj/machinery/computer/med_data/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/card/id) && !scan && user.unEquip(O)) - O.loc = src - scan = O - to_chat(user, "You insert \the [O].") - else - ..() - -/obj/machinery/computer/med_data/attack_hand(mob/user as mob) - if(..()) - return - nano_ui_interact(user) - -/obj/machinery/computer/med_data/nano_ui_interact(mob/user) - var/dat - if (src.temp) - dat = text("[src.temp]

Clear Screen") - else - dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) - if (src.authenticated) - switch(src.screen) - if(1) - dat += {" -Search Records -
List Records -
Medbot Tracking -
-
Record Maintenance -
{Log Out}
-"} - if(2) - dat += "Record List:
" - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) - //Foreach goto(132) - dat += text("
Back", src) - if(3) - dat += text("Records Maintenance
\nBackup To Disk
\nUpload From disk
\nDelete All Records
\n
\nBack", src, src, src, src) - if(4) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") - dat += "
Medical Record

" - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - dat += "
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/game/say.dm b/code/game/say.dm index 1c82ea2f3d7..f9f58f0e0f1 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -40,7 +40,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/virtualspeaker) if(ishuman(M)) // Humans use their job as seen on the crew manifest. This is so the AI // can know their job even if they don't carry an ID. - var/record_rank = find_record(name, "rank") + #warn fix this this wont work! + var/record_rank = get_crewmember_record(name) if(record_rank) job = record_rank else diff --git a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm index 0d7f0d248d7..aa42e71e02f 100644 --- a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm +++ b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm @@ -7,6 +7,6 @@ return var/dat dat += "

Crew Manifest

" - dat += data_core.get_manifest() + dat += html_crew_manifest(TRUE) user << browse(HTML_SKELETON_TITLE("Crew Manifest", dat), "window=manifest;size=370x420;can_close=1") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index fdf2f4674dd..534fe5c71bf 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -319,23 +319,8 @@ Contractors and the like can also be revived with the previous role mostly intac var/mob/living/carbon/human/new_character = new()//The mob being spawned. - var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. - if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something - /*Try and locate a record for the person being respawned through data_core. - This isn't an exact science but it does the trick more often than not.*/ - var/id = md5("[G_found.real_name][G_found.mind.assigned_role]") - for(var/datum/data/record/t in data_core.locked) - if(t.fields["id"]==id) - record_found = t//We shall now reference the record. - break - - if(record_found)//If they have a record we can determine a few things. - new_character.real_name = record_found.fields["name"] - new_character.gender = record_found.fields["sex"] - new_character.age = record_found.fields["age"] - new_character.b_type = record_found.fields["b_type"] - new_character.dna_trace = record_found.fields["b_dna"] - new_character.fingers_trace = record_found.fields["fingerprint"] + if(G_found.client?.prefs)//If they have a record we can determine a few things. + G_found.client?.prefs.copy_to(new_character) else new_character.gender = pick(MALE,FEMALE) var/datum/preferences/A = new() @@ -376,12 +361,13 @@ Contractors and the like can also be revived with the previous role mostly intac //Now for special roles and equipment. SSjob.EquipRank(new_character, new_character.mind.assigned_role) + var/datum/computer_file/report/crew_record/record_found = get_crewmember_record(new_character.name) //Announces the character on all the systems, based on the record. if(!issilicon(new_character))//If they are not a cyborg/AI. if(!record_found && !player_is_antag(new_character.mind, only_offstation_roles = 1)) //If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. //Power to the user! - if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") - data_core.manifest_inject(new_character) + if(alert(new_character,"Warning: No record entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") + CreateModularRecord(new_character) if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") call(/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role) diff --git a/code/modules/asset_cache/assets/legacyuiicons.dm b/code/modules/asset_cache/assets/legacyuiicons.dm new file mode 100644 index 00000000000..5051a76d70a --- /dev/null +++ b/code/modules/asset_cache/assets/legacyuiicons.dm @@ -0,0 +1,5 @@ +/datum/asset/spritesheet/legacyicons + name = "oldicons" + +/datum/asset/spritesheet/legacyicons/create_spritesheets() + InsertAll("", 'icons/ui_icons/dmis/uiicons16.dmi') diff --git a/code/modules/client/preference_setup/background/03_records.dm b/code/modules/client/preference_setup/background/03_records.dm index cc694cf9528..54084ff6555 100644 --- a/code/modules/client/preference_setup/background/03_records.dm +++ b/code/modules/client/preference_setup/background/03_records.dm @@ -9,15 +9,9 @@ sort_order = 5 /datum/category_item/player_setup_item/background/records/load_character(savefile/S) - from_file(S["med_record"],pref.med_record) - from_file(S["sec_record"],pref.sec_record) - from_file(S["gen_record"],pref.gen_record) from_file(S["memory"],pref.memory) -/datum/category_item/player_setup_item/background/records/save_character(savefile/S) - to_file(S["med_record"],pref.med_record) - to_file(S["sec_record"],pref.sec_record) - to_file(S["gen_record"],pref.gen_record) +/datum/category_item/player_setup_item/background/records/save_character(var/savefile/S) to_file(S["memory"],pref.memory) /datum/category_item/player_setup_item/background/records/content(mob/user) @@ -26,33 +20,30 @@ if(jobban_isbanned(user, "Records")) . += "[span_danger("You are banned from using character records.")]
" else - . += "Medical Records: " - . += "[TextPreview(pref.med_record,40)]
" - . += "Employment Records: " - . += "[TextPreview(pref.gen_record,40)]
" - . += "Security Records: " - . += "[TextPreview(pref.sec_record,40)]
" + if(pref.med_record) + . += "Medical Records: " + . += "[TextPreview(pref.med_record,40)]
" + if(pref.gen_record) + . += "Employment Records: " + . += "[TextPreview(pref.gen_record,40)]
" + if(pref.sec_record) + . += "Security Records: " + . += "[TextPreview(pref.sec_record,40)]
" . += "Memory: " . += "[TextPreview(pref.memory,40)]
" . = jointext(.,null) /datum/category_item/player_setup_item/background/records/OnTopic(href,list/href_list, mob/user) if(href_list["set_medical_records"]) - var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.med_record = new_medical + input(user,"Read medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null return TOPIC_REFRESH else if(href_list["set_general_records"]) - var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.gen_record = new_general + input(user,"Read employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null return TOPIC_REFRESH else if(href_list["set_security_records"]) - var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.sec_record = sec_medical + input(user,"Read security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null return TOPIC_REFRESH else if(href_list["set_memory"]) @@ -62,3 +53,82 @@ return TOPIC_REFRESH . = ..() + +/datum/category_item/player_setup_item/background/records/proc/load_record(savefile/S, recordtype) + var/recordgiven = S["[recordtype]"] + if(S["version"] >= 19) + if(!recordgiven || !(recordtype in pref.vars)) + return FALSE + + if(istype(recordgiven, /datum/storedrecord)) + pref.vars[recordtype] = recordgiven + else + if(istext(recordgiven) && (recordtype in pref.vars)) + pref.vars[recordtype] = recordgiven + + + +/datum/storedrecord + +/datum/storedrecord/proc/transfertocomputer(datum/report_field/tofile) + // nobody here. +/datum/storedrecord/security + var/list/crimes = list() + var/list/evidence = list() + var/list/locations = list() + + +/datum/storedrecord/security/transfertocomputer(datum/report_field/tofile) + if(!istype(tofile, /datum/report_field/arraylinkage)) + return FALSE + var/datum/report_field/arraylinkage/toset = tofile + toset.arrays = list() + toset.arrays["crimes"] = crimes // edit these appropriately on any changes + toset.arrays["evidence"] = evidence // don't forget to synch these indexes + toset.arrays["locations"] = locations + +/datum/storedrecord/security/default // used by default + crimes = list("No crimes on record.") + evidence = list("N/A.") + locations = list("N/A.") + + +/datum/storedrecord/medical + var/list/prosthetics = list() + var/list/wounds = list() + var/list/bodystate = list() + var/list/chemhistory = list() + var/list/psychological = list() + + +/datum/storedrecord/medical/transfertocomputer(datum/report_field/tofile) + if(!istype(tofile, /datum/report_field/arrayclump)) + return FALSE + var/datum/report_field/arrayclump/toset = tofile + var/list/tochange = toset.value + tochange["prosthetics"] = prosthetics // change these appropriately as well + tochange["wounds"] = wounds // but as an arrayclump, they don't need synchronized indexing + tochange["Body state"] = bodystate + tochange["chemhistory"] = chemhistory + tochange["psychological"] = psychological + + +/datum/storedrecord/medical/default // used by default + prosthetics = list("No prosthetics on record.") + wounds = list("No wounds on record.") + bodystate = list("Alive at time of writing.") + chemhistory = list("Chemical record is clean.") + psychological = list("No psychological profiling has been done at time of writing.") + + +/datum/storedrecord/general + var/background // background is defined by fates + var/origin // origin is defined by origin + + + + +/datum/storedrecord/general/default // used by default + background = list("Unremarkable.") + origin = list("Origin unknown.") + diff --git a/code/modules/client/preference_setup/general/05_records.dm b/code/modules/client/preference_setup/general/05_records.dm deleted file mode 100644 index 5a246b16f99..00000000000 --- a/code/modules/client/preference_setup/general/05_records.dm +++ /dev/null @@ -1,64 +0,0 @@ -/datum/preferences - var/med_record = "" - var/sec_record = "" - var/gen_record = "" - var/memory = "" - -/datum/category_item/player_setup_item/physical/records - name = "Records" - sort_order = 5 - -/datum/category_item/player_setup_item/physical/records/load_character(savefile/S) - from_file(S["med_record"],pref.med_record) - from_file(S["sec_record"],pref.sec_record) - from_file(S["gen_record"],pref.gen_record) - from_file(S["memory"],pref.memory) - -/datum/category_item/player_setup_item/physical/records/save_character(savefile/S) - to_file(S["med_record"],pref.med_record) - to_file(S["sec_record"],pref.sec_record) - to_file(S["gen_record"],pref.gen_record) - to_file(S["memory"],pref.memory) - -/datum/category_item/player_setup_item/physical/records/content(mob/user) - . = list() - . += "
Records:
" - if(jobban_isbanned(user, "Records")) - . += "[span_danger("You are banned from using character records.")]
" - else - . += "Medical Records: " - . += "[TextPreview(pref.med_record,40)]
" - . += "Employment Records: " - . += "[TextPreview(pref.gen_record,40)]
" - . += "Security Records: " - . += "[TextPreview(pref.sec_record,40)]
" - . += "Memory: " - . += "[TextPreview(pref.memory,40)]
" - . = jointext(.,null) - -/datum/category_item/player_setup_item/physical/records/OnTopic(href,list/href_list, mob/user) - if(href_list["set_medical_records"]) - var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.med_record = new_medical - return TOPIC_REFRESH - - else if(href_list["set_general_records"]) - var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.gen_record = new_general - return TOPIC_REFRESH - - else if(href_list["set_security_records"]) - var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.sec_record = sec_medical - return TOPIC_REFRESH - - else if(href_list["set_memory"]) - var/memes = sanitize(input(user,"Enter memorized information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.memory)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(memes) && CanUseTopic(user)) - pref.memory = memes - return TOPIC_REFRESH - - . = ..() diff --git a/code/modules/client/preference_setup/loadout/lists/accessories.dm b/code/modules/client/preference_setup/loadout/lists/accessories.dm index 8ef7c68fba2..939ae4b7dae 100644 --- a/code/modules/client/preference_setup/loadout/lists/accessories.dm +++ b/code/modules/client/preference_setup/loadout/lists/accessories.dm @@ -43,7 +43,7 @@ /datum/gear/accessory/guild display_name = "armband, Aster's Guild" path = /obj/item/clothing/accessory/armband/cargo - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) /datum/gear/accessory/engineering display_name = "armband, Technomancer League" diff --git a/code/modules/client/preference_setup/loadout/lists/suits.dm b/code/modules/client/preference_setup/loadout/lists/suits.dm index aae61f2a909..2915bdfa18f 100644 --- a/code/modules/client/preference_setup/loadout/lists/suits.dm +++ b/code/modules/client/preference_setup/loadout/lists/suits.dm @@ -137,10 +137,10 @@ /datum/gear/suit/guild/black display_name = "black guild coat" path = /obj/item/clothing/suit/storage/cargo_jacket/black - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) /datum/gear/suit/guild/black/old display_name = "old black guild coat" path = /obj/item/clothing/suit/storage/cargo_jacket/black/old - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index eb54efa9128..30422fa437d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -239,10 +239,7 @@ for(var/lang in alternate_languages) character.add_language(lang) - - character.med_record = med_record - character.sec_record = sec_record - character.gen_record = gen_record + character.exploit_record = exploit_record if(!character.isSynthetic()) character.nutrition = rand(250, 450) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index d7d82c168db..3002912be54 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1,5 +1,5 @@ #define SAVEFILE_VERSION_MIN 8 -#define SAVEFILE_VERSION_MAX 18 +#define SAVEFILE_VERSION_MAX 19 /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) return diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index dbf3eeaa6a2..d0a84e987e6 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -37,8 +37,12 @@ return owner_name //Attempts to return the associated data record for this account +// expensive to run, store the result from this. /datum/money_account/proc/get_record() - return find_general_record("pay_account", account_number) + for(var/datum/computer_file/report/crew_record/CR in GLOB.all_crew_records) + var/accountnum = CR.get_account() + if(account_number == accountnum) + return CR /datum/transaction var/target_name = "" diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index d295a3712f3..c3fe3de3adc 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -118,9 +118,8 @@ var/mob/living/carbon/human/H = speaker if(H.voice) speaker_name = H.voice - for(var/datum/data/record/G in data_core.general) - if(G.fields["name"] == speaker_name) - return H.rank_prefix_name(speaker_name) + if(get_crewmember_record(speaker_name)) + return H.rank_prefix_name(speaker_name) return voice_name ? voice_name : speaker_name diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 3f1a9e16042..8bc4de7c34f 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -303,9 +303,10 @@ if(perpname) var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname) criminal = R ? R.get_criminalStatus() : "None" - msg += "\n" - msg += "Criminal status: \[[criminal]\]\n" - msg += "Security records: \[View\] \[Add comment\]\n" + + msg += "Criminal status: \[[criminal]\]\n" + msg += {"Security records: \[View\] \[View Brief\] + \[Add Note\]\n"} if(hasHUD(user, "medical")) var/perpname = "wot" @@ -317,16 +318,11 @@ perpname = id_card.registered_name else perpname = src.name + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + medical = E.get_status() - for (var/datum/data/record/E in data_core.general) - if (E.fields["name"] == perpname) - for (var/datum/data/record/R in data_core.general) - if (R.fields["id"] == E.fields["id"]) - medical = R.fields["p_stat"] - - msg += "\n" msg += "Physical status: \[[medical]\]\n" - msg += "Medical records: \[View\] \[Add comment\]\n" + msg += "Medical records: \[View\]\n" var/obj/item/clothing/under/U = w_uniform if(U && istype(U) && U.sensor_mode >= 2) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 42f79d430e8..c44d9367e7f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -429,21 +429,20 @@ var/list/rank_prefix = list(\ if(perpname) var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname) if(R) + modified = TRUE var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.get_criminalStatus()) in GLOB.security_statuses + "Cancel" - if(hasHUD(usr, "security")) - if(setcriminal != "Cancel") - R.set_criminalStatus(setcriminal) - modified = TRUE - BITSET(hud_updateflag, WANTED_HUD) - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - U.handle_regular_hud_updates() - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - U.handle_regular_hud_updates() + if(setcriminal != "Cancel") + R.set_criminalStatus(setcriminal) + BITSET(hud_updateflag, WANTED_HUD) + if(ishuman(usr)) + var/mob/living/carbon/human/U = usr + U.handle_regular_hud_updates() + if(isrobot(usr)) + var/mob/living/silicon/robot/U = usr + U.handle_regular_hud_updates() if(!modified) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) + to_chat(usr, span_red("Unable to locate a criminal record for this person.")) if(href_list["secrecord"]) if(hasHUD(usr,"security")) @@ -456,52 +455,50 @@ var/list/rank_prefix = list(\ else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]") - to_chat(usr, "Minor Crimes: [R.fields["mi_crim"]]") - to_chat(usr, "Details: [R.fields["mi_crim_d"]]") - to_chat(usr, "Major Crimes: [R.fields["ma_crim"]]") - to_chat(usr, "Details: [R.fields["ma_crim_d"]]") - to_chat(usr, "Notes: [R.fields["notes"]]") - to_chat(usr, "\[View Comment Log\]") - read = 1 + var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname) + if(CR) + to_chat(usr, "Name: [CR.get_name()] Criminal Status: [CR.get_criminalStatus()]") + var/datum/report_field/array/tofetch = CR.get_linkage_secNotes() + var/list/Briefing = tofetch.value_list + if(Briefing.len > 0) + var/list/combined = list() + for(var/iterator = min(Briefing.len-1, 3), iterator > -1, iterator -= 1) + combined.Add(Briefing[Briefing.len - iterator]) + to_chat(usr, "Briefing latest: "+combined.Join(", ")) + to_chat(usr, "\[Add to Brief\]") + to_chat(usr, "\[View Full Brief\]") + read = 1 if(!read) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) + to_chat(usr, span_red("Unable to locate a criminal record for this person.")) - if(href_list["secrecordComment"]) + if(href_list["viewbrief"]) if(hasHUD(usr,"security")) var/perpname = "wot" - var/read = 0 - var/obj/item/card/id/id = GetIdCard() - if(istype(id)) - perpname = id.registered_name + if(wear_id) + var/obj/item/card/id/id + if(istype(wear_id, /obj/item/modular_computer/pda)) + id = wear_id.GetIdCard() + if(!id) + id = get_idcard() + if(id) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - read = 1 - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, text("[]", R.fields[text("com_[]", counter)])) - counter++ - if(counter == 1) - to_chat(usr, "No comment found") - to_chat(usr, "\[Add comment\]") - - if(!read) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(!E) + to_chat(usr, span_danger("Unable to locate a record for this person.")) + return + var/datum/report_field/array/tofetch = E.get_linkage_secNotes() + var/list/Briefing = tofetch.value_list + if(Briefing.len > 0) + to_chat(usr, span_notice("Brief: " + Briefing.Join(", "))) + else + to_chat(usr, span_notice("[perpname] does not have a brief.")) - if(href_list["secrecordadd"]) + if(href_list["secnoteadd"]) if(hasHUD(usr,"security")) var/perpname = "wot" if(wear_id) @@ -510,32 +507,27 @@ var/list/rank_prefix = list(\ id = wear_id.GetIdCard() if(!id) id = get_idcard() - if(id) - perpname = id.registered_name + if(id) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - var/t1 = sanitize(input("Add Comment:", "Sec. records", null, null) as message) - if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) - return - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - counter++ - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR]
[t1]") - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR]
[t1]") + + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(!E) + to_chat(usr, span_warning("Record for [perpname] not found!")) + return + var/t1 = sanitize(input("Add to Brief:", "Sec. records", null, null) as text) + if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) + return + + var/datum/report_field/array/recordnote = E.get_linkage_secNotes() + + if(recordnote) + recordnote.add_value(t1) if(href_list["medical"]) if(hasHUD(usr,"medical")) var/perpname = "wot" - var/modified = 0 var/obj/item/card/id/id = GetIdCard() if(istype(id)) @@ -543,126 +535,49 @@ var/list/rank_prefix = list(\ else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.general) - if(R.fields["id"] == E.fields["id"]) - - var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*SSD*", "*Deceased*", "Physically Unfit", "Active", "Disabled", "Cancel") - - if(hasHUD(usr,"medical")) - if(setmedical != "Cancel") - R.fields["p_stat"] = setmedical - modified = 1 - if(PDA_Manifest.len) - PDA_Manifest.Cut() + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(E) + var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", E.get_status()) in GLOB.physical_statuses - spawn() - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - U.handle_regular_hud_updates() - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - U.handle_regular_hud_updates() + if(hasHUD(usr,"medical")) + if(setmedical != "Cancel") + E.set_status(setmedical) - if(!modified) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) - - if(href_list["medrecord"]) - if(hasHUD(usr,"medical")) - var/perpname = "wot" - var/read = 0 + spawn() + if(ishuman(usr)) + var/mob/living/carbon/human/U = usr + U.handle_regular_hud_updates() + if(isrobot(usr)) + var/mob/living/silicon/robot/U = usr + U.handle_regular_hud_updates() - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name else - perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - to_chat(usr, "Name: [R.fields["name"]] Blood Type: [R.fields["b_type"]]") - to_chat(usr, "DNA: [R.fields["b_dna"]]") - to_chat(usr, "Minor Disabilities: [R.fields["mi_dis"]]") - to_chat(usr, "Details: [R.fields["mi_dis_d"]]") - to_chat(usr, "Major Disabilities: [R.fields["ma_dis"]]") - to_chat(usr, "Details: [R.fields["ma_dis_d"]]") - to_chat(usr, "Notes: [R.fields["notes"]]") - to_chat(usr, "\[View Comment Log\]") - read = 1 - - if(!read) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) + to_chat(usr, span_red("Unable to locate a medical record for this person.")) - if(href_list["medrecordComment"]) + if(href_list["medrecord"]) if(hasHUD(usr,"medical")) var/perpname = "wot" var/read = 0 - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name + var/obj/item/card/id/id = GetIdCard() + if(istype(id)) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - read = 1 - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, text("[]", R.fields[text("com_[]", counter)])) - counter++ - if(counter == 1) - to_chat(usr, "No comment found") - to_chat(usr, "\[Add comment\]") + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + var/datum/report_field/arrayclump/M = E.get_linkage_medRecord() + if(E) + to_chat(usr, "Name: [E.get_name()] Blood Type: [E.get_bloodtype()]") + to_chat(usr, "DNA: [E.get_dna()]") + to_chat(usr, "Prosthetics: [M.value["prosthetics"]]") + to_chat(usr, "Recorded Wounds: [M.value["wounds"]]") + to_chat(usr, "Autopsy: [M.value["Body state"]]") + to_chat(usr, "Psychological Profile: [M.value["psychological"]]") + to_chat(usr, "Chemical History: [M.value["chemhistory"]]") + read = 1 if(!read) - to_chat(usr, span_red("Unable to locate a data core entry for this person.")) - - if(href_list["medrecordadd"]) - if(hasHUD(usr,"medical")) - var/perpname = "wot" - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name - else - perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) - if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) ) - return - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - counter++ - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR]
[t1]") - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [CURRENT_SHIP_YEAR]
[t1]") + to_chat(usr, span_red("Unable to locate a medical record for this person.")) if(href_list["lookitem"]) var/obj/item/I = locate(href_list["lookitem"]) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 66bba58d9aa..fd29cff4472 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -105,9 +105,6 @@ /// Extra overlays from equipped items var/list/equipment_overlays = list() - var/med_record = "" - var/sec_record = "" - var/gen_record = "" var/exploit_record = "" /// Whether this mob's ability to stand has been affected diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 43434ed760f..1881ffe5887 100755 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -500,17 +500,8 @@ default behaviour is: // Delete them from datacore. - if(PDA_Manifest.len) - PDA_Manifest.Cut() - for(var/datum/data/record/R in data_core.medical) - if ((R.fields["name"] == src.real_name)) - qdel(R) - for(var/datum/data/record/T in data_core.security) - if ((T.fields["name"] == src.real_name)) - qdel(T) - for(var/datum/data/record/G in data_core.general) - if ((G.fields["name"] == src.real_name)) - qdel(G) + var/datum/todelete = get_crewmember_record(name) + qdel(todelete) //This should guarantee that ghosts don't spawn. src.ckey = null diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 6181156b527..b5626805c2a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -543,8 +543,8 @@ var/list/ai_verbs_default = list( var/personnel_list[] = list() - for(var/datum/data/record/t in data_core.locked)//Look in data core locked. - personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image. + for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records) + personnel_list["[t.get_name()]: [t.get_job()]"] = t.photo_front//Pull names, rank, and image. if(personnel_list.len) input = input("Select a crew member:") as null|anything in personnel_list diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 50c307c0653..f0256ca095e 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -58,12 +58,10 @@ var/medHUD = FALSE // Toggles whether the Medical HUD is active or not var/medical_cannotfind = 0 - var/datum/data/record/medicalActive1 // Datacore record declarations for record software - var/datum/data/record/medicalActive2 + var/datum/data/record/medicalActive // Datacore record declarations for record software var/security_cannotfind = 0 - var/datum/data/record/securityActive1 // Could probably just combine all these into one - var/datum/data/record/securityActive2 + var/datum/data/record/securityActive var/obj/machinery/door/hackdoor // The airlock being hacked var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check @@ -158,11 +156,9 @@ set category = "pAI Commands" set name = "Reset Records Software" - securityActive1 = null - securityActive2 = null + securityActive = null security_cannotfind = 0 - medicalActive1 = null - medicalActive2 = null + medicalActive = null medical_cannotfind = 0 SSnano.update_uis(src) to_chat(usr, span_notice("You reset your record-viewing software.")) diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 9bc461a4e0d..ecd75855088 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -122,21 +122,19 @@ ram_cost = 5 id = "manifest" toggle = 0 + var/datum/nano_module/crew_manifest/manifestmodule + var/datum/topic_manager/program/mandatorymanager -/datum/pai_software/crew_manifest/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - data_core.get_manifest_json() +/datum/pai_software/crew_manifest/New() + mandatorymanager = new() + manifestmodule = new(src, mandatorymanager) - var/data[0] - // This is dumb, but NanoUI breaks if it has no data to send - data["manifest"] = list("__json_cache" = ManifestJSON) +/datum/pai_software/crew_manifest/Destroy() + . = ..() + QDEL_NULL(manifestmodule) - ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) +/datum/pai_software/crew_manifest/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=NANOUI_REINITIALIZE) + manifestmodule.nano_ui_interact(user, ui, "main", force_open) // transfers applicable vars to manifestmodule /* Medical Records */ /datum/pai_software/med_records @@ -147,51 +145,40 @@ /datum/pai_software/med_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) var/data[0] - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) + for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records) var/record[0] - record["name"] = general.fields["name"] + record["name"] = general.get_name() record["ref"] = "\ref[general]" records[++records.len] = record data["records"] = records - var/datum/data/record/G = user.medicalActive1 - var/datum/data/record/M = user.medicalActive2 - data["general"] = G ? G.fields : null - data["medical"] = M ? M.fields : null + var/datum/computer_file/report/crew_record/G = user.securityActive + var/datum/report_field/arrayclump/M = G?.get_linkage_medRecord() + data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \ +"job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "bloodtype" = G.get_bloodtype()) : null + data["prosthetics"] = M ? M.value["prosthetics"] : null + data["wounds"] = M ? M.value["wounds"] : null + data["Body state"] = M ? M.value["body state"] : null + data["chemhistory"] = M ? M.value["chemhistory"] : null + data["psychological"] = M ? M.value["psychological"] : null data["could_not_find"] = user.medical_cannotfind ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_medrecords.tmpl", "Medical Records", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) /datum/pai_software/med_records/Topic(href, href_list) var/mob/living/silicon/pai/P = usr if(!istype(P)) return if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = null - if (!( data_core.general.Find(R) )) - P.medical_cannotfind = 1 - else - P.medical_cannotfind = 0 - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - P.medicalActive1 = R - P.medicalActive2 = M + var/datum/computer_file/report/crew_record/record = locate(href_list["select"]) + if(istype(record)) + P.medical_cannotfind = 0 + P.medicalActive = record else P.medical_cannotfind = 1 - return 1 + return TRUE /* Security records */ /datum/pai_software/sec_records @@ -202,20 +189,19 @@ /datum/pai_software/sec_records/on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) var/data[0] - var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) + for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records) var/record[0] - record["name"] = general.fields["name"] + record["name"] = general.get_name() record["ref"] = "\ref[general]" records[++records.len] = record data["records"] = records - var/datum/data/record/G = user.securityActive1 - var/datum/data/record/S = user.securityActive2 - data["general"] = G ? G.fields : null - data["security"] = S ? S.fields : null + var/datum/computer_file/report/crew_record/G = user.securityActive + data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \ + "job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "criminalStatus" = G.get_criminalStatus(), \ + "secNotes" = G.get_linkage_secNotes()) : null data["could_not_find"] = user.security_cannotfind ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) @@ -231,26 +217,14 @@ if(!istype(P)) return if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/S = null - if (!( data_core.general.Find(R) )) - P.securityActive1 = null - P.securityActive2 = null - P.security_cannotfind = 1 - else - P.security_cannotfind = 0 - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - P.securityActive1 = R - P.securityActive2 = S + var/datum/computer_file/report/crew_record/record = locate(href_list["select"]) + if(istype(record)) + P.security_cannotfind = 0 + P.securityActive = record else - P.securityActive1 = null - P.securityActive2 = null + P.securityActive = null P.security_cannotfind = 1 - return 1 + return TRUE /* Door Jack */ /datum/pai_software/door_jack diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 70ad56658c0..fc5182f7f9b 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -448,11 +448,11 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT) if(id) perpname = id.registered_name - var/datum/data/record/R = find_security_record("name", perpname) - if(check_records && !R) + var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname) + if(check_records && !CR) threatcount += 4 - if(check_arrest && R && (R.fields["criminal"] == "*Arrest*")) + if(check_arrest && CR && (CR?.get_criminalStatus() == "*Arrest*")) // why is paperwork's folly being translated to electronic format? threatcount += 4 return threatcount diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index d4f9396b4fe..e47ecf75d29 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -332,7 +332,6 @@ if(SSjob.ShouldCreateRecords(job.title)) if(character.mind.assigned_role != "Robot") CreateModularRecord(character) - data_core.manifest_inject(character) matchmaker.do_matchmaking() SSticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index a60b9c5d019..677cd0dacce 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -308,6 +308,8 @@ SetName(initial(name)) /obj/item/modular_computer/proc/update_uis() + if(active_program && istype(active_program?.nanomodule_path, /datum/nano_module/tgui)) + return FALSE if(active_program) //Should we update program ui or computer ui? SSnano.update_uis(active_program) if(active_program.NM) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index e9cb4fa6618..6efb8fbc1b9 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -195,7 +195,10 @@ if(ui) ui.close() return computer.nano_ui_interact(user) - if(istype(NM)) + if(istype(NM, /datum/nano_module/tgui)) + NM.ui_interact(user) + return FALSE + else if(istype(NM)) NM.nano_ui_interact(user, ui_key, null, force_open) return 0 return 1 diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm index 50a46be6b0e..4e949a6c588 100644 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -62,7 +62,7 @@ data["security_jobs"] = format_jobs(security_positions) //data["exploration_jobs"] = format_jobs(exploration_positions) data["service_jobs"] = format_jobs(civilian_positions) - data["supply_jobs"] = format_jobs(cargo_positions) + data["supply_jobs"] = format_jobs(guild_positions) data["church_jobs"] = format_jobs(church_positions) //data["civilian_jobs"] = format_jobs(civilian_positions) data["centcom_jobs"] = format_jobs(get_all_centcom_jobs()) diff --git a/code/modules/modular_computers/file_system/programs/generic/records.dm b/code/modules/modular_computers/file_system/programs/generic/records.dm index 72bb6bdb81a..0cddabd2af0 100644 --- a/code/modules/modular_computers/file_system/programs/generic/records.dm +++ b/code/modules/modular_computers/file_system/programs/generic/records.dm @@ -1,3 +1,5 @@ + +#define NULL_RECORD list("name" = null, "uid" = null, "creator" = null, "file_time" = null, "fields" = null, "access" = null, "access_edit" = null) /datum/computer_file/program/records filename = "crewrecords" filedesc = "Crew Records" @@ -7,22 +9,22 @@ size = 14 requires_ntnet = TRUE available_on_ntnet = TRUE - nanomodule_path = /datum/nano_module/records + nanomodule_path = /datum/nano_module/tgui/records usage_flags = PROGRAM_ALL -/datum/nano_module/records +/datum/nano_module/tgui/records name = "Crew Records" var/datum/computer_file/report/crew_record/active_record var/message = null -/datum/nano_module/records/nano_ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = NANOUI_FOCUS, state = GLOB.default_state) +/datum/nano_module/tgui/records/ui_data(mob/user) var/list/data = host.initial_data() var/list/user_access = get_record_access(user) data["message"] = message if(active_record) - user << browse_rsc(active_record.photo_front, "front_[active_record.uid].png") - user << browse_rsc(active_record.photo_side, "side_[active_record.uid].png") + data["front_pic"] = icon2base64html(active_record.photo_front) + data["side_pic"] = icon2base64html(active_record.photo_side) data["pic_edit"] = check_access(user, access_heads) || check_access(user, access_security) data += active_record.generate_nano_data(user_access) else @@ -38,16 +40,20 @@ data["creation"] = check_access(user, access_heads) data["dnasearch"] = check_access(user, access_moebius) || check_access(user, access_forensics_lockers) data["fingersearch"] = check_access(user, access_security) + data += NULL_RECORD + return data +#undef NULL_RECORD + + - ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) +/datum/nano_module/tgui/records/ui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui || currentui) if (!ui) - ui = new(user, src, ui_key, "crew_records.tmpl", name, 700, 540, state = state) - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() + currentui = new(user, src, "CrewRecords", name) + currentui.open() -/datum/nano_module/records/proc/get_record_access(mob/user) +/datum/nano_module/tgui/records/proc/get_record_access(var/mob/user) var/list/user_access = using_access || user.GetAccess() var/obj/item/modular_computer/PC = nano_host() @@ -57,7 +63,7 @@ return user_access -/datum/nano_module/records/proc/edit_field(mob/user, field_ID) +/datum/nano_module/tgui/records/proc/edit_field(var/mob/user, var/field_ID) var/datum/computer_file/report/crew_record/R = active_record if(!R) return @@ -65,71 +71,72 @@ if(!F) return if(!F.verify_access_edit(get_record_access(user))) - to_chat(user, span_notice("\The [nano_host()] flashes an \"Access Denied\" warning.")) + to_chat(user, span_notice("The [nano_host()] flashes an \"Access Denied\" warning.")) return F.ask_value(user) -/datum/nano_module/records/Topic(href, href_list) +/datum/nano_module/tgui/records/ui_act(action, params) if(..()) return 1 - if(href_list["clear_active"]) - active_record = null - return 1 - if(href_list["clear_message"]) - message = null - return 1 - if(href_list["set_active"]) - var/ID = text2num(href_list["set_active"]) - for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) - if(R.uid == ID) - active_record = R - break - return 1 - if(href_list["new_record"]) - if(!check_access(usr, access_heads)) - to_chat(usr, "Access Denied.") - return - active_record = new/datum/computer_file/report/crew_record() - GLOB.all_crew_records.Add(active_record) - return 1 - if(href_list["print_active"]) - if(!active_record) - return - print_text(record_to_html(active_record, get_record_access(usr)), usr) - return 1 - if(href_list["search"]) - var/field_name = href_list["search"] - var/search = sanitize(input("Enter the value for search for.") as null|text) - if(!search) + switch(action) + + if("clear_active") + active_record = null return 1 - for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) - var/datum/report_field/field = R.field_from_name(field_name) - if(lowertext(field.get_value()) == lowertext(search)) - active_record = R + if("clear_message") + message = null + return 1 + if("set_active") + var/ID = text2num(params["set_active"]) + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + if(R.uid == ID) + active_record = R + break + return 1 + if("new_record") + if(!check_access(usr, access_heads)) + to_chat(usr, "Access Denied.") + return + active_record = new/datum/computer_file/report/crew_record() + GLOB.all_crew_records.Add(active_record) + return 1 + if("print_active") + if(!active_record) + return + print_text(record_to_html(active_record, get_record_access(usr)), usr) + return 1 + if("search") + var/field_name = params["search"] + var/search = sanitize(input("Enter the value for search for.") as null|text) + if(!search) return 1 - message = "Unable to find record containing '[search]'" - return 1 + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + var/datum/report_field/field = R.field_from_name(field_name) + if(lowertext(field.get_value()) == lowertext(search)) + active_record = R + return 1 + message = "Unable to find record containing '[search]'" + return 1 var/datum/computer_file/report/crew_record/R = active_record if(!istype(R)) return 1 - if(href_list["edit_photo_front"]) - var/photo = get_photo(usr) - if(photo && active_record) - active_record.photo_front = photo - nano_ui_interact(usr) - return 1 - if(href_list["edit_photo_side"]) - var/photo = get_photo(usr) - if(photo && active_record) - active_record.photo_side = photo - nano_ui_interact(usr) - return 1 - if(href_list["edit_field"]) - edit_field(usr, text2num(href_list["edit_field"])) - return 1 + switch(action) + if("edit_photo_front") + var/photo = get_photo(usr) + if(photo && active_record) + active_record.photo_front = photo + return 1 + if("edit_photo_side") + var/photo = get_photo(usr) + if(photo && active_record) + active_record.photo_side = photo + return 1 + if("edit_field") + edit_field(usr, text2num(params["edit_field"])) + return 1 -/datum/nano_module/records/proc/get_photo(mob/user) +/datum/nano_module/tgui/records/proc/get_photo(var/mob/user) if(istype(user.get_active_held_item(), /obj/item/photo)) var/obj/item/photo/photo = user.get_active_held_item() return photo.img diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm index a158121b5c7..c6fb06b2825 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -53,34 +53,131 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") // Medical record set_bloodtype(H ? H.b_type : "Unset") - set_medRecord((H && H.med_record && !jobban_isbanned(H.ckey, "Records") ? html_decode(H.med_record) : "No record supplied")) + var/datum/preferences/loadedprefs = H?.client?.prefs + var/datum/report_field/arrayclump/medRecord = get_linkage_medRecord() + if(H) + var/list/wounds = list() + var/list/prosthetics = list() + var/list/scannedlimbs = list() + for(var/datum/organ_description/OD in H.species.has_limbs) // default limbs for species + if(H.organs_by_name[OD.organ_tag]) + if(istype(H.organs_by_name[OD.organ_tag], OD.default_type)) // these lists contain abnormalilities, so normalities are skipped. + continue + else + var/obj/item/organ/external/organthing = H.organs_by_name[OD.organ_tag] + if(organthing.is_stump()) + wounds.Add("[organthing.name] instead of [OD.name]") + else + prosthetics.Add(organthing.name) + + scannedlimbs.Add(organthing) + // TODO: add organ checks once FBPs are better coded + else + wounds.Add("Missing [OD.name]") + var/list/addictions = list() + for(var/datum/reagent/addicted in H.metabolism_effects.addiction_list) + addictions.Add("Observed addicted to [addicted.name]") + + var/bodystate + switch(H.stat) + if(DEAD) + bodystate = list("Dead at time of writing") + if(UNCONSCIOUS) + if(H.getOxyLoss() > H.species.total_health/2) + bodystate = list("Comatose at time of writing") + else + bodystate = list("Alive at time of writing") + if(CONSCIOUS) + bodystate = list("Alive at time of writing") + + medRecord.value["wounds"] = wounds.len ? wounds : list("No wounds on record.") + medRecord.value["prosthetics"] = prosthetics.len ? prosthetics : list("No prosthetics on record.") + medRecord.value["Body state"] = bodystate ? bodystate : list("\[Data Missing\]") + medRecord.value["chemhistory"] = addictions.len ? addictions : list("Chemical record is clean.") + + var/list/psychological = list() + for(var/datum/perk/profile in H.stats.perks) + switch(profile.type) + if(PERK_NIHILIST) + psychological.Add("Has an empty outlook on life.") + if(PERK_MORALIST) + psychological.Add("High morale in groups.") + if(PERK_DRUG_ADDICT) + psychological.Add("Easily addicted, remains addicted indefinitely.") + if(PERK_ALCOHOLIC) + psychological.Add("Psychologically dependent on alcohol.") + if(PERK_REJECTED_GENIUS, PERK_NOBLE) + psychological.Add("Mentally destabilized by minor stressing factors.") + if(PERK_RAT) + psychological.Add("Innately stressed by environments, to some degree.") + if(PERK_PAPER_WORM) + psychological.Add("Accustomed to over-stress.") + if(PERK_OBORIN_SYNDROME) + psychological.Add("Innately resilient to mental harm.") + if(PERK_LOWBORN, PERK_VAGABOND) + psychological |= "Accustomed to bad living conditions." + if(PERK_SURVIVOR) + psychological.Add("Accustomed to the presence of death.") + if(PERK_NEAT) + psychological.Add("Accustomed to the presence of grime, and comforted by its removal.") + if(PERK_GREEN_THUMB) + psychological.Add("Comforted by gardening.") + if(PERK_CLUB) + psychological.Add("Provides a comfortingly professional presence.") + if(PERK_CHAINGUN_SMOKER) + psychological.Add("Invigorated by smoking.") + if(PERK_CHARMING_PERSONALITY) + psychological.Add("Provides a comfortingly charming presence.") + if(PERK_HORRIBLE_DEEDS) + psychological.Add("UNSETTLING.") + if(PERK_TERRIBLE_FATE) + psychological.Add("More afraid of death than usual.") + if(PERK_BALLS_OF_PLASTEEL) + psychological.Add("Higher pain tolerance than otherwise indicated.") + if(PERK_ARTIST) + psychological.Add("Looks at life as art.") + + medRecord.value["psychological"] = psychological.len ? psychological : list("No psychological abnormality at time of writing.") + else // if there isn't a human + var/datum/storedrecord/medical/default/medrecord = new() // just use the defaults + medrecord.transfertocomputer(medRecord) + qdel(medrecord) // Security record set_criminalStatus(GLOB.default_security_status) set_dna(H ? H.dna_trace : "") set_fingerprint(H ? H.fingers_trace : "") - set_secRecord(H && H.sec_record && !jobban_isbanned(H.ckey, "Records") ? html_decode(H.sec_record) : "No record supplied") - // Employment record - var/employment_record = "No record supplied" if(H) - if(H.gen_record && !jobban_isbanned(H.ckey, "Records")) - employment_record = html_decode(H.gen_record) - if(H.client && H.client.prefs) - var/list/qualifications - if(LAZYLEN(qualifications)) - employment_record = "[employment_record ? "[employment_record]\[br\]" : ""][jointext(qualifications, "\[br\]>")]" - set_emplRecord(employment_record) - - - if(H) - var/stats = list() - for(var/statName in ALL_STATS) - var/points = H.stats.getStat(statName,pure = TRUE) - if(points > STAT_LEVEL_NONE) - stats += "[statName]: [points] ([statPointsToLevel(points)])" + for(var/datum/perk/fate/profile in H.stats.perks) + switch(profile) + if(PERK_PAPER_WORM) + set_emplRecord("Experienced in bureacracy.") + if(PERK_FREELANCER) + set_emplRecord("Wide variety of employments.") + if(PERK_DRUG_ADDICT) + set_emplRecord("Has a history of drug addiction.") + if(PERK_ALCOHOLIC) + set_emplRecord("Is an alcoholic.") + if(PERK_NOBLE) + set_emplRecord("Is of noble origin.") + if(PERK_LOWBORN) + set_emplRecord("Was hired from poverty.") + if(!get_emplRecord()) + set_emplRecord("Standard background.") + else + set_emplRecord("No record supplied.") - set_skillset(jointext(stats,"\n")) + if(loadedprefs) + var/originfound + for(var/datum/category_group/setup_option_category/background/origin/OriginBG in loadedprefs.setup_options) + if(loadedprefs.loaded_character[OriginBG.name]) + originfound = OriginBG.name + break + if(originfound) + set_origin(originfound) + else + set_origin("Origin not on record.") // Antag record set_antagRecord(H && H.exploit_record && !jobban_isbanned(H, "Records") ? html_decode(H.exploit_record) : "") @@ -96,16 +193,16 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") /proc/SortModularRecords() // improved bubble sort - if(GLOB.all_crew_records.len > 1) - for(var/i = 1; i <= GLOB.all_crew_records.len; i++) - var/flag = FALSE - for(var/j = 1; j <= GLOB.all_crew_records.len - 1; j++) - var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j] - var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1] - if(sorttext(CR.get_name(), CR_NEXT.get_name()) == -1) - flag = TRUE - GLOB.all_crew_records.Swap(j,j+1) - if(!flag) + if(GLOB.all_crew_records.len > 1) // if list is big enough to sort + for(var/i = 1, i <= GLOB.all_crew_records.len, i++) // for each entry in list + var/flag = FALSE // define a var as false + for(var/j = GLOB.all_crew_records.len-1, j >= 1, j--) // cycle through all entries, + var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j] // starting from the one before the last + var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1] // and the last + if(sorttext(CR.get_name(), CR_NEXT.get_name()) == 1) // if the one before the last is bigger than the last + flag = TRUE // reset the var to true + GLOB.all_crew_records.Swap(j,j+1) // and swap the last and the one before the last + if(!flag) // if no work was done, stop break // Gets crew records filtered by set of positions @@ -161,9 +258,13 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") #define GETTER_SETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_##KEY(){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) return F.get_value()} \ /datum/computer_file/report/crew_record/proc/set_##KEY(given_value){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) F.set_value(given_value)} +#define SELF_GETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_linkage_##KEY(){return locate(/datum/report_field/##PATH/##KEY) in fields} #define SETUP_FIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) GETTER_SETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\ /datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\ KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} +#define SETUP_ARRAYFIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) SELF_GETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\ +/datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\ +KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} // Fear not the preprocessor, for it is a friend. To add a field, use one of these, depending on value type and if you need special access to see it. // It will also create getter/setter procs for record datum, named like /get_[key here]() /set_[key_here](value) e.g. get_name() set_name(value) @@ -174,6 +275,8 @@ KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} #define FIELD_LIST(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) #define FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) SETUP_FIELD(NAME, KEY, options/crew_record, ACCESS, ACCESS_EDIT);\ /datum/report_field/options/crew_record/##KEY/get_options(){return OPTIONS} +#define ARRAYFIELD_SINGLE(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, array/crew_record, ACCESS, ACCESS_EDIT) +#define ARRAYFIELD_CLUMP(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, arrayclump/crew_record, ACCESS, ACCESS_EDIT) // GENERIC RECORDS FIELD_SHORT("Name", name, null, access_change_ids) @@ -189,17 +292,17 @@ FIELD_NUM("Account",account, null, access_change_ids) // MEDICAL RECORDS FIELD_LIST("Blood Type", bloodtype, GLOB.blood_types, access_moebius, access_moebius) -FIELD_LONG("Medical Record", medRecord, access_moebius, access_moebius) +ARRAYFIELD_CLUMP("Medical Record", medRecord, access_moebius, access_moebius) // SECURITY RECORDS FIELD_LIST("Criminal Status", criminalStatus, GLOB.security_statuses, access_security, access_security) -FIELD_LONG("Security Record", secRecord, access_security, access_security) +ARRAYFIELD_SINGLE("Brief", secNotes, access_security, access_security) FIELD_SHORT("DNA", dna, access_security, access_security) FIELD_SHORT("Fingerprint", fingerprint, access_security, access_security) // EMPLOYMENT RECORDS FIELD_LONG("Employment Record", emplRecord, access_heads, access_heads) -FIELD_LONG("Qualifications", skillset, access_heads, access_heads) +FIELD_LONG("Place of origin", origin, access_heads, access_heads) // ANTAG RECORDS FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_syndicate) @@ -240,9 +343,13 @@ FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_synd . |= BR.name */ #undef GETTER_SETTER +#undef SELF_GETTER #undef SETUP_FIELD +#undef SETUP_ARRAYFIELD #undef FIELD_SHORT #undef FIELD_LONG #undef FIELD_NUM #undef FIELD_LIST #undef FIELD_LIST_EDIT +#undef ARRAYFIELD_SINGLE +#undef ARRAYFIELD_CLUMP diff --git a/code/modules/modular_computers/file_system/reports/report.dm b/code/modules/modular_computers/file_system/reports/report.dm index 2be0080d016..94fe1ded684 100644 --- a/code/modules/modular_computers/file_system/reports/report.dm +++ b/code/modules/modular_computers/file_system/reports/report.dm @@ -133,7 +133,22 @@ If the override option is set to 0, the access supplied will instead be added as dat["access"] = field.verify_access(given_access) dat["access_edit"] = field.verify_access_edit(given_access) dat["name"] = field.display_name() - dat["value"] = field.get_value() + + if(istype(field, /datum/report_field/array)) + var/datum/report_field/array/arrayfield = field + dat["list_value"] = arrayfield.value_list.Copy() + dat["list_clumps"] = null // must override with null values or else react gets weird + dat["value"] = null + else if(istype(field, /datum/report_field/arrayclump)) + var/datum/report_field/arrayclump/clumpfield = field + dat["list_value"] = null + dat["list_clumps"] = clumpfield.value + dat["value"] = null + else + dat["list_value"] = null + dat["list_clumps"] = null + dat["value"] = field.get_value() + dat["can_edit"] = field.can_edit dat["needs_big_box"] = field.needs_big_box dat["ignore_value"] = field.ignore_value diff --git a/code/modules/modular_computers/file_system/reports/report_field.dm b/code/modules/modular_computers/file_system/reports/report_field.dm index f453d8c2f9a..b09fb51db6f 100644 --- a/code/modules/modular_computers/file_system/reports/report_field.dm +++ b/code/modules/modular_computers/file_system/reports/report_field.dm @@ -211,4 +211,151 @@ Basic field subtypes. value_list.Remove(given_value) /datum/report_field/array/ask_value(mob/user) - add_value(input(user, "Add value", "") as null|text) + var/inputchoice = input(user, "Add or Remove value", "Field Edit", "Add") in list("Add", "Remove") + if(inputchoice == "Add") + var/toadd = input(user, "Add value", "Field Input") as null|text + if(!isnull(toadd)) + add_value(toadd) + else if(inputchoice == "Remove") + remove_value(input(user, "Choose value to remove", "Field Reduce") as null|anything in value_list ) + + + +/datum/report_field/arraylinkage + var/list/arrays = list() + ignore_value = TRUE // value is too generic to use + +// retrieves index of key +// can retrieve additional entries of same index using additionalarrays param +/datum/report_field/arraylinkage/proc/retrieve_index_of_array(key, index = 0, additionalarrays = list()) + if(!(key && (arrays.len > 0) && index > 0)) // can we access? + return FALSE + var/primeretrieved = arrays[key] // key's array + if(!(index && primeretrieved && length(primeretrieved) >= index)) // can we access the index asked for using the key? + return FALSE + var/list/toreturn = list(primeretrieved[index]) + for(var/arrayexists in additionalarrays) // all linked arrays we also want index of + if((arrayexists in arrays) && length(arrays[arrayexists]) >= index) + var/list/toadd = arrays[arrayexists] + toreturn.Add(toadd[index]) + else + return FALSE // we really don't want input from bad sources. + . = toreturn // succeeded all the checks? caller's will be done. + +// adds one index to the end of each list +// sets the contents of each list for the created index on demand using either keys or arrangement of any given input of proper size +/datum/report_field/arraylinkage/proc/add_index(list/new_entries, keyed = FALSE) + if(!new_entries || new_entries.len > arrays.len) + return FALSE + if(new_entries.len != arrays.len) // only accept using list-order based indexing when it has a 1 to 1 ratio + keyed = TRUE + var/count = 1 + if(keyed) + for(var/key in arrays) // unfitting keys are discarded, but can still disqualify a list. + var/list/currentarray = arrays[key] + if(new_entries[key]) + currentarray.Add(new_entries[key]) + else + currentarray.Add(null) // all arrays must have the same indexing for the linkage to work. + . = TRUE + else + for(var/entry in new_entries) // sanitize before it's t oo late + if(new_entries[entry]) + CRASH("keyed outside of key mode in add_index") + for(var/entry in new_entries) + var/list/currentarray = arrays?[count] + if(!currentarray) // in case a check breaks + return + count ++ + currentarray.Add(entry) + . = TRUE + +// set one entry in one list +/datum/report_field/arraylinkage/proc/edit_index(key, setto, index) + if(!arrays[key] || length(arrays[key]) < index || !islist(arrays[key])) + return FALSE + var/list/accessed = arrays[key] + if(accessed) + accessed[index] = setto + . = TRUE + +// delete one index of all lists in arraylinkage +/datum/report_field/arraylinkage/proc/remove_index(index) + if(!length(arrays) || length(arrays[1]) < index) // check if there are arrays and the first one is long enough + return FALSE // hopefully all arrays have the same length as the first one + for(var/list/arraytocut in arrays) + arraytocut.Cut(index, index+1) + . = TRUE + +/datum/report_field/arraylinkage/ask_value(mob/user) + +/datum/report_field/arrayclump // these arrays are explicitly unlinked and are stored here for categorization + value = list() // only input key=array as entry + +/datum/report_field/arrayclump/set_value(given_value) + if(!islist(given_value)) + return FALSE + . = ..() + +/datum/report_field/arrayclump/ask_value(mob/user) + . = TRUE + var/list/clumpvalue = value + if(!istype(clumpvalue)) + return FALSE + var/list/entries = clumpvalue.Copy() + entries.Add("") + + var/entrychoice = input(user, "Choose Entry Category", "Entry Category") as null | anything in entries + if(entrychoice == "" ) + var/entryname = input(user, "Choose Entry Name", "Entry Name") as text | null + entryname = sanitizeSafe(entryname) + if(!istext(entryname)) + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + if(clumpvalue[entryname]) // only replace entry with alert + if(alert(user, "Replace old entry?", "Entry Replacement", "Yes", "No") == "No") + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + var/startingvalue = input(user, "Create Entry", "Entry Creation") as text | null + startingvalue = sanitizeSafe(startingvalue) + if(!istext(startingvalue)) + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + to_chat(user, SPAN_NOTICE("You have successfully added an entry to [name].")) + value[entryname] = list(startingvalue) + + else if(entrychoice) + var/list/selections = clumpvalue[entrychoice] + selections = selections.Copy() // don't edit the original list + selections.Add("") + var/selectionchoice = input(user, "Select Entry", "Entry") as null | anything in selections + if(!istext(selectionchoice)) + return FALSE + if(selectionchoice == "") + var/nextvalue = input(user, "Add Value", "Value") as text | null + nextvalue = sanitizeSafe(nextvalue) + if(!istext(nextvalue)) + to_chat(user, SPAN_NOTICE("Addition canceled successfully.")) + return FALSE + else + var/list/entrytoaddto = clumpvalue[entrychoice] + if(istype(entrytoaddto)) + entrytoaddto.Add(nextvalue) + else + CRASH("Type Mismatch in clump list") + + else + var/newvalue = input(user, "New Value", "Value") as text | null + newvalue = sanitizeSafe(newvalue) + if(!istext(newvalue)) + to_chat(user, SPAN_NOTICE("Replacement canceled successfully.")) + return FALSE + var/list/intermediaryvalue = clumpvalue[entrychoice] + if(istype(intermediaryvalue)) + var/indexhound = clumpvalue.Find(intermediaryvalue) // the Hound finds the value we splice + intermediaryvalue.Splice(indexhound, indexhound+1, newvalue) + else + CRASH("Type Mismatch in clump list") + + + diff --git a/code/modules/nano/modules/tgui_type.dm b/code/modules/nano/modules/tgui_type.dm new file mode 100644 index 00000000000..e605715301b --- /dev/null +++ b/code/modules/nano/modules/tgui_type.dm @@ -0,0 +1,92 @@ +/datum/nano_module/tgui + var/datum/tgui/currentui // gotta save it, we can't get it any other way + var/show_map ; var/map_z_level // the sins of our predecessors, brought to the present by the sins of our own + +/datum/nano_module/tgui/ui_host(mob/user) + return nano_host() + +/datum/nano_module/tgui/ui_close(mob/user) + . = ..() + currentui = null // must clear reference to ui + +/datum/nano_module/tgui/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/legacyicons) + ) + + +/datum/nano_module/tgui/ui_act(action, params) + . = ..() + + if(istype(host, /datum/computer_file/program)) + var/datum/computer_file/program/program = host + switch(action) + if("PC_exit") + program.computer.kill_program() + return TRUE + if("PC_enable_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H) && !H.enabled) + H.enabled = TRUE + H.enabled() + . = TRUE + if("PC_disable_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H) && H.enabled) + H.enabled = FALSE + H.disabled() + . = TRUE + if("PC_toggle_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H)) + H.enabled = !H.enabled + if(H.enabled) + H.enabled() + else + H.disabled() + . = TRUE + if("PC_shutdown") + program.computer.shutdown_computer() + return TRUE + if("PC_minimize") + var/mob/user = usr + program.computer.minimize_program(user) + + if("PC_killprogram") + var/prog_name = params["PC_killprogram"] + var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer + if(!prog_disk) + return TRUE + + for(var/p in program.computer.all_threads) + var/datum/computer_file/program/PRG = p + if(PRG.program_state == PROGRAM_STATE_KILLED) + continue + + if(PRG.filename == prog_name && (PRG in prog_disk.stored_files)) + PRG.kill_program(forced=TRUE) + to_chat(usr, SPAN_NOTICE("Program [PRG.filename].[PRG.filetype] has been killed.")) + . = TRUE + + if("PC_runprogram") + var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer + return program.computer.run_program(params["PC_runprogram"], prog_disk) + + if("PC_setautorun") + if(!program.computer.hard_drive) + return + program.computer.set_autorun(params["PC_setautorun"]) + if("PC_terminal") + program.computer.open_terminal(usr) + return TRUE + +/datum/nano_module/tgui/ui_status(mob/user, datum/ui_state/state) + . = ..(user, state ? state : GLOB.default_state) + if(. > UI_DISABLED && istype(host, /datum/computer_file/program)) + var/datum/computer_file/program/relevant = host + if(relevant.program_state == PROGRAM_STATE_KILLED) + . = UI_CLOSE + else if(relevant.program_state == PROGRAM_STATE_BACKGROUND) + . = min(., UI_UPDATE) // theoretically might be necessary with a new system, if redundant just collapse this with the killing check. + + diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index da13f74c193..2e347f91a1d 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -107,22 +107,12 @@ /obj/structure/filingcabinet/security/populate() if(virgin) - for(var/datum/data/record/G in data_core.general) - var/datum/data/record/S - for(var/datum/data/record/R in data_core.security) - if((R.fields["name"] == G.fields["name"] || R.fields["id"] == G.fields["id"])) - S = R - break + for(var/datum/computer_file/report/crew_record/G in GLOB.all_crew_records) var/obj/item/paper/P = new /obj/item/paper(src) P.info = "
Security Record

" - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nSex: [G.fields["sex"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
" - P.info += "
\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 00000000000..7b5d90ace41 Binary files /dev/null and b/icons/ui_icons/dmis/uiicons16.dmi differ diff --git a/maps/CEVEris/_CEV_Eris.dmm b/maps/CEVEris/_CEV_Eris.dmm index 7cb20aa7fbd..0518d04520b 100644 --- a/maps/CEVEris/_CEV_Eris.dmm +++ b/maps/CEVEris/_CEV_Eris.dmm @@ -102878,6 +102878,14 @@ }, /turf/floor/plating/under, /area/eris/maintenance/sorter) +"qmi" = ( +/obj/item/cell/medium, +/obj/item/cell/medium, +/obj/item/computer_hardware/processor_unit, +/obj/item/computer_hardware/tesla_link, +/obj/item/computer_hardware/tesla_link, +/turf/floor/hull, +/area/space) "qmJ" = ( /obj/machinery/door/blast/shutters{ dir = 4; @@ -104987,6 +104995,13 @@ }, /turf/floor/plating/under, /area/eris/maintenance/section3deck5port) +"tZv" = ( +/obj/item/computer_hardware/network_card/wired, +/obj/item/computer_hardware/network_card/wired, +/obj/item/computer_hardware/scanner/paper, +/obj/item/computer_hardware/scanner/paper, +/turf/floor/hull, +/area/space) "tZw" = ( /obj/structure/cable/green{ d1 = 4; @@ -205277,7 +205292,7 @@ iEk cBO cwU abF -abF +qmi abF cwU cwU @@ -205479,7 +205494,7 @@ cBO cos cwU abF -abF +tZv abF abF cwU diff --git a/nano/templates/crew_records.tmpl b/nano/templates/crew_records.tmpl index 543879ebe0d..009496403e1 100644 --- a/nano/templates/crew_records.tmpl +++ b/nano/templates/crew_records.tmpl @@ -28,6 +28,27 @@ {{if value.needs_big_box}}
{{:value.value}} + {{else}} + {{if value.list_value}} + {{for value.list_value}} + {{:value}} + {{/for}} + {{else}} + {{if value.list_clumps}} + {{for value.list_clumps}} + {{for value}} + {{:value}} + {{/for}} + {{/for}} + {{else}} + {{if value.links}} + {{for 1 to value.links.len}} + {{for value.links}} + + {{/if}} + {{/if}} + {{/if}} + {{/if}}
{{else}}
{{:value.value}}
diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl index 37b1d7061ca..b45d66cd2c9 100644 --- a/nano/templates/pai_medrecords.tmpl +++ b/nano/templates/pai_medrecords.tmpl @@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,50 +28,52 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
=Status
+
{{:data.general.status}}
-
Mental Status
-
{{:data.general.m_stat}}
+
Blood Type
+
{{:data.general.bloodtype}}
{{/if}} {{if data.medical}}
-
Blood Type
-
{{:data.medical.b_type}}
-
-
-
Minor Disabilities
-
{{:data.medical.mi_dis}}
-
{{:data.medical.mi_dis_d}}
+
Prosthetics
+ {{for data.medical.value.prosthetics}} +
{{:value}}
+ {{/for}}
-
Major Disabilities
-
{{:data.medical.ma_dis}}
-
{{:data.medical.ma_dis_d}}
+
Wounds
+ {{for data.medical.value.wounds}} +
{{:value}}
+ {{/for}}
-
Allergies
-
{{:data.medical.alg}}
-
{{:data.medical.alg_d}}
+
Body State
+ {{for data.medical.value.body state}} +
{{:value}}
+ {{/for}}
-
Current Diseases
-
{{:data.medical.cdi}}
-
{{:data.medical.cdi_d}}
+
Chemical History
+ {{for data.medical.value.chemhistory}} +
{{:value}}
+ {{/for}}
-
Important Notes
-
{{:data.medical.notes}}
+
Psychological Profile
+ {{for data.medical.value.psychological}} +
{{:value}}
+ {{/for}}
{{/if}} diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl index e139034c0de..cdb3321a07c 100644 --- a/nano/templates/pai_secrecords.tmpl +++ b/nano/templates/pai_secrecords.tmpl @@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,40 +28,24 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
Status
+
{{:data.general.status}}
-
-
Mental Status
-
{{:data.general.m_stat}}
-
-{{/if}} -{{if data.security}}
Criminal Status
-
{{:data.security.criminal}}
-
-
-
Minor Crimes
-
{{:data.security.mi_crim}}
-
{{:data.security.mi_crim_d}}
-
-
-
Major Crimes
-
{{:data.security.ma_crim}}
-
{{:data.security.ma_crim_d}}
-
+
{{:data.general.criminalStatus }}
+
Important Notes
-
{{:data.security.notes}}
+
{{:data.general.secNotes}}
{{/if}} diff --git a/tgui/packages/tgui/interfaces/Computer.tsx b/tgui/packages/tgui/interfaces/Computer.tsx new file mode 100644 index 00000000000..9da923a2ae7 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Computer.tsx @@ -0,0 +1,173 @@ +import { Box, Button, Table } from 'tgui-core/components'; +import { BooleanLike } from 'tgui-core/react'; + +import { sendAct } from '../backend'; + +export interface ComputerInterface { + PC_batteryicon: string; + PC_batterypercent: string; + PC_showbatteryicon: BooleanLike; + PC_light_name: string; + PC_light_on: BooleanLike; + PC_apclinkicon: string; + PC_ntneticon: string; + has_gps: BooleanLike; + gps_icon: string; + gps_data: string; + PC_programheaders: Programheader[]; + PC_stationtime: string; + PC_hasheader: BooleanLike; + PC_showexitprogram: BooleanLike; + mapZLevels: number[]; + mapZLevel: number; +} + +type Programheader = { + icon: string; +}; + +export const ProgramShell = (props: ComputerInterface) => { + const { + PC_batteryicon, + PC_batterypercent, + PC_showbatteryicon, + PC_light_name, + PC_light_on, + PC_apclinkicon, + PC_ntneticon, + has_gps, + gps_icon, + gps_data, + PC_programheaders, + PC_stationtime, + PC_hasheader, + PC_showexitprogram, + mapZLevels, + mapZLevel, + } = props; + const act = sendAct; + return ( + <> + + { + // 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, i) => ( + + + + ))} + +
+
+
+ + + + {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..1609553f36c --- /dev/null +++ b/tgui/packages/tgui/interfaces/CrewRecords.tsx @@ -0,0 +1,344 @@ +import { Box, Button, Divider, Table } from 'tgui-core/components'; +import { BooleanLike } from 'tgui-core/react'; +import { classes } from 'tgui-core/react'; + +import { sendAct, useBackend } from '../backend'; +import { GameIcon } from '../components/GameIcon'; +import { Window } from '../layouts'; +import { ComputerInterface, ProgramShell } from './Computer'; + +interface CrewRecordsInterface extends RecordConcrete, ComputerInterface { + message: string; + front_pic: string; + side_pic: string; + pic_edit: BooleanLike; + all_records: RecordAbstract[]; + creation: BooleanLike; + dnasearch: BooleanLike; + fingersearch: BooleanLike; +} + +interface RecordConcrete { + name: string; + uid: number; + creator: string; + filetime: string; + fields: RecordField[]; + access: BooleanLike; + access_edit: BooleanLike; +} +type RecordField = { + access: BooleanLike; + access_edit: BooleanLike; + name: string; + value: string | number | object; + list_value: any[]; + list_clumps: object[]; + can_edit: BooleanLike; + needs_big_box: BooleanLike; + ignore_value: BooleanLike; + ID: number; +}; + +type RecordAbstract = { + name: string; + rank: string; + id: number; +}; + +export const CrewRecords = (props: ComputerInterface) => { + const { act, data } = useBackend(); + const { + message, + uid, + fields, + front_pic, + side_pic, + pic_edit, + all_records, + creation, + dnasearch, + fingersearch, + } = data; + return ( + + + {ProgramShell(props)} + {message &&