diff --git a/code/__DEFINES/stat_tracking.dm b/code/__DEFINES/stat_tracking.dm index d7d207469d8dd..f1492642459af 100644 --- a/code/__DEFINES/stat_tracking.dm +++ b/code/__DEFINES/stat_tracking.dm @@ -8,10 +8,4 @@ #define STAT_LOG_ENTRY(entrylist, entryname) \ var/list/STAT_ENTRY = entrylist[entryname] || (entrylist[entryname] = new /list(STAT_ENTRY_LENGTH));\ STAT_ENTRY[STAT_ENTRY_TIME] += STAT_TIME;\ - var/STAT_INCR_AMOUNT = min(1, 2**round((STAT_ENTRY[STAT_ENTRY_COUNT] || 0)/SHORT_REAL_LIMIT));\ - if (STAT_INCR_AMOUNT == 1 || prob(100/STAT_INCR_AMOUNT)) {\ - STAT_ENTRY[STAT_ENTRY_COUNT] += STAT_INCR_AMOUNT;\ - };\ - - - + STAT_ENTRY[STAT_ENTRY_COUNT] += 1; diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 397cfeddd3148..98237b820f007 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -165,7 +165,6 @@ #define INIT_ORDER_PERSISTENCE -2 //before assets because some assets take data from SSPersistence #define INIT_ORDER_ASSETS -4 #define INIT_ORDER_ICON_SMOOTHING -5 -#define INIT_ORDER_OVERLAY -6 #define INIT_ORDER_STAT -7 #define INIT_ORDER_XKEYSCORE -10 #define INIT_ORDER_STICKY_BAN -10 @@ -219,7 +218,6 @@ #define FIRE_PRIORITY_ATMOS_ADJACENCY 300 #define FIRE_PRIORITY_CHAT 400 #define FIRE_PRIORITY_RUNECHAT 410 -#define FIRE_PRIORITY_OVERLAYS 500 #define FIRE_PRIORITY_CALLBACKS 600 #define FIRE_PRIORITY_EXPLOSIONS 666 #define FIRE_PRIORITY_PREFERENCES 690 @@ -289,27 +287,21 @@ #define GAME_STATE_FINISHED 4 //! ## Overlays subsystem - -/// Compile all the overlays for an atom from the cache lists -#define COMPILE_OVERLAYS(A)\ - if (A) {\ - var/list/ad = A.add_overlays;\ - var/list/rm = A.remove_overlays;\ - if(LAZYLEN(rm)){\ - A.overlays -= rm;\ - rm.Cut();\ - }\ - if(LAZYLEN(ad)){\ - A.overlays |= ad;\ - ad.Cut();\ - }\ - for(var/I in A.alternate_appearances){\ - var/datum/atom_hud/alternate_appearance/AA = A.alternate_appearances[I];\ +#define POST_OVERLAY_CHANGE(changed_on) \ + if(length(changed_on.overlays) >= MAX_ATOM_OVERLAYS) { \ + var/text_lays = overlays2text(changed_on.overlays); \ + stack_trace("Too many overlays on [changed_on.type] - [length(changed_on.overlays)], refusing to update and cutting.\ + \n What follows is a printout of all existing overlays at the time of the overflow \n[text_lays]"); \ + changed_on.overlays.Cut(); \ + changed_on.add_overlay(mutable_appearance('icons/testing/greyscale_error.dmi')); \ + } \ + if(alternate_appearances) { \ + for(var/I in changed_on.alternate_appearances){\ + var/datum/atom_hud/alternate_appearance/AA = changed_on.alternate_appearances[I];\ if(AA.transfer_overlays){\ - AA.copy_overlays(A, TRUE);\ + AA.copy_overlays(changed_on, TRUE);\ }\ - }\ - A.flags_1 &= ~OVERLAY_QUEUED_1;\ + } \ } /** diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 4918460a0949b..3419c2cb1c2c2 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1156,7 +1156,6 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) body.equipOutfit(outfit_override,visualsOnly = TRUE) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") - COMPILE_OVERLAYS(body) for(var/D in showDirs) var/icon/partial = getFlatIcon(body, defdir=D) out_icon.Insert(partial,dir=D) @@ -1185,7 +1184,6 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) var/initial_human_dir = existing_human.dir existing_human.dir = SOUTH var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") - COMPILE_OVERLAYS(existing_human) for(var/direction in directions_to_output) var/icon/partial = getFlatIcon(existing_human, defdir = direction) out_icon.Insert(partial, dir = direction) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 43a1497a6ec07..f99915531aa7f 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -188,13 +188,13 @@ DEFINE_BITFIELD(flags_1, list( "NOJAUNT_1" = NOJAUNT_1, "NO_RUINS_1" = NO_RUINS_1, "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, - "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, "ON_BORDER_1" = ON_BORDER_1, "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1, "TESLA_IGNORE_1" = TESLA_IGNORE_1, "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, "UNPAINTABLE_1" = UNPAINTABLE_1, + "HTML_USE_INITAL_ICON_1" = HTML_USE_INITAL_ICON_1, )) DEFINE_BITFIELD(flags_ricochet, list( diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm index 957e5806f02a7..163259083637b 100644 --- a/code/controllers/subsystem/overlays.dm +++ b/code/controllers/subsystem/overlays.dm @@ -1,74 +1,16 @@ SUBSYSTEM_DEF(overlays) name = "Overlay" - flags = SS_TICKER - wait = 1 - priority = FIRE_PRIORITY_OVERLAYS - init_order = INIT_ORDER_OVERLAY - - var/list/queue + flags = SS_NO_FIRE|SS_NO_INIT var/list/stats - // If the overlay set currently being considered contains a manglable overlay. - // This is only safe because SSoverlays can only ever consider one overlay list at a time with no interior sleeps. Professional on closed course, do not attempt. - var/context_needs_automangle - /datum/controller/subsystem/overlays/PreInit() - queue = list() stats = list() -/datum/controller/subsystem/overlays/Initialize() - initialized = TRUE - fire(mc_check = FALSE) - return SS_INIT_SUCCESS - - -/datum/controller/subsystem/overlays/stat_entry() - . = ..("Ov:[length(queue)]") - - /datum/controller/subsystem/overlays/Shutdown() rustg_file_append(render_stats(stats), "[GLOB.log_directory]/overlay.log") - /datum/controller/subsystem/overlays/Recover() - queue = SSoverlays.queue - - -/datum/controller/subsystem/overlays/fire(resumed = FALSE, mc_check = TRUE) - var/list/queue = src.queue - var/static/count = 0 - if (count) - var/c = count - count = 0 //so if we runtime on the Cut, we don't try again. - queue.Cut(1,c+1) - - for (var/atom/atom_to_compile as anything in queue) - count++ - if(!atom_to_compile) - continue - STAT_START_STOPWATCH - COMPILE_OVERLAYS(atom_to_compile) - UNSETEMPTY(atom_to_compile.add_overlays) - UNSETEMPTY(atom_to_compile.remove_overlays) - STAT_STOP_STOPWATCH - STAT_LOG_ENTRY(stats, atom_to_compile.type) - if(length(atom_to_compile.overlays) >= MAX_ATOM_OVERLAYS) - //Break it real GOOD - var/text_lays = overlays2text(atom_to_compile.overlays) - stack_trace("Too many overlays on [atom_to_compile.type] - [length(atom_to_compile.overlays)], refusing to update and cutting.\ - \n What follows is a printout of all existing overlays at the time of the overflow \n[text_lays]") - atom_to_compile.overlays.Cut() - //Let them know they fucked up - atom_to_compile.add_overlay(mutable_appearance('icons/testing/greyscale_error.dmi')) - continue - if(mc_check) - if(MC_TICK_CHECK) - break - else - CHECK_TICK - if (count) - queue.Cut(1,count+1) - count = 0 + stats = SSoverlays.stats /// Converts an overlay list into text for debug printing /// Of note: overlays aren't actually mutable appearances, they're just appearances @@ -95,167 +37,83 @@ SUBSYSTEM_DEF(overlays) iconbro.icon = icon return iconbro.appearance -// If the overlay has a planeset (e.g., emissive), mark for ZM mangle. This won't catch overlays on overlays, but the flag can just manually be set in that case. -#define ZM_AUTOMANGLE(target) if ((target):plane != FLOAT_PLANE) { SSoverlays.context_needs_automangle = TRUE; } - -/atom/proc/build_appearance_list(old_overlays) - var/static/image/appearance_bro = new() - var/list/new_overlays = list() - - for (var/overlay in (islist(old_overlays) ? old_overlays : list(old_overlays))) +/atom/proc/build_appearance_list(build_overlays) + if (!islist(build_overlays)) + build_overlays = list(build_overlays) + for (var/overlay in build_overlays) if(!overlay) + build_overlays -= overlay continue if (istext(overlay)) - new_overlays += iconstate2appearance(icon, overlay) +#ifdef UNIT_TESTS + // This is too expensive to run normally but running it during CI is a good test + if(!skip_sprite_error) + var/list/icon_states_available = icon_states(icon) + if(!(overlay in icon_states_available)) + var/icon_file = "[icon]" || "Unknown Generated Icon" + stack_trace("Invalid overlay: Icon object '[icon_file]' [REF(icon)] used in '[src]' [type] is missing icon state [overlay].") + continue +#endif + build_overlays -= overlay + build_overlays += iconstate2appearance(icon, overlay) else if(isicon(overlay)) - new_overlays += icon2appearance(overlay) - else - if(isloc(overlay)) - var/atom/A = overlay - if (A.flags_1 & OVERLAY_QUEUED_1) - COMPILE_OVERLAYS(A) - appearance_bro.appearance = overlay //this works for images and atoms too! - if(!ispath(overlay)) - var/image/I = overlay - appearance_bro.dir = I.dir - new_overlays += appearance_bro.appearance - return new_overlays - -// The same as the above, but with ZM_AUTOMANGLE. -/atom/movable/build_appearance_list(old_overlays) - var/static/image/appearance_bro = new() - var/list/new_overlays = list() + build_overlays -= overlay + build_overlays += icon2appearance(overlay) + return build_overlays - for (var/overlay in (islist(old_overlays) ? old_overlays : list(old_overlays))) - if(!overlay) - continue - var/image/new_overlay - if (istext(overlay)) - new_overlay = iconstate2appearance(icon, overlay) - else if(isicon(overlay)) - new_overlay = icon2appearance(overlay) - else - if(isloc(overlay)) - var/atom/A = overlay - if (A.flags_1 & OVERLAY_QUEUED_1) - COMPILE_OVERLAYS(A) - appearance_bro.appearance = overlay //this works for images and atoms too! - if(!ispath(overlay)) - var/image/I = overlay - appearance_bro.dir = I.dir - new_overlay = appearance_bro.appearance - if(new_overlay) - new_overlays += new_overlay - ZM_AUTOMANGLE(new_overlay) - return new_overlays +#ifdef UNIT_TESTS +/atom/var/skip_sprite_error +/obj/item/gun/skip_sprite_error = TRUE +// I hate this but gun sprites are not implemented properly, and unit test blames this +// We'll need to clean up gun sprites someday, but not right now, it's a mess +#endif -#define NOT_QUEUED_ALREADY (!(flags_1 & OVERLAY_QUEUED_1)) -#define QUEUE_FOR_COMPILE flags_1 |= OVERLAY_QUEUED_1; SSoverlays.queue += src; /atom/proc/cut_overlays() - LAZYINITLIST(remove_overlays) - LAZYINITLIST(add_overlays) - remove_overlays = overlays.Copy() - add_overlays.Cut() - - //If not already queued for work and there are overlays to remove - if(NOT_QUEUED_ALREADY && remove_overlays.len) - QUEUE_FOR_COMPILE + STAT_START_STOPWATCH + overlays = null + POST_OVERLAY_CHANGE(src) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(SSoverlays.stats, type) -// This one gets to be done the sane way because it shouldn't be as hot as the others. -/atom/movable/cut_overlays() - ..() - zmm_flags &= ~ZMM_AUTOMANGLE - -/atom/proc/cut_overlay(list/overlays) +/atom/proc/cut_overlay(list/remove_overlays) if(!overlays) return - SSoverlays.context_needs_automangle = FALSE - overlays = build_appearance_list(overlays) - LAZYINITLIST(add_overlays) //always initialized after this point - LAZYINITLIST(remove_overlays) - var/a_len = add_overlays.len - var/r_len = remove_overlays.len - - remove_overlays += overlays - add_overlays -= overlays - - var/fa_len = add_overlays.len - var/fr_len = remove_overlays.len - - - //If not already queued and there is work to be done - if(NOT_QUEUED_ALREADY && (fa_len != a_len || fr_len != r_len)) - QUEUE_FOR_COMPILE - -/atom/movable/cut_overlay(list/overlays) - ..() - // If we removed an automangle-eligible overlay and have automangle enabled, reevaluate automangling. - if (!SSoverlays.context_needs_automangle || !(zmm_flags & ZMM_AUTOMANGLE)) - return - - var/list/cached_overlays = src.overlays.Copy() - - // If we cut some overlays but some are still left, we need to scan for AUTOMANGLE. - if (LAZYLEN(cached_overlays)) - // need to scan overlays - var/found = FALSE - for (var/i in 1 to length(cached_overlays)) - var/image/I = cached_overlays[i] - if (I.plane != FLOAT_PLANE) - found = TRUE - break - if (!found) - zmm_flags &= ~ZMM_AUTOMANGLE - // None left, just unset the bit. - else - zmm_flags &= ~ZMM_AUTOMANGLE + STAT_START_STOPWATCH + overlays -= build_appearance_list(remove_overlays) + POST_OVERLAY_CHANGE(src) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(SSoverlays.stats, type) -/atom/proc/add_overlay(list/overlays) +/atom/proc/add_overlay(list/add_overlays) if(!overlays) return + STAT_START_STOPWATCH + overlays += build_appearance_list(add_overlays) + POST_OVERLAY_CHANGE(src) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(SSoverlays.stats, type) - // the things I do for performance - var/is_movable = istype(src, /atom/movable) - - SSoverlays.context_needs_automangle = FALSE - overlays = build_appearance_list(overlays) - if (SSoverlays.context_needs_automangle && is_movable) - // This is a movable flag. - src:zmm_flags |= ZMM_AUTOMANGLE - - LAZYINITLIST(add_overlays) //always initialized after this point - var/a_len = add_overlays.len - - - add_overlays += overlays - var/fa_len = add_overlays.len - if(NOT_QUEUED_ALREADY && fa_len != a_len) - QUEUE_FOR_COMPILE - -/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom +/atom/proc/copy_overlays(atom/other, cut_old) //copys our_overlays from another atom if(!other) if(cut_old) cut_overlays() return + STAT_START_STOPWATCH var/list/cached_other = other.overlays.Copy() - if(cached_other) - if (istype(src, /atom/movable)) - for (var/i in 1 to length(cached_other)) - var/image/I = cached_other[i] - if (I.plane != FLOAT_PLANE) - src:zmm_flags |= ZMM_AUTOMANGLE - break - if(cut_old || !LAZYLEN(overlays)) - remove_overlays = overlays - add_overlays = cached_other - if(NOT_QUEUED_ALREADY) - QUEUE_FOR_COMPILE - else if(cut_old) - cut_overlays() - -#undef NOT_QUEUED_ALREADY -#undef QUEUE_FOR_COMPILE + if(cut_old) + if(cached_other) + overlays = cached_other + else + overlays = null + POST_OVERLAY_CHANGE(src) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(SSoverlays.stats, type) + else if(cached_other) + overlays += cached_other + POST_OVERLAY_CHANGE(src) + STAT_STOP_STOPWATCH + STAT_LOG_ENTRY(SSoverlays.stats, type) //TODO: Better solution for these? /image/proc/add_overlay(x) @@ -281,5 +139,3 @@ SUBSYSTEM_DEF(overlays) overlays |= cached_other else if(cut_old) cut_overlays() - -#undef ZM_AUTOMANGLE diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 4ebfb454f337e..b478b6831021f 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -300,7 +300,6 @@ if(outfit_type) mannequin.equipOutfit(outfit_type,TRUE) mannequin.setDir(SOUTH) - COMPILE_OVERLAYS(mannequin) . = image(mannequin) unset_busy_human_dummy("HOLODISK_PRESET") diff --git a/code/datums/records/manifest.dm b/code/datums/records/manifest.dm index 2e4757fb7f49d..fbc3cb18e5281 100644 --- a/code/datums/records/manifest.dm +++ b/code/datums/records/manifest.dm @@ -85,8 +85,6 @@ /datum/manifest/proc/inject(mob/living/carbon/human/person, nosignal = FALSE) set waitfor = FALSE - // We need to compile the overlays now, otherwise we're basically copying an empty icon. - COMPILE_OVERLAYS(person) var/mutable_appearance/character_appearance = new(person.appearance) var/datum/dna/stored/record_dna = new() person.dna.copy_dna(record_dna) diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm index e6770fd442c7d..a774f9b15050e 100644 --- a/code/game/machinery/airlock_cycle_control.dm +++ b/code/game/machinery/airlock_cycle_control.dm @@ -161,7 +161,7 @@ //1 is the lowest value found in monitors.dmi pressure_bars = 1 else - pressure_bars = round(pressure / maxpressure * 5 + 0.01) + pressure_bars = min(round(pressure / maxpressure * 5 + 0.01), 5) var/new_overlays_hash = "[pressure_bars]-[cyclestate]-[buildstage]-[panel_open]-[machine_stat]-[shorted]-[locked]-[vis_target]" if(use_hash && new_overlays_hash == overlays_hash) @@ -185,7 +185,8 @@ return var/is_exterior_pressure = (cyclestate == AIRLOCK_CYCLESTATE_OUTCLOSING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPENING || cyclestate == AIRLOCK_CYCLESTATE_OUTOPEN) - add_overlay("aac_[is_exterior_pressure ? "ext" : "int"]p_[pressure_bars]") + if(pressure_bars > 0) // 0 means no overlay. no need this. + add_overlay("aac_[is_exterior_pressure ? "ext" : "int"]p_[pressure_bars]") add_overlay("aac_cyclestate_[cyclestate]") if(obj_flags & EMAGGED) add_overlay("aac_emagged") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index a93f78d53e534..c64274fd186d7 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( name = "random arcade" desc = "random arcade machine" icon_state = "arcade" - icon_keyboard = "no_keyboard" + icon_keyboard = null icon_screen = "invaders" //these muthafuckas arent supposed to smooth diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 98ca8c0d0d025..48cfb4e02e160 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -84,10 +84,12 @@ return /obj/machinery/computer/atmos_alert/update_icon() - ..() if(machine_stat & (NOPOWER|BROKEN)) return if(priority_alarms.len) - add_overlay("alert:2") + icon_screen = "alert:2" else if(minor_alarms.len) - add_overlay("alert:1") + icon_screen = "alert:1" + else + icon_screen = "alert:0" + ..() diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 1e76a77af7df9..608ddc83fe52f 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -208,7 +208,7 @@ name = "security camera monitor" desc = "An old TV hooked into the station's camera network." icon_state = "television" - icon_keyboard = "no_keyboard" + icon_keyboard = null icon_screen = "detective_tv" //these muthafuckas arent supposed to smooth diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index 0394557805990..32313d7256789 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -119,7 +119,7 @@ title = "Door Controls" icon_state = "oldcomp" icon_screen = "library" - icon_keyboard = "no_keyboard" + icon_keyboard = null base_icon_state = null smoothing_flags = NONE diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 44622acbfc1a9..0d59c695f9f77 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -14,6 +14,7 @@ GLOBAL_LIST_EMPTY(cryopod_computers) desc = "An interface between crew and the cryogenic storage oversight systems." icon = 'icons/obj/Cryogenic2.dmi' icon_state = "cellconsole_1" + icon_keyboard = null base_icon_state = null smoothing_flags = NONE diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 20a3df4cec1c2..c2348509cd298 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -72,36 +72,30 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/firealarm) if(machine_stat & NOPOWER) return - . += "fire_overlay" + . += mutable_appearance(icon, "fire_overlay") if(is_station_level(z)) - . += "fire_[SSsecurity_level.get_current_level_as_number()]" . += mutable_appearance(icon, "fire_[SSsecurity_level.get_current_level_as_number()]") . += emissive_appearance(icon, "fire_[SSsecurity_level.get_current_level_as_number()]", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) else - . += "fire_[SEC_LEVEL_GREEN]" . += mutable_appearance(icon, "fire_[SEC_LEVEL_GREEN]") . += emissive_appearance(icon, "fire_[SEC_LEVEL_GREEN]", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) if(obj_flags & EMAGGED) - . += "fire_emagged" . += mutable_appearance(icon, "fire_emagged") . += emissive_appearance(icon, "fire_emagged", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) return //If it's emagged, don't do anything else for overlays. if(locked) - . += "fire_locked" . += mutable_appearance(icon, "fire_locked", layer + 1) //If we are locked, overlay that over the fire_off . += emissive_appearance(icon, "fire_locked", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) if(detecting && A.fire) - . += "fire_on" . += mutable_appearance(icon, "fire_on", layer + 2) //If we are locked and there is a fire, overlay the fire detection overlay ontop of the locked one. . += emissive_appearance(icon, "fire_on", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) else - . += "fire_off" . += mutable_appearance(icon, "fire_off") . += emissive_appearance(icon, "fire_off", layer, alpha = 255) ADD_LUM_SOURCE(src, LUM_SOURCE_MANAGED_OVERLAY) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index a332fb9a6ef93..362d86798c020 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -735,7 +735,8 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) . = ..() if(has_ammobar) var/ratio = CEILING((matter / max_matter) * ammo_sections, 1) - . += "[icon_state]_charge[ratio]" + if(ratio > 0) + . += "[icon_state]_charge[ratio]" /obj/item/construction/rcd/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/implants/implant_stealth.dm b/code/game/objects/items/implants/implant_stealth.dm index b43b08e1dfe01..3b15d2480051b 100644 --- a/code/game/objects/items/implants/implant_stealth.dm +++ b/code/game/objects/items/implants/implant_stealth.dm @@ -16,6 +16,8 @@ max_integrity = 1 // "This dumb box shouldn't take more than one hit to make it vanish." move_speed_multiplier = 0.5 + has_opened_overlay = FALSE + /obj/structure/closet/cardboard/agent/proc/go_invisible() animate(src, , alpha = 0, time = 20) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index d1090f957b4a2..16cafd6482e34 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -959,7 +959,6 @@ . = ..() var/mutable_appearance/arm = mutable_appearance(icon = icon, icon_state = "borg_beaker_apparatus_arm") if(stored) - COMPILE_OVERLAYS(stored) stored.pixel_x = 0 stored.pixel_y = 0 var/mutable_appearance/stored_copy = new /mutable_appearance(stored) @@ -1010,7 +1009,6 @@ . = ..() var/mutable_appearance/arm = mutable_appearance(icon, "borg_hardware_apparatus_arm1") if(stored) - COMPILE_OVERLAYS(stored) stored.pixel_x = -3 stored.pixel_y = 0 if(!istype(stored, /obj/item/circuitboard)) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index d593e23866fdd..8088cbe5a1dba 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -42,18 +42,23 @@ /obj/item/robot_suit/update_overlays() . = ..() - if(l_arm) - . += "[l_arm.icon_state]+o" - if(r_arm) - . += "[r_arm.icon_state]+o" - if(chest) - . += "[chest.icon_state]+o" - if(l_leg) - . += "[l_leg.icon_state]+o" - if(r_leg) - . += "[r_leg.icon_state]+o" - if(head) - . += "[head.icon_state]+o" + /* + There is a code that changes limb icon_state + ` limb.icon_state = "[limb_id]_[body_zone][is_dimorphic ? "_[limb_gender]" : ""]" ` + This is why you need to use initial() here. + */ + if(l_arm && initial(l_arm.icon_state)) + . += "[initial(l_arm.icon_state)]+o" + if(r_arm && initial(r_arm.icon_state)) + . += "[initial(r_arm.icon_state)]+o" + if(chest && initial(chest.icon_state)) + . += "[initial(chest.icon_state)]+o" + if(l_leg && initial(l_leg.icon_state)) + . += "[initial(l_leg.icon_state)]+o" + if(r_leg && initial(r_leg.icon_state)) + . += "[initial(r_leg.icon_state)]+o" + if(head && initial(head.icon_state)) + . += "[initial(head.icon_state)]+o" /obj/item/robot_suit/proc/check_completion() if(src.l_arm && src.r_arm) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 0f78045a55820..4454ecabadd4e 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -58,7 +58,7 @@ /obj/item/storage/box/update_overlays() . = ..() if(illustration) - . += illustration + . += mutable_appearance(icon, illustration) /obj/item/storage/box/attack_self(mob/user) ..() @@ -780,6 +780,7 @@ icon = 'icons/obj/cigarettes.dmi' icon_state = "matchbox" item_state = "zippo" + illustration = null worn_icon_state = "lighter" w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_BELT diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index cd9ed72415e04..aad445b349ac9 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -106,6 +106,7 @@ layer = BELOW_OBJ_LAYER update_mob_alpha() + /obj/structure/closet/update_overlays() . = ..() closet_update_overlays(.) @@ -116,9 +117,9 @@ var/overlay_state = isnull(base_icon_state) ? initial(icon_state) : base_icon_state if(opened && has_opened_overlay) var/mutable_appearance/door_overlay = mutable_appearance(icon, "[overlay_state]_open", alpha = src.alpha) - . += door_overlay door_overlay.overlays += emissive_blocker(door_overlay.icon, door_overlay.icon_state, src, alpha = door_overlay.alpha) // If we don't do this the door doesn't block emissives and it looks weird. - else if(has_closed_overlay) + . += door_overlay + else if((!opened) && has_closed_overlay) . += "[icon_door || overlay_state]_door" if(welded) . += icon_welded @@ -163,7 +164,6 @@ is_animating_door = FALSE vis_contents -= door_obj update_icon() - COMPILE_OVERLAYS(src) /obj/structure/closet/proc/get_door_transform(angle) var/matrix/M = matrix() diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index c8f7ec4095138..72a439d0193b6 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -21,6 +21,8 @@ var/obj/item/bodybag/foldedbag_instance = null var/tagged = 0 // so closet code knows to put the tag overlay back + has_closed_overlay = FALSE + /obj/structure/closet/body_bag/Destroy() // If we have a stored bag, and it's in nullspace (not in someone's hand), delete it. if (foldedbag_instance && !foldedbag_instance.loc) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index 256683aec27db..6eedbabdf2080 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -22,6 +22,8 @@ var/move_delay = FALSE var/egged = 0 + has_closed_overlay = FALSE + /obj/structure/closet/cardboard/relaymove(mob/living/user, direction) if(opened || move_delay || user.incapacitated() || !isturf(loc) || !has_gravity(loc)) return @@ -63,7 +65,6 @@ I.alpha = 0 animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING) - /obj/structure/closet/cardboard/metal name = "large metal box" desc = "THE COWARDS! THE FOOLS!" diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d552cbd2a255e..496c33bac6e47 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -79,7 +79,6 @@ is_animating_door = FALSE vis_contents -= door_obj update_icon() - COMPILE_OVERLAYS(src) /obj/structure/closet/crate/get_door_transform(crateanim_1, crateanim_2) var/matrix/M = matrix() @@ -318,14 +317,12 @@ dense_when_open = FALSE ///Becomes TRUE when the crate is being closed to ensure the compression sequence completes as expected. var/closing = FALSE + door_anim_time = 0 /obj/structure/closet/crate/capsule/update_icon() cut_overlays() icon_state = "capsule[opened ? "_open" : "_close"]" -/obj/structure/closet/crate/capsule/animate_door(closing) - return FALSE - /obj/structure/closet/crate/capsule/insertion_allowed(atom/movable/AM) if(!isitem(AM)) return FALSE //Capsule pod can only hold items, not mobs, structures or otherwise diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm index 2fda6f1ebc050..4af6c830db03c 100644 --- a/code/game/objects/structures/crates_lockers/crates/critter.dm +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -58,7 +58,6 @@ is_animating_door = FALSE vis_contents -= door_obj update_icon() - COMPILE_OVERLAYS(src) /obj/structure/closet/crate/critter/get_door_transform(crateanim_1, crateanim_2) var/matrix/M = matrix() diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index b2166db10b646..d802ea8f5a8cc 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -13,6 +13,9 @@ close_sound_volume = 50 door_anim_time = 0 + has_opened_overlay = FALSE + has_closed_overlay = FALSE + /obj/structure/closet/crate/large/attack_hand(mob/user) add_fingerprint(user) if(manifest) diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 36dc95bc3aaec..b7d15db676039 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -310,7 +310,6 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) qdel(I) randomize_human(D) JB.equip(D, TRUE, FALSE) - COMPILE_OVERLAYS(D) var/icon/I = icon(getFlatIcon(D), frame = 1) final.Insert(I, JB.title) qdel(D) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index ac936aa73f97c..24df54817ddc2 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -286,7 +286,6 @@ equipAntagOnDummy(mannequin, ert) - COMPILE_OVERLAYS(mannequin) CHECK_TICK var/icon/preview_icon = icon('icons/effects/effects.dmi', "nothing") preview_icon.Scale(48+32, 16+32) diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index be861bd50e849..181aff92e082d 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -13,6 +13,7 @@ icon = 'icons/obj/abductor.dmi' icon_state = "camera" + icon_keyboard = null base_icon_state = null smoothing_flags = NONE smoothing_groups = null diff --git a/code/modules/antagonists/role_preference/_role_preference.dm b/code/modules/antagonists/role_preference/_role_preference.dm index 37d8cc2437a16..19a0e9555aeef 100644 --- a/code/modules/antagonists/role_preference/_role_preference.dm +++ b/code/modules/antagonists/role_preference/_role_preference.dm @@ -21,7 +21,6 @@ /datum/role_preference/proc/render_preview_outfit(datum/outfit/outfit, mob/living/carbon/human/dummy) dummy = dummy || new /mob/living/carbon/human/dummy/consistent dummy.equipOutfit(outfit, visualsOnly = TRUE) - COMPILE_OVERLAYS(dummy) var/icon = getFlatIcon(dummy) // We don't want to qdel the dummy right away, since its items haven't initialized yet. diff --git a/code/modules/client/preferences/middleware/species.dm b/code/modules/client/preferences/middleware/species.dm index f960128e0d2f7..a6e87b30eedea 100644 --- a/code/modules/client/preferences/middleware/species.dm +++ b/code/modules/client/preferences/middleware/species.dm @@ -20,7 +20,6 @@ dummy.set_species(species_type) dummy.equipOutfit(/datum/outfit/job/assistant/consistent, visualsOnly = TRUE) dummy.dna.species.prepare_human_for_preview(dummy) - COMPILE_OVERLAYS(dummy) var/icon/dummy_icon = getFlatIcon(dummy) dummy_icon.Scale(64, 64) diff --git a/code/modules/client/preferences/submodules/preference_character_preview.dm b/code/modules/client/preferences/submodules/preference_character_preview.dm index 11c0556917d8e..1f26e9cf4bcce 100644 --- a/code/modules/client/preferences/submodules/preference_character_preview.dm +++ b/code/modules/client/preferences/submodules/preference_character_preview.dm @@ -27,7 +27,6 @@ else apply_loadout_to_mob(mannequin, mannequin, preference_source = parent, on_dummy = TRUE) - COMPILE_OVERLAYS(mannequin) return mannequin.appearance // This is necessary because you can open the set preferences menu before diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index dec029001110a..4e455f9b90925 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -15,6 +15,7 @@ name = "auxillary base management console" icon = 'icons/obj/terminals.dmi' icon_state = "dorm_available" + icon_keyboard = null base_icon_state = null smoothing_flags = NONE smoothing_groups = null diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 225bf40f36e9c..8e4327eb40cdd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -818,6 +818,9 @@ GLOBAL_DATUM(blackbox, /obj/machinery/smartfridge/black_box) anchored = TRUE resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE var/mob/living/simple_animal/holder_animal + door_anim_time = 0 + has_opened_overlay = FALSE + has_closed_overlay = FALSE /obj/structure/closet/stasis/process() if(holder_animal) diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index 985a579a6a9ff..cdadc374913e0 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -39,7 +39,6 @@ var/mob/living/carbon/human/dummy/dummy = new dummy.equipOutfit(outfit) dummy.set_species(/datum/species/zombie) - COMPILE_OVERLAYS(dummy) icon = getFlatIcon(dummy) qdel(dummy) diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index feac0407bc148..9389174239e8f 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -98,3 +98,6 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/item/computer_hardware/battery) desc = "A tiny power cell, commonly seen in low-end portable microcomputers." icon_state = "cell_micro" maxcharge = 300 + +/obj/item/stock_parts/cell/computer/update_icon() + return diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 13a1f4bd3dee4..4ba575c137153 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -71,6 +71,8 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/item/stock_parts/cell) . = ..() if(grown_battery) . += mutable_appearance('icons/obj/power.dmi', "grown_wires") + return // we don't add more overlays if this is a plant battery + if(charge < 0.01) return else if(charge/maxcharge >=0.995) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 16769170a7960..65a07e59bce14 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -225,7 +225,7 @@ if(modifystate) var/obj/item/ammo_casing/energy/shot = ammo_type[select] if(single_shot_type_overlay) - . += "[icon_state]_[initial(shot.select_name)]" + . += mutable_appearance(icon, "[icon_state]_[initial(shot.select_name)]") overlay_icon_state += "_[initial(shot.select_name)]" var/ratio = get_charge_ratio() diff --git a/code/modules/research/nanites/nanite_cloud_controller.dm b/code/modules/research/nanites/nanite_cloud_controller.dm index 717f2fcab252c..95cd6ba2180c0 100644 --- a/code/modules/research/nanites/nanite_cloud_controller.dm +++ b/code/modules/research/nanites/nanite_cloud_controller.dm @@ -3,6 +3,7 @@ desc = "Stores and controls nanite cloud backups." icon = 'icons/obj/machines/research.dmi' icon_state = "nanite_cloud_controller" + icon_keyboard = null circuit = /obj/item/circuitboard/computer/nanite_cloud_controller //these muthafuckas arent supposed to smooth diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index 31da296ea3d20..cb871dc68e638 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -37,6 +37,7 @@ name = "syndicate assault pod control" desc = "Controls the drop pod's launch system." icon = 'icons/obj/terminals.dmi' + icon_keyboard = null base_icon_state = null smoothing_flags = NONE diff --git a/icons/obj/dice.dmi b/icons/obj/dice.dmi index 9ecbb9363d3ed..fc8bf6bcbe4b4 100644 Binary files a/icons/obj/dice.dmi and b/icons/obj/dice.dmi differ