From bc83fc1e9f42e960a95b4e9621e5ad16a2e7d924 Mon Sep 17 00:00:00 2001 From: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com> Date: Fri, 26 Aug 2022 19:25:48 -0400 Subject: [PATCH] Makes the game start faster by optimizing round-start manifest injections (#69393) * Massively optimizes the manifest_inject() proc by relaying the creation of the Security Records pictures to be on-demand * Implements the change in the Security records and improves the photo's resolution as well * Implements the change in the Medical records and improves the photo's resolution as well * Updates the usage of the photos in human code * Actually makes AI holograms still work with this new change * Makes the appearance_holder a static variable, to avoid having to re-instanciate it all the time * Uses the mutable_appearance instead of a static atom/movable/screen * Less static atom/movable/screen stuff in the AI code too * Removes my funny comment :( * Removes some redundant null checks * Updates the documentation for get_flat_human_icon() and get_flat_existing_human_icon() * Removes get_id_photo() as it's no longer used --- code/__HELPERS/icons.dm | 6 +- code/datums/datacore.dm | 83 +++++++++++++------ code/game/machinery/computer/medical.dm | 34 ++++---- code/game/machinery/computer/security.dm | 58 +++++++------ code/modules/mob/living/carbon/human/human.dm | 4 +- code/modules/mob/living/silicon/ai/ai.dm | 9 +- 6 files changed, 120 insertions(+), 74 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index b551f7886b7..6eb9a2e40dc 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1050,7 +1050,8 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) return J return 0 -//For creating consistent icons for human looking simple animals +/// # If you already have a human and need to get its flat icon, call `get_flat_existing_human_icon()` instead. +/// For creating consistent icons for human looking simple animals. /proc/get_flat_human_icon(icon_id, datum/job/job, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null) var/static/list/humanoid_icon_cache = list() if(icon_id && humanoid_icon_cache[icon_id]) @@ -1082,7 +1083,8 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) * A simpler version of get_flat_human_icon() that uses an existing human as a base to create the icon. * Does not feature caching yet, since I could not think of a good way to cache them without having a possibility * of using the cached version when we don't want to, so only use this proc if you just need this flat icon - * generated once. + * generated once and handle the caching yourself if you need to access that icon multiple times, or + * refactor this proc to feature caching of icons. * * Arguments: * * existing_human - The human we want to get a flat icon out of. diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index cc741243d09..46dfadaffc3 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -19,16 +19,61 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) var/list/fields = list() /datum/data/record/Destroy() - if(src in GLOB.data_core.medical) - GLOB.data_core.medical -= src - if(src in GLOB.data_core.security) - GLOB.data_core.security -= src - if(src in GLOB.data_core.general) - GLOB.data_core.general -= src - if(src in GLOB.data_core.locked) - GLOB.data_core.locked -= src + GLOB.data_core.medical -= src + GLOB.data_core.security -= src + GLOB.data_core.general -= src + GLOB.data_core.locked -= src . = ..() +/// A helper proc to get the front photo of a character from the record. +/// Handles calling `get_photo()`, read its documentation for more information. +/datum/data/record/proc/get_front_photo() + return get_photo("photo_front", SOUTH) + +/// A helper proc to get the side photo of a character from the record. +/// Handles calling `get_photo()`, read its documentation for more information. +/datum/data/record/proc/get_side_photo() + return get_photo("photo_side", WEST) + +/** + * You shouldn't be calling this directly, use `get_front_photo()` or `get_side_photo()` + * instead. + * + * This is the proc that handles either fetching (if it was already generated before) or + * generating (if it wasn't) the specified photo from the specified record. This is only + * intended to be used by records that used to try to access `fields["photo_front"]` or + * `fields["photo_side"]`, and will return an empty icon if there isn't any of the necessary + * fields. + * + * Arguments: + * * field_name - The name of the key in the `fields` list, of the record itself. + * * orientation - The direction in which you want the character appearance to be rotated + * in the outputed photo. + * + * Returns an empty `/icon` if there was no `character_appearance` entry in the `fields` list, + * returns the generated/cached photo otherwise. + */ +/datum/data/record/proc/get_photo(field_name, orientation) + if(fields[field_name]) + return fields[field_name] + + if(!fields["character_appearance"]) + return new /icon() + + var/mutable_appearance/character_appearance = fields["character_appearance"] + character_appearance.setDir(orientation) + + var/icon/picture_image = getFlatIcon(character_appearance) + + var/datum/picture/picture = new + picture.picture_name = "[fields["name"]]" + picture.picture_desc = "This is [fields["name"]]." + picture.picture_image = picture_image + + var/obj/item/photo/photo = new(null, picture) + fields[field_name] = photo + return photo + /datum/data/crime name = "crime" var/crimeName = "" @@ -223,17 +268,9 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) var/static/record_id_num = 1001 var/id = num2hex(record_id_num++,6) - var/image = get_id_photo(H, show_directions) - var/datum/picture/pf = new - var/datum/picture/ps = new - pf.picture_name = "[H]" - ps.picture_name = "[H]" - pf.picture_desc = "This is [H]." - ps.picture_desc = "This is [H]." - pf.picture_image = icon(image, dir = SOUTH) - ps.picture_image = icon(image, dir = WEST) - var/obj/item/photo/photo_front = new(null, pf) - var/obj/item/photo/photo_side = new(null, ps) + // We need to compile the overlays now, otherwise we're basically copying an empty icon. + COMPILE_OVERLAYS(H) + var/mutable_appearance/character_appearance = new(H.appearance) //These records should ~really~ be merged or something //General Record @@ -255,8 +292,7 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) G.fields["gender"] = "Female" else G.fields["gender"] = "Other" - G.fields["photo_front"] = photo_front - G.fields["photo_side"] = photo_side + G.fields["character_appearance"] = character_appearance general += G //Medical Record @@ -305,14 +341,11 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) L.fields["identity"] = H.dna.unique_identity L.fields["species"] = H.dna.species.type L.fields["features"] = H.dna.features - L.fields["image"] = image + L.fields["character_appearance"] = character_appearance L.fields["mindref"] = H.mind locked += L return -/datum/datacore/proc/get_id_photo(mob/living/carbon/human/human, show_directions = list(SOUTH)) - return get_flat_existing_human_icon(human, show_directions) - //Todo: Add citations to the prinout - you get them from sec record's "citation" field, same as "crim" (which is frankly a terrible fucking field name) ///Standardized printed records. SPRs. Like SATs but for bad guys who probably didn't actually finish school. Input the records and out comes a paper. /proc/print_security_record(datum/data/record/general_data, datum/data/record/security, atom/location) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 2776ecf6eff..51fbfd512f3 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -96,15 +96,17 @@ dat += "" if(active1 in GLOB.data_core.general) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") + var/front_photo = active1.get_front_photo() + if(istype(front_photo, /obj/item/photo)) + var/obj/item/photo/photo_front = front_photo + user << browse_rsc(photo_front.picture.picture_image, "photo_front") + var/side_photo = active1.get_side_photo() + if(istype(side_photo, /obj/item/photo)) + var/obj/item/photo/photo_side = side_photo + user << browse_rsc(photo_side.picture.picture_image, "photo_side") dat += "" - dat += "" - dat += "" + dat += "" + dat += "" dat += "" dat += "" dat += "" @@ -370,16 +372,16 @@ active2.fields["b_dna"] = t1 if("show_photo_front") if(active1) - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) + var/front_photo = active1.get_front_photo() + if(istype(front_photo, /obj/item/photo)) + var/obj/item/photo/photo = front_photo + photo.show(usr) if("show_photo_side") if(active1) - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) + var/side_photo = active1.get_side_photo() + if(istype(side_photo, /obj/item/photo)) + var/obj/item/photo/photo = side_photo + photo.show(usr) else else if(href_list["p_stat"]) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 14bc3569161..aa9bf03d9c7 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -336,12 +336,14 @@ if(3) dat += "Security Record
" if(istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") + var/front_photo = active1.get_front_photo() + if(istype(front_photo, /obj/item/photo)) + var/obj/item/photo/photo_front = front_photo + user << browse_rsc(photo_front.picture.picture_image, "photo_front") + var/side_photo = active1.get_side_photo() + if(istype(side_photo, /obj/item/photo)) + var/obj/item/photo/photo_side = side_photo + user << browse_rsc(photo_side.picture.picture_image, "photo_side") dat += {"
Medical Record
Name:[active1.fields["name"]]
ID:[active1.fields["id"]]
Gender: [active1.fields["gender"]] 
Age: [active1.fields["age"]] 
-
@@ -354,10 +356,10 @@
Name: [active1.fields["name"]] 
ID: [active1.fields["id"]] 
Physical Status: [active1.fields["p_stat"]] 
Mental Status: [active1.fields["m_stat"]] 

+
-

Print photo
Update front photo

+

Print photo
Update side photo
"} @@ -574,7 +576,7 @@ What a mess.*/ printing = 1 sleep(30) if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. - var/obj/item/photo/photo = active1.fields["photo_front"] + var/obj/item/photo/photo = active1.get_front_photo() new /obj/item/poster/wanted(loc, photo.picture.picture_image, wanted_name, info, headerText) printing = 0 if("Print Missing") @@ -591,7 +593,7 @@ What a mess.*/ printing = 1 sleep(30) if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. - var/obj/item/photo/photo = active1.fields["photo_front"] + var/obj/item/photo/photo = active1.get_front_photo() new /obj/item/poster/wanted/missing(loc, photo.picture.picture_image, missing_name, info, headerText) printing = 0 @@ -754,10 +756,11 @@ What a mess.*/ return active1.fields["species"] = t1 if("show_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) + if(active1) + var/front_photo = active1.get_front_photo() + if(istype(front_photo, /obj/item/photo)) + var/obj/item/photo/photo = front_photo + photo.show(usr) if("upd_photo_front") var/obj/item/photo/photo = get_photo(usr) if(photo) @@ -771,15 +774,17 @@ What a mess.*/ I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) active1.fields["photo_front"] = photo if("print_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - print_photo(P.picture.picture_image, active1.fields["name"]) + if(active1) + var/front_photo = active1.get_front_photo() + if(istype(front_photo, /obj/item/photo)) + var/obj/item/photo/photo_front = front_photo + print_photo(photo_front.picture.picture_image, active1.fields["name"]) if("show_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) + if(active1) + var/side_photo = active1.get_side_photo() + if(istype(side_photo, /obj/item/photo)) + var/obj/item/photo/photo = side_photo + photo.show(usr) if("upd_photo_side") var/obj/item/photo/photo = get_photo(usr) if(photo) @@ -793,10 +798,11 @@ What a mess.*/ I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) active1.fields["photo_side"] = photo if("print_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - print_photo(P.picture.picture_image, active1.fields["name"]) + if(active1) + var/side_photo = active1.get_side_photo() + if(istype(side_photo, /obj/item/photo)) + var/obj/item/photo/photo_side = side_photo + print_photo(photo_side.picture.picture_image, active1.fields["name"]) if("crim_add") if(istype(active1, /datum/data/record)) var/t1 = tgui_input_text(usr, "Input crime names", "Security Records") diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 16b9d2eff50..214320d2c09 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -136,9 +136,9 @@ return var/obj/item/photo/photo_from_record = null if(href_list["photo_front"]) - photo_from_record = target_record.fields["photo_front"] + photo_from_record = target_record.get_front_photo() else if(href_list["photo_side"]) - photo_from_record = target_record.fields["photo_side"] + photo_from_record = target_record.get_side_photo() if(photo_from_record) photo_from_record.show(human_user) return diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b3cfe93d9a1..2c3a74c49d7 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -660,7 +660,7 @@ var/list/personnel_list = list() for(var/datum/data/record/record_datum in GLOB.data_core.locked)//Look in data core locked. - personnel_list["[record_datum.fields["name"]]: [record_datum.fields["rank"]]"] = record_datum.fields["image"]//Pull names, rank, and image. + personnel_list["[record_datum.fields["name"]]: [record_datum.fields["rank"]]"] = record_datum.fields["character_appearance"]//Pull names, rank, and image. if(!length(personnel_list)) tgui_alert(usr,"No suitable records found. Aborting.") @@ -670,10 +670,13 @@ return if(isnull(personnel_list[input])) return - var/icon/character_icon = personnel_list[input] + var/mutable_appearance/character_icon = personnel_list[input] if(character_icon) qdel(holo_icon)//Clear old icon so we're not storing it in memory. - holo_icon = getHologramIcon(icon(character_icon)) + character_icon.setDir(SOUTH) + + var/icon/icon_for_holo = getFlatIcon(character_icon) + holo_icon = getHologramIcon(icon(icon_for_holo)) if("My Character") switch(tgui_alert(usr,"WARNING: Your AI hologram will take the appearance of your currently selected character ([usr.client.prefs?.read_preference(/datum/preference/name/real_name)]). Are you sure you want to proceed?", "Customize", list("Yes","No")))