From eace452b300cea24281d41406e9b8085651b8eef Mon Sep 17 00:00:00 2001 From: Lohikar Date: Sun, 13 Aug 2017 17:01:40 -0500 Subject: [PATCH] Human icon key & preferences tweaks (#3274) changes: Reworked how human body icon keys are generated; resulting keys should be much shorter now and involve less duplication of the same string. Players are now shown a message when they try to add markings to a species that has none available. Admin revive for human-types will now also re-apply their organ and marking prefs. Admin revive now also resets shock_stage (fixes rejuv'd mobs being slow for a while) --- code/controllers/subsystems/icon_cache.dm | 12 +++++ .../gamemodes/changeling/changeling_powers.dm | 2 +- .../preference_setup/general/03_body.dm | 4 ++ code/modules/client/preferences.dm | 44 +---------------- code/modules/mob/living/carbon/human/human.dm | 14 +++++- .../mob/living/carbon/human/human_helpers.dm | 48 +++++++++++++++++++ .../mob/living/carbon/human/update_icons.dm | 26 ++-------- code/modules/mob/living/living.dm | 2 +- code/modules/organs/organ_icon.dm | 25 ++++++++++ html/changelogs/lohikar-prefs.yml | 5 ++ 10 files changed, 114 insertions(+), 68 deletions(-) create mode 100644 html/changelogs/lohikar-prefs.yml diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index 958219a2d17..bf3dfbec7c3 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -52,6 +52,8 @@ var/list/human_underwear_cache = list() var/list/human_undershirt_cache = list() var/list/human_socks_cache = list() + var/list/organ_keymap = list() + var/current_organ_keymap_idex = 1 // This is an assoc list of all icon states in `icons/mob/collar.dmi`, used by human update-icons. var/list/collar_states var/list/uniform_states @@ -64,6 +66,16 @@ for (var/i in icon_states('icons/mob/collar.dmi')) collar_states[i] = TRUE +/datum/controller/subsystem/icon_cache/proc/get_organ_shortcode(obj/item/organ/external/organ) + if (QDELETED(organ)) + return null + + var/key = organ.get_mob_cache_key(FALSE) + . = organ_keymap[key] + if (!.) + organ_keymap[key] = "organ[current_organ_keymap_idex++]" + . = organ_keymap[key] + /datum/controller/subsystem/icon_cache/proc/setup_uniform_mappings() uniform_states = list() for (var/i in icon_states('icons/mob/uniform.dmi')) diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 93b355de1e5..057fb5e2202 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -443,7 +443,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E var/mob/living/carbon/C = src // restore us to health - C.revive() + C.revive(FALSE) // remove our fake death flag C.status_flags &= ~(FAKEDEATH) // let us move again diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 4eedd68509c..911819b3c46 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -462,6 +462,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else if(!(pref.species in S.species_allowed)) usable_markings -= M + if (!usable_markings.len) + alert(user, "This species does not have any body markings available.") + return TOPIC_NOACTION + var/new_marking = input(user, "Choose a body marking:", "Character Preference") as null|anything in usable_markings if(new_marking && CanUseTopic(user)) pref.body_markings[new_marking] = "#000000" //New markings start black diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 62a12011cba..4081f9f7113 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -363,48 +363,8 @@ datum/preferences character.skills = skills character.used_skillpoints = used_skillpoints - // Destroy/cyborgize organs - - for(var/name in organ_data) - - var/status = organ_data[name] - var/obj/item/organ/external/O = character.organs_by_name[name] - if(O) - O.status = 0 - if(status == "amputated") - character.organs_by_name[O.limb_name] = null - character.organs -= O - if(O.children) // This might need to become recursive. - for(var/obj/item/organ/external/child in O.children) - character.organs_by_name[child.limb_name] = null - character.organs -= child - - else if(status == "cyborg") - if(rlimb_data[name]) - O.robotize(rlimb_data[name]) - else - O.robotize() - else - var/obj/item/organ/I = character.internal_organs_by_name[name] - if(I) - if(status == "assisted") - I.mechassist() - else if(status == "mechanical") - I.robotize() - - for(var/N in character.organs_by_name) - var/obj/item/organ/external/O = character.organs_by_name[N] - if (O) - O.markings.Cut() - - for(var/M in body_markings) - var/datum/sprite_accessory/marking/mark_datum = body_marking_styles_list[M] - var/mark_color = "[body_markings[M]]" - - for(var/BP in mark_datum.body_parts) - var/obj/item/organ/external/O = character.organs_by_name[BP] - if(O) - O.markings[M] = list("color" = mark_color, "datum" = mark_datum) + // Destroy/cyborgize organs & setup body markings + character.sync_organ_prefs_to_mob(src) character.underwear = underwear diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 45c67891fa7..7d6d0826b5b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1009,16 +1009,25 @@ else germ_level += n -/mob/living/carbon/human/revive() +/mob/living/carbon/human/revive(reset_to_roundstart = TRUE) if(species && !(species.flags & NO_BLOOD)) vessel.add_reagent("blood",560-vessel.total_volume) fixblood() // Fix up all organs. - // This will ignore any prosthetics in the prefs currently. species.create_organs(src) + var/datum/preferences/prefs + if (client) + prefs = client.prefs + else if (ckey) // Mob might be logged out. + prefs = preferences_datums[ckey(ckey)] // run the ckey through ckey() here so that aghosted mobs can be rejuv'd too. (Their ckeys are prefixed with @) + + if (prefs && real_name == prefs.real_name) + // Re-apply the mob's markings and prosthetics if their pref is their current char. + sync_organ_prefs_to_mob(prefs, reset_to_roundstart) // Don't apply prosthetics if we're a ling rejuving. + if(!client || !key) //Don't boot out anyone already in the mob. for (var/obj/item/organ/brain/H in world) if(H.brainmob) @@ -1035,6 +1044,7 @@ V.cure(src) losebreath = 0 + shock_stage = 0 ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index d4c0c75330c..03d4e3debf7 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -78,3 +78,51 @@ /mob/living/carbon/human/proc/process_rig(var/obj/item/weapon/rig/O) if(O.visor && O.visor.active && O.visor.vision && O.visor.vision.glasses && (!O.helmet || (head && O.helmet == head))) process_glasses(O.visor.vision.glasses) + +// Applies organ/markings prefs to this mob. +/mob/living/carbon/human/proc/sync_organ_prefs_to_mob(datum/preferences/prefs, apply_prosthetics = TRUE, apply_markings = TRUE) + if (apply_prosthetics) + var/list/rlimb_data = prefs.rlimb_data + var/list/organ_data = prefs.organ_data + for(var/name in organ_data) + var/status = organ_data[name] + var/obj/item/organ/external/O = organs_by_name[name] + if(O) + O.status = 0 + switch(status) + if ("amputated") + organs_by_name[O.limb_name] = null + organs -= O + if(O.children) // This might need to become recursive. + for(var/obj/item/organ/external/child in O.children) + organs_by_name[child.limb_name] = null + organs -= child + if ("cyborg") + if (rlimb_data[name]) + O.robotize(rlimb_data[name]) + else + O.robotize() + else + var/obj/item/organ/I = internal_organs_by_name[name] + if(I) + switch (status) + if ("assisted") + I.mechassist() + if ("mechanical") + I.robotize() + + if (apply_markings) + for(var/N in organs_by_name) + var/obj/item/organ/external/O = organs_by_name[N] + if (O) + O.markings.Cut() + + var/list/body_markings = prefs.body_markings + for(var/M in body_markings) + var/datum/sprite_accessory/marking/mark_datum = body_marking_styles_list[M] + var/mark_color = "[body_markings[M]]" + + for(var/BP in mark_datum.body_parts) + var/obj/item/organ/external/O = organs_by_name[BP] + if(O) + O.markings[M] = list("color" = mark_color, "datum" = mark_datum) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index c086071a555..6829fe78717 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -233,7 +233,7 @@ There are several things that need to be remembered: qdel(stand_icon) stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") - var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin][lip_style || "nolips"]" + var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin][lip_style || "nolips"][!!husk][!!fat][!!hulk][!!skeleton]" var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] if(eyes) icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" @@ -242,29 +242,11 @@ There are several things that need to be remembered: for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] - if(!part || part.is_stump()) - icon_key += "0" - else if(part.status & ORGAN_ROBOT) - icon_key += "2[part.model ? "-[part.model]": ""]" - else if(part.status & ORGAN_DEAD) - icon_key += "3" - else - icon_key += "1" - if(part) - icon_key += "[part.species.race_key]" - icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]" - icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]" - if(part.skin_color) - icon_key += "[part.skin_color]" - if(part.body_hair && part.hair_color) - icon_key += "[part.hair_color]" - else - icon_key += "#000000" + if (!part) + continue - for(var/M in part.markings) - icon_key += "[M][part.markings[M]["color"]]" + icon_key += SSicon_cache.get_organ_shortcode(part) - icon_key = "[icon_key][!!husk][!!fat][!!hulk][!!skeleton]" var/icon/base_icon = SSicon_cache.human_icon_cache[icon_key] if (!base_icon) // Icon ain't in the cache, so generate it. //BEGIN CACHED ICON GENERATION. diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 85b04873ffe..854e48c373d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -412,7 +412,7 @@ default behaviour is: -/mob/living/proc/revive() +/mob/living/proc/revive(reset_to_roundstart = TRUE) // this param is only used in human regen. // Stop killing yourself. Please. // if(suiciding) // suiciding = 0 diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 937115dc453..3f097e74c3e 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -189,3 +189,28 @@ damage_state = n_is return 1 return 0 + +// This is NOT safe for caching the organ's own icon, it's only meant to be used for the mob icon cache. +/obj/item/organ/external/proc/get_mob_cache_key() + var/list/keyparts = list() + if (is_stump()) + keyparts += "stump" + else if (status & ORGAN_ROBOT) + keyparts += "robot:[model || "nomodel"]" + else if (status & ORGAN_DEAD) + keyparts += "dead" + else + keyparts += "norm" + + keyparts += "[species.race_key]" + keyparts += "[dna.GetUIState(DNA_UI_GENDER)]" + keyparts += "[dna.GetUIValue(DNA_UI_SKIN_TONE)]" + if (skin_color) + keyparts += "[skin_color]" + if (body_hair && hair_color) + keyparts += "[hair_color]" + + for (var/marking in markings) + keyparts += "[marking][markings[marking]["color"]]" + + . = keyparts.Join("_") diff --git a/html/changelogs/lohikar-prefs.yml b/html/changelogs/lohikar-prefs.yml new file mode 100644 index 00000000000..30d92f0fd21 --- /dev/null +++ b/html/changelogs/lohikar-prefs.yml @@ -0,0 +1,5 @@ +author: Lohikar +delete-after: True +changes: + - tweak: "Preferences setup will now tell you if you try to add body markings to a species that has none available." + - tweak: "Admin revive will now restore body markings and round-start prosthetics."