diff --git a/code/controllers/subsystems/initialization/misc_early.dm b/code/controllers/subsystems/initialization/misc_early.dm index 22886a48f16..1785f3e33b4 100644 --- a/code/controllers/subsystems/initialization/misc_early.dm +++ b/code/controllers/subsystems/initialization/misc_early.dm @@ -1,4 +1,4 @@ -// This is the first subsystem initialized by the MC. +// This is one of the first subsystems initialized by the MC. // Stuff that should be loaded before everything else that isn't significant enough to get its own SS goes here. /datum/controller/subsystem/misc_early diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 421da3b6b60..506426c76a1 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -156,8 +156,8 @@ var/global/list/datum/dna/gene/dna_genes[0] body_markings.Cut() for(var/obj/item/organ/external/E in character.organs) - if(E.markings.len) - body_markings[E.limb_name] = E.markings.Copy() + if(LAZYLEN(E.genetic_markings)) + body_markings[E.limb_name] = E.genetic_markings.Copy() UpdateUI() diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index cee13661d66..2c89dc11d42 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -168,7 +168,8 @@ var/obj/item/organ/external/E = H.organs_by_name[tag] if(E) var/list/marklist = dna.body_markings[tag] - E.markings = marklist.Copy() + E.genetic_markings = marklist.Copy() + E.invalidate_marking_cache() //Hair var/hair = dna.GetUIValueRange(DNA_UI_HAIR_STYLE,hair_styles_list.len) diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 4f664ebd288..ebc9a3302ae 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -475,11 +475,13 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O else if(href_list["marking_style"]) var/list/usable_markings = pref.body_markings ^ body_marking_styles_list + var/datum/species/species = global.all_species[pref.species] + var/btype = species.get_bodytype() for(var/M in usable_markings) var/datum/sprite_accessory/S = usable_markings[M] if(!S.species_allowed.len) continue - else if(!(pref.species in S.species_allowed)) + else if(!(btype in S.species_allowed)) usable_markings -= M if (!usable_markings.len) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 017d8a91593..d2926789dec 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -115,7 +115,9 @@ for(var/N in organs_by_name) var/obj/item/organ/external/O = organs_by_name[N] if (O) - O.markings.Cut() + O.genetic_markings = null + O.temporary_markings = null + O.invalidate_marking_cache() var/list/body_markings = prefs.body_markings for(var/M in body_markings) @@ -125,7 +127,13 @@ 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) + var/list/attr = list("color" = mark_color, "datum" = mark_datum) + if (mark_datum.is_genetic) + LAZYINITLIST(O.genetic_markings) + O.genetic_markings[M] = attr + else + LAZYINITLIST(O.temporary_markings) + O.temporary_markings[M] = attr // Helper proc that grabs whatever organ this humantype uses to see. // Usually eyes, but can be something else. diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm index 0b26dff8803..d25959e0d1f 100644 --- a/code/modules/mob/new_player/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories.dm @@ -1146,6 +1146,7 @@ species_allowed = list() var/body_parts = list() //A list of bodyparts this covers, TODO: port defines for organs someday + var/is_genetic = TRUE // If TRUE, the marking is considered genetic and is embedded into DNA. tiger_stripes name = "Tiger Stripes (Tajara)" diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 1bedd501f7a..50636099049 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -60,7 +60,12 @@ var/can_stand var/body_hair var/painted = 0 - var/list/markings = list() // Markings (body_markings) to apply to the icon + var/list/genetic_markings // Markings (body_markings) to apply to the icon + var/list/temporary_markings // Same as above, but not preserved when cloning + var/list/cached_markings // The two above lists cached for perf. reasons. + +/obj/item/organ/external/proc/invalidate_marking_cache() + cached_markings = null /obj/item/organ/external/Destroy() if(parent && parent.children) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index ad22de28a23..1aeba77c5c0 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -2,14 +2,14 @@ return /obj/item/organ/external/proc/compile_icon() - overlays.Cut() + cut_overlays() // This is a kludge, only one icon has more than one generation of children though. for(var/obj/item/organ/external/organ in contents) if(organ.children && organ.children.len) for(var/obj/item/organ/external/child in organ.children) add_overlay(child.mob_icon) - overlays |= organ.mob_icon + add_overlay(organ.mob_icon) /obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human) s_tone = null @@ -83,9 +83,12 @@ add_overlay(lip_icon) mob_icon.Blend(lip_icon, ICON_OVERLAY) - for(var/M in markings) - var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/m_color = markings[M]["color"] + if (!cached_markings) + update_marking_cache() + + for(var/M in cached_markings) + var/datum/sprite_accessory/marking/mark_style = cached_markings[M]["datum"] + var/m_color = cached_markings[M]["color"] var/cache_key = "[mark_style.icon]-[mark_style.icon_state]-[limb_name]-[m_color]" var/icon/finished_icon = SSicon_cache.markings_cache[cache_key] @@ -148,9 +151,12 @@ mob_icon.Blend(skin_color, ICON_ADD) //Body markings, does not include head, duplicated (sadly) above. - for(var/M in markings) - var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/m_color = markings[M]["color"] + if (!cached_markings) + update_marking_cache() + + for(var/M in cached_markings) + var/datum/sprite_accessory/marking/mark_style = cached_markings[M]["datum"] + var/m_color = cached_markings[M]["color"] var/cache_key = "[mark_style.icon]-[mark_style.icon_state]-[limb_name]-[m_color]" var/icon/finished_icon = SSicon_cache.markings_cache[cache_key] @@ -205,7 +211,16 @@ if (body_hair && hair_color) keyparts += "[hair_color]" - for (var/marking in markings) - keyparts += "[marking][markings[marking]["color"]]" + if (!cached_markings) + update_marking_cache() + + for (var/marking in cached_markings) + keyparts += "[marking][cached_markings[marking]["color"]]" . = keyparts.Join("_") + +/obj/item/organ/external/proc/update_marking_cache() + if (LAZYLEN(genetic_markings)) + LAZYADD(cached_markings, genetic_markings) + if (LAZYLEN(temporary_markings)) + LAZYADD(cached_markings, temporary_markings)