diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index dc9956e7338..ce178b8b25b 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -50,9 +50,6 @@ // haironly: nobeard_[hair_style][r_hair][g_hair][b_hair] // beardonly: [beard_style][r_facial][g_facial][b_facial]_nohair var/list/human_hair_cache = list() - 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. @@ -73,6 +70,8 @@ var/list/space_cache = list() var/list/crayon_cache = list() + var/list/istate_cache = list() + /datum/controller/subsystem/icon_cache/New() NEW_SS_GLOBAL(SSicon_cache) @@ -95,7 +94,7 @@ var/key = organ.get_mob_cache_key(FALSE) . = organ_keymap[key] if (!.) - organ_keymap[key] = "organ[current_organ_keymap_idex++]" + organ_keymap[key] = "o[current_organ_keymap_idex++]" . = organ_keymap[key] /datum/controller/subsystem/icon_cache/proc/setup_uniform_mappings() @@ -124,3 +123,35 @@ I.icon_state = istr I.overlays += space_dust_cache[istr] space_cache[istr] = I + +/datum/controller/subsystem/icon_cache/proc/get_state(icon/I, state) // returns an APPEARANCE, not an image! + if (!isicon(I)) + CRASH("Expected icon.") + + if (!istext(state)) + // non-fatal, so just print a message then carry on. + crash_with("Received non-text icon_state '[state || "(NULL)"]'; normalizing, but this shouldn't happen.") + state = "[state]" + + var/list/cache = istate_cache[I] + if (cache) + if (cache[state]) + return cache[state] + else + cache = preload_icon(I) + + var/image/im = image(icon = I, icon_state = state) + return cache[state] = im.appearance + +// Loads all icon states in an icon into the istate cache. +/datum/controller/subsystem/icon_cache/proc/preload_icon(icon/I) + log_debug("SSicon_cache: preloading '[I]'...") + var/list/cache = list() + var/image/im = new(icon = I) + for (var/state in icon_states(I)) + im.icon_state = state + cache[state] = im.appearance + + log_debug("SSicon_cache: preloaded [cache.len] states.") + istate_cache[I] = cache + return cache diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 713ce496dbf..5e20a6b052b 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -448,7 +448,7 @@ var/list/sacrificed = list() chose_name = 1 break D.universal_speak = 1 - D.underwear = 0 + D.underwear = null D.key = ghost.key cult.add_antagonist(D.mind) playsound(loc, 'sound/magic/exit_blood.ogg', 100, 1) diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm index 639887a6030..0e4b1ca6520 100644 --- a/code/game/objects/structures/under_wardrobe.dm +++ b/code/game/objects/structures/under_wardrobe.dm @@ -54,7 +54,7 @@ if(F_UNDER) H.underwear = selection[pick] - H.update_body(1) + H.update_underwear(TRUE) return 1 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 8ea21884ad9..ffbdbba0e2d 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -176,20 +176,16 @@ return 1 //Nothing found to block so return success! var/const/enterloopsanity = 100 -/turf/Entered(atom/atom as mob|obj) +/turf/Entered(atom/movable/AM) if(movement_disabled) usr << "Movement is admin-disabled." //This is to identify lag problems return - ..() - if(!istype(atom, /atom/movable)) - return + ASSERT(istype(AM)) - var/atom/movable/A = atom - - if(ismob(A)) - var/mob/M = A + if(ismob(AM)) + var/mob/M = AM if(!M.lastarea) M.lastarea = get_area(M.loc) if(M.lastarea.has_gravity() == 0) @@ -197,21 +193,26 @@ var/const/enterloopsanity = 100 // Footstep SFX logic moved to human_movement.dm - Move(). - else if(!istype(src, /turf/space)) + else if (type != /turf/space) M.inertia_dir = 0 M.make_floating(0) + ..() + var/objects = 0 - if(A && (A.flags & PROXMOVE) && A.simulated) - for(var/atom/movable/thing in range(1)) - if(objects > enterloopsanity) break + if(AM && (AM.flags & PROXMOVE) && AM.simulated) + for(var/atom/movable/oAM in range(1)) + if(objects > enterloopsanity) + break objects++ - spawn(0) - if(A) - A.HasProximity(thing, 1) - if ((thing && A) && (thing.flags & PROXMOVE)) - thing.HasProximity(A, 1) - return + + if (oAM.simulated) + addtimer(CALLBACK(AM, /atom/movable/.proc/proximity_callback, oAM), 0) + +/atom/movable/proc/proximity_callback(atom/movable/AM) + HasProximity(AM, TRUE) + if (!QDELETED(AM) && !QDELETED(src) && (AM.flags & PROXMOVE)) + AM.HasProximity(src, TRUE) /turf/proc/adjacent_fire_act(turf/simulated/floor/source, temperature, volume) return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index aa9b19c2fd7..282bc34eb0c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -387,6 +387,7 @@ datum/preferences character.update_mutations(0) character.update_body(0) character.update_hair(0) + character.update_underwear(0) character.update_icons() /datum/preferences/proc/open_load_dialog_sql(mob/user) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index f64a75582bc..02f6c5f243e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -87,28 +87,29 @@ There are several things that need to be remembered: #define MUTATIONS_LAYER 1 #define DAMAGE_LAYER 2 #define SURGERY_LAYER 3 -#define UNIFORM_LAYER 4 -#define ID_LAYER 5 -#define SHOES_LAYER 6 -#define GLOVES_LAYER 7 -#define BELT_LAYER 8 -#define SUIT_LAYER 9 -#define TAIL_LAYER 10 -#define GLASSES_LAYER 11 -#define BELT_LAYER_ALT 12 -#define SUIT_STORE_LAYER 13 -#define BACK_LAYER 14 -#define HAIR_LAYER 15 -#define EARS_LAYER 16 -#define FACEMASK_LAYER 17 -#define HEAD_LAYER 18 -#define COLLAR_LAYER 19 -#define HANDCUFF_LAYER 20 -#define LEGCUFF_LAYER 21 -#define L_HAND_LAYER 22 -#define R_HAND_LAYER 23 -#define FIRE_LAYER 24 //If you're on fire -#define TOTAL_LAYERS 24 +#define UNDERWEAR_LAYER 4 +#define UNIFORM_LAYER 5 +#define ID_LAYER 6 +#define SHOES_LAYER 7 +#define GLOVES_LAYER 8 +#define BELT_LAYER 9 +#define SUIT_LAYER 10 +#define TAIL_LAYER 11 +#define GLASSES_LAYER 12 +#define BELT_LAYER_ALT 13 +#define SUIT_STORE_LAYER 14 +#define BACK_LAYER 15 +#define HAIR_LAYER 16 +#define EARS_LAYER 17 +#define FACEMASK_LAYER 18 +#define HEAD_LAYER 19 +#define COLLAR_LAYER 20 +#define HANDCUFF_LAYER 21 +#define LEGCUFF_LAYER 22 +#define L_HAND_LAYER 23 +#define R_HAND_LAYER 24 +#define FIRE_LAYER 25 //If you're on fire +#define TOTAL_LAYERS 25 ////////////////////////////////// #define UNDERSCORE_OR_NULL(target) "[target ? "[target]_" : ""]" @@ -261,17 +262,17 @@ There are several things that need to be remembered: //And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part) if(part.icon_position&(LEFT|RIGHT)) var/icon/temp2 = new('icons/mob/human.dmi',"blank") - temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH) - temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH) + temp2.Insert(new /icon(temp ,dir = NORTH), dir = NORTH) + temp2.Insert(new /icon(temp, dir = SOUTH), dir = SOUTH) if(!(part.icon_position & LEFT)) - temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) + temp2.Insert(new /icon(temp, dir = EAST), dir = EAST) if(!(part.icon_position & RIGHT)) - temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) + temp2.Insert(new /icon(temp, dir = WEST), dir = WEST) base_icon.Blend(temp2, ICON_OVERLAY) if(part.icon_position & LEFT) - temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) + temp2.Insert(new /icon(temp, dir = EAST), dir = EAST) if(part.icon_position & RIGHT) - temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) + temp2.Insert(new /icon(temp, dir = WEST), dir = WEST) base_icon.Blend(temp2, ICON_UNDERLAY) else base_icon.Blend(temp, ICON_OVERLAY) @@ -296,37 +297,29 @@ There are several things that need to be remembered: //END CACHED ICON GENERATION. stand_icon.Blend(base_icon,ICON_OVERLAY) - //Underwear - if(underwear && species.appearance_flags & HAS_UNDERWEAR) - var/uwear = "[underwear]" - var/icon/undies = SSicon_cache.human_underwear_cache[uwear] - if (!undies) - undies = new('icons/mob/human.dmi', underwear) - SSicon_cache.human_underwear_cache[uwear] = undies - stand_icon.Blend(undies, ICON_OVERLAY) - - if(undershirt && species.appearance_flags & HAS_UNDERWEAR) - var/ushirt = "[undershirt]" - var/icon/shirt = SSicon_cache.human_undershirt_cache[ushirt] - if (!shirt) - shirt = new('icons/mob/human.dmi', undershirt) - SSicon_cache.human_undershirt_cache[ushirt] = shirt - stand_icon.Blend(shirt, ICON_OVERLAY) - - if(socks && species.appearance_flags & HAS_SOCKS) - var/sockskey = "[socks]" - var/icon/socksicon = SSicon_cache.human_socks_cache[sockskey] - if (!socksicon) - socksicon = new('icons/mob/human.dmi', socks) - SSicon_cache.human_socks_cache[sockskey] = socksicon - stand_icon.Blend(socksicon, ICON_OVERLAY) - if(update_icons) update_icons() //tail update_tail_showing(0) +/mob/living/carbon/human/proc/update_underwear(update_icons = TRUE) + var/list/ovr + + if(underwear && (species.appearance_flags & HAS_UNDERWEAR)) + LAZYADD(ovr, SSicon_cache.get_state('icons/mob/human.dmi', "[underwear]")) + + if(undershirt && (species.appearance_flags & HAS_UNDERWEAR)) + LAZYADD(ovr, SSicon_cache.get_state('icons/mob/human.dmi', "[undershirt]")) + + if(socks && (species.appearance_flags & HAS_SOCKS)) + LAZYADD(ovr, SSicon_cache.get_state('icons/mob/human.dmi', "[socks]")) + + overlays_raw[UNDERWEAR_LAYER] = ovr + + if (update_icons) + update_icons() + // This proc generates & returns an icon representing a human's hair, using a cached icon from SSicon_cache if possible. // If `hair_is_visible` is FALSE, only facial hair will be drawn. /mob/living/carbon/human/proc/generate_hair_icon(hair_is_visible = TRUE) @@ -451,30 +444,33 @@ There are several things that need to be remembered: return ..() - if(transforming) return - update_mutations(0) - update_body(0) - update_hair(0) - update_inv_w_uniform(0) - update_inv_wear_id(0) - update_inv_gloves(0) - update_inv_glasses(0) - update_inv_ears(0) - update_inv_shoes(0) - update_inv_s_store(0) - update_inv_wear_mask(0) - update_inv_head(0) - update_inv_belt(0) - update_inv_back(0) - update_inv_wear_suit(0) - update_inv_r_hand(0) - update_inv_l_hand(0) - update_inv_handcuffed(0) - update_inv_legcuffed(0) - update_inv_pockets(0) - update_fire(0) - update_surgery(0) + if(transforming) + return + + update_mutations(FALSE) + update_body(FALSE) + update_hair(FALSE) + update_inv_w_uniform(FALSE) + update_inv_wear_id(FALSE) + update_inv_gloves(FALSE) + update_inv_glasses(FALSE) + update_inv_ears(FALSE) + update_inv_shoes(FALSE) + update_inv_s_store(FALSE) + update_inv_wear_mask(FALSE) + update_inv_head(FALSE) + update_inv_belt(FALSE) + update_inv_back(FALSE) + update_inv_wear_suit(FALSE) + update_inv_r_hand(FALSE) + update_inv_l_hand(FALSE) + update_inv_handcuffed(FALSE) + update_inv_legcuffed(FALSE) + update_inv_pockets(FALSE) + update_fire(FALSE) + update_surgery(FALSE) + update_underwear(FALSE) UpdateDamageIcon() update_icons() //Hud Stuff diff --git a/code/modules/multiz/zmimic/mimic_turf.dm b/code/modules/multiz/zmimic/mimic_turf.dm index d89350e4b3f..ac079a718e6 100644 --- a/code/modules/multiz/zmimic/mimic_turf.dm +++ b/code/modules/multiz/zmimic/mimic_turf.dm @@ -7,7 +7,7 @@ /turf/Entered(atom/movable/thing, turf/oldLoc) . = ..() - if (thing.bound_overlay || !thing.no_z_overlay || !above || !(above.flags & MIMIC_BELOW) || (isturf(oldLoc) && oldLoc.above && (oldLoc.above.flags & MIMIC_BELOW))) + if (thing.bound_overlay || thing.no_z_overlay || !TURF_IS_MIMICING(above)) return above.update_mimic() diff --git a/html/changelogs/lohikar-aaaa.yml b/html/changelogs/lohikar-aaaa.yml new file mode 100644 index 00000000000..a7f0c6ac931 --- /dev/null +++ b/html/changelogs/lohikar-aaaa.yml @@ -0,0 +1,4 @@ +author: Lohikar +delete-after: True +changes: + - bugfix: "Openspaces will now properly show mobs/objects that became visible after roundstart."