From bb5a34eaf8734cfaf5d2b721233007bd1ce2f177 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Sat, 23 Dec 2017 13:27:51 -0600 Subject: [PATCH] Misc. Optimizations (#3993) changes: Overlays now creates less temporary lists. Falling no longer queues unsimulated atoms that wouldn't fall anyways (incl. LOs). Pixel-shifted AO is now cached too. Changed some references to get_map_cell() to macro equivalents in random maps. Added smoothing hinting to the icon smoother, allowing for major performance improvements in common cases. Space initialization no longer involves appearance churn (and is much faster as a result). --- code/_helpers/icon_smoothing.dm | 144 +++++++++++++-------- code/_helpers/lists.dm | 6 + code/controllers/subsystems/icon_cache.dm | 31 ++++- code/controllers/subsystems/icon_smooth.dm | 1 + code/controllers/subsystems/overlays.dm | 46 ++++--- code/game/turfs/simulated/wall_types.dm | 1 + code/game/turfs/space/space.dm | 20 +-- code/modules/ambient_occlusion/ao_turf.dm | 27 ++-- code/modules/lighting/lighting_overlay.dm | 4 +- code/modules/mining/mine_turfs.dm | 5 +- code/modules/multiz/turf.dm | 28 ++-- code/modules/random_map/random_map.dm | 31 +++-- 12 files changed, 213 insertions(+), 131 deletions(-) diff --git a/code/_helpers/icon_smoothing.dm b/code/_helpers/icon_smoothing.dm index 4050d02318e..b664eb02082 100644 --- a/code/_helpers/icon_smoothing.dm +++ b/code/_helpers/icon_smoothing.dm @@ -39,6 +39,10 @@ #define SMOOTH_QUEUED 16 //atom is currently queued to smooth. #define SMOOTH_NO_CLEAR_ICON 32 // don't clear the atom's icon_state on smooth. +#define SMOOTHHINT_CUT_ON_ALL_F 1 // Don't apply overlays if they're all the 'f' state. +#define SMOOTHHINT_ONLY_MATCH_TURF 2 // Only try to match turfs (this is faster than matching all atoms) +#define SMOOTHHINT_TARGETS_NOT_UNIQUE 4 // The smoother can assume that all atoms of this type will have the same canSmoothWith value. + #define NULLTURF_BORDER 123456789 #define DEFAULT_UNDERLAY_ICON 'icons/turf/floors.dmi' @@ -47,6 +51,7 @@ /atom var/smooth = SMOOTH_FALSE + var/smoothing_hints = SMOOTHHINT_TARGETS_NOT_UNIQUE var/tmp/top_left_corner var/tmp/top_right_corner var/tmp/bottom_left_corner @@ -75,47 +80,63 @@ var/adjacencies = 0 - var/atom/movable/AM + if (smoothing_hints & SMOOTHHINT_ONLY_MATCH_TURF) + var/turf/T + var/list/tcache + if (smoothing_hints & SMOOTHHINT_TARGETS_NOT_UNIQUE) + tcache = SSicon_smooth.typecachecache[type] + if (!tcache) + tcache = typecacheof(canSmoothWith || type, FALSE, !(smooth & SMOOTH_MORE)) + SSicon_smooth.typecachecache[type] = tcache + else + tcache = typecacheof(canSmoothWith || type, FALSE, !(smooth & SMOOTH_MORE)) - for(var/direction in cardinal) - AM = find_type_in_direction(src, direction) - if(AM == NULLTURF_BORDER) - if((smooth & SMOOTH_BORDER)) + if (smooth & SMOOTH_BORDER) + CALCULATE_NEIGHBORS(src, adjacencies, T, !T || tcache[T.type]) + else + CALCULATE_NEIGHBORS(src, adjacencies, T, T && tcache[T.type]) + else + var/atom/movable/AM + + for(var/direction in cardinal) + AM = find_type_in_direction(src, direction) + if(AM == NULLTURF_BORDER) + if((smooth & SMOOTH_BORDER)) + adjacencies |= 1 << direction + else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) adjacencies |= 1 << direction - else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) - adjacencies |= 1 << direction - if(adjacencies & N_NORTH) - if(adjacencies & N_WEST) - AM = find_type_in_direction(src, NORTHWEST) - if(AM == NULLTURF_BORDER) - if((smooth & SMOOTH_BORDER)) + if(adjacencies & N_NORTH) + if(adjacencies & N_WEST) + AM = find_type_in_direction(src, NORTHWEST) + if(AM == NULLTURF_BORDER) + if((smooth & SMOOTH_BORDER)) + adjacencies |= N_NORTHWEST + else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) adjacencies |= N_NORTHWEST - else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) - adjacencies |= N_NORTHWEST - if(adjacencies & N_EAST) - AM = find_type_in_direction(src, NORTHEAST) - if(AM == NULLTURF_BORDER) - if((smooth & SMOOTH_BORDER)) + if(adjacencies & N_EAST) + AM = find_type_in_direction(src, NORTHEAST) + if(AM == NULLTURF_BORDER) + if((smooth & SMOOTH_BORDER)) + adjacencies |= N_NORTHEAST + else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) adjacencies |= N_NORTHEAST - else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) - adjacencies |= N_NORTHEAST - if(adjacencies & N_SOUTH) - if(adjacencies & N_WEST) - AM = find_type_in_direction(src, SOUTHWEST) - if(AM == NULLTURF_BORDER) - if((smooth & SMOOTH_BORDER)) + if(adjacencies & N_SOUTH) + if(adjacencies & N_WEST) + AM = find_type_in_direction(src, SOUTHWEST) + if(AM == NULLTURF_BORDER) + if((smooth & SMOOTH_BORDER)) + adjacencies |= N_SOUTHWEST + else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) adjacencies |= N_SOUTHWEST - else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) - adjacencies |= N_SOUTHWEST - if(adjacencies & N_EAST) - AM = find_type_in_direction(src, SOUTHEAST) - if(AM == NULLTURF_BORDER) - if((smooth & SMOOTH_BORDER)) + if(adjacencies & N_EAST) + AM = find_type_in_direction(src, SOUTHEAST) + if(AM == NULLTURF_BORDER) + if((smooth & SMOOTH_BORDER)) + adjacencies |= N_SOUTHEAST + else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) adjacencies |= N_SOUTHEAST - else if( (AM && !istype(AM)) || (istype(AM) && AM.anchored) ) - adjacencies |= N_SOUTHEAST return adjacencies @@ -207,11 +228,13 @@ underlays = U /proc/cardinal_smooth(atom/A, adjacencies) + var/num_of_f = 0 //NW CORNER var/nw = "1-i" if((adjacencies & N_NORTH) && (adjacencies & N_WEST)) if(adjacencies & N_NORTHWEST) nw = "1-f" + num_of_f++ else nw = "1-nw" else @@ -225,6 +248,7 @@ if((adjacencies & N_NORTH) && (adjacencies & N_EAST)) if(adjacencies & N_NORTHEAST) ne = "2-f" + num_of_f++ else ne = "2-ne" else @@ -238,6 +262,7 @@ if((adjacencies & N_SOUTH) && (adjacencies & N_WEST)) if(adjacencies & N_SOUTHWEST) sw = "3-f" + num_of_f++ else sw = "3-sw" else @@ -251,6 +276,7 @@ if((adjacencies & N_SOUTH) && (adjacencies & N_EAST)) if(adjacencies & N_SOUTHEAST) se = "4-f" + num_of_f++ else se = "4-se" else @@ -289,7 +315,7 @@ if(Old) A.cut_overlay(Old) - if(New) + if(New && (num_of_f != 4 || !(A.smoothing_hints & SMOOTHHINT_CUT_ON_ALL_F))) A.add_overlay(New) if (A.icon_state && !(A.smooth & SMOOTH_NO_CLEAR_ICON)) @@ -362,33 +388,43 @@ if(!target_turf) return NULLTURF_BORDER - if(source.canSmoothWith) - var/atom/A - if(source.smooth & SMOOTH_MORE) + if (source.smoothing_hints & SMOOTHHINT_TARGETS_NOT_UNIQUE) + var/list/tcache = SSicon_smooth.typecachecache[source.type] + if (!tcache) + tcache = typecacheof(source.canSmoothWith || source.type, FALSE, !(source.smooth & SMOOTH_MORE)) + SSicon_smooth.typecachecache[source.type] = tcache + + if (is_type_in_typecache(target_turf, tcache)) + return target_turf + return typecache_first_match(target_turf.contents, tcache) + else + if(source.canSmoothWith) + var/atom/A + if(source.smooth & SMOOTH_MORE) + for(var/a_type in source.canSmoothWith) + if( istype(target_turf, a_type) ) + return target_turf + if (ispath(a_type, /turf)) + continue + A = locate(a_type) in target_turf + if(A) + return A + return null + for(var/a_type in source.canSmoothWith) - if( istype(target_turf, a_type) ) + if(a_type == target_turf.type) return target_turf if (ispath(a_type, /turf)) continue A = locate(a_type) in target_turf - if(A) + if(A && A.type == a_type) return A return null - - for(var/a_type in source.canSmoothWith) - if(a_type == target_turf.type) - return target_turf - if (ispath(a_type, /turf)) - continue - A = locate(a_type) in target_turf - if(A && A.type == a_type) - return A - return null - else - if(isturf(source)) - return source.type == target_turf.type ? target_turf : null - var/atom/A = locate(source.type) in target_turf - return A && A.type == source.type ? A : null + else + if(isturf(source)) + return source.type == target_turf.type ? target_turf : null + var/atom/A = locate(source.type) in target_turf + return A && A.type == source.type ? A : null //Icon smoothing helpers /proc/smooth_zlevel(var/zlevel, now = FALSE) diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 6bfe425935c..f9fb8680235 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -318,6 +318,12 @@ if(typecache_include[A.type] && !typecache_exclude[A.type]) . += A +/proc/typecache_first_match(list/target, list/typecache) + for (var/thing in target) + var/datum/D = thing + if (typecache[D.type]) + return D + //Like typesof() or subtypesof(), but returns a typecache instead of a list /proc/typecacheof(path, ignore_root_path, only_root_path = FALSE) if(ispath(path)) diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index 00041ce6d15..3f37cf53504 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -2,7 +2,8 @@ /datum/controller/subsystem/icon_cache name = "Icon Cache" - flags = SS_NO_FIRE | SS_NO_INIT + flags = SS_NO_FIRE + init_order = SS_INIT_MISC_FIRST // Cached bloody overlays, key is object type. var/list/bloody_cache = list() @@ -67,9 +68,20 @@ var/list/rgb_blend_cache = list() // not an icon per-se, but this proc could be expensive so we might as well cache it. + var/list/space_dust_cache = list() + + var/list/space_cache = list() + /datum/controller/subsystem/icon_cache/New() NEW_SS_GLOBAL(SSicon_cache) +/datum/controller/subsystem/icon_cache/Initialize() + build_dust_cache() + build_space_cache() + setup_collar_mappings() + setup_uniform_mappings() + ..() + /datum/controller/subsystem/icon_cache/proc/setup_collar_mappings() collar_states = list() for (var/i in icon_states('icons/mob/collar.dmi')) @@ -94,3 +106,20 @@ var/image/I = new(icon, icon_state) I.color = color return I + +/datum/controller/subsystem/icon_cache/proc/build_dust_cache() + for (var/i in 0 to 25) + var/image/im = image('icons/turf/space_parallax1.dmi',"[i]") + im.plane = PLANE_SPACE_DUST + im.alpha = 80 + im.blend_mode = BLEND_ADD + space_dust_cache["[i]"] = im + +/datum/controller/subsystem/icon_cache/proc/build_space_cache() + for (var/i in 0 to 25) + var/image/I = new() + I.appearance = /turf/space + var/istr = "[i]" + I.icon_state = istr + I.overlays += space_dust_cache[istr] + space_cache[istr] = I diff --git a/code/controllers/subsystems/icon_smooth.dm b/code/controllers/subsystems/icon_smooth.dm index 81365632079..abc44a95878 100644 --- a/code/controllers/subsystems/icon_smooth.dm +++ b/code/controllers/subsystems/icon_smooth.dm @@ -8,6 +8,7 @@ var/datum/controller/subsystem/icon_smooth/SSicon_smooth flags = SS_TICKER | SS_FIRE_IN_LOBBY var/list/smooth_queue = list() + var/list/typecachecache = list() var/explosion_in_progress = FALSE diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 9a6f5afb995..87954a6fb84 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -102,25 +102,33 @@ var/datum/controller/subsystem/overlays/SSoverlays . = iconbro.appearance icon_cache[icon] = . -/atom/proc/build_appearance_list(new_overlays) - var/static/image/appearance_bro = new() - if (!islist(new_overlays)) - new_overlays = list(new_overlays) - else - listclearnulls(new_overlays) - for (var/i in 1 to length(new_overlays)) - var/image/cached_overlay = new_overlays[i] - if (istext(cached_overlay)) - new_overlays[i] = iconstate2appearance(icon, cached_overlay) - else if(isicon(cached_overlay)) - new_overlays[i] = icon2appearance(cached_overlay) - else //image probable - appearance_bro.appearance = cached_overlay - if(!ispath(cached_overlay)) - appearance_bro.dir = cached_overlay.dir - new_overlays[i] = appearance_bro.appearance - return new_overlays +#define APPEARANCEIFY(origin, target) \ + if (istext(origin)) { \ + target = iconstate2appearance(icon, origin); \ + } \ + else if (isicon(origin)) { \ + target = icon2appearance(origin); \ + } \ + else { \ + appearance_bro.appearance = origin; \ + if (!ispath(origin)) { \ + appearance_bro.dir = origin.dir; \ + } \ + target = appearance_bro.appearance; \ + } +/atom/proc/build_appearance_list(atom/new_overlays) + var/static/image/appearance_bro = new + if (islist(new_overlays)) + listclearnulls(new_overlays) + for (var/i in 1 to length(new_overlays)) + var/image/cached_overlay = new_overlays[i] + APPEARANCEIFY(cached_overlay, new_overlays[i]) + return new_overlays + else + APPEARANCEIFY(new_overlays, .) + +#undef APPEARANCEIFY #define NOT_QUEUED_ALREADY (!(overlay_queued)) #define QUEUE_FOR_COMPILE overlay_queued = TRUE; SSoverlays.processing += src; @@ -165,7 +173,7 @@ var/datum/controller/subsystem/overlays/SSoverlays overlays = build_appearance_list(overlays) - if (!overlays.len) + if (!overlays || (islist(overlays) && !overlays.len)) // No point trying to compile if we don't have any overlays. return diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm index 7d470d4bcb2..add91920f1e 100644 --- a/code/game/turfs/simulated/wall_types.dm +++ b/code/game/turfs/simulated/wall_types.dm @@ -22,6 +22,7 @@ icon = 'icons/turf/smooth/cult_wall.dmi' canSmoothWith = null smooth = SMOOTH_TRUE + smoothing_hints = SMOOTHHINT_TARGETS_NOT_UNIQUE | SMOOTHHINT_ONLY_MATCH_TURF icon_state = "cult" /turf/simulated/wall/rusty diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index ea1cd9ca474..3ebc54cc4a2 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -10,30 +10,15 @@ temperature = T20C thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT - - var/static/list/dust_cache // heat_capacity = 700000 No. is_hole = TRUE permit_ao = FALSE -/turf/space/proc/build_dust_cache() - LAZYINITLIST(dust_cache) - for (var/i in 0 to 25) - var/image/im = image('icons/turf/space_parallax1.dmi',"[i]") - im.plane = PLANE_SPACE_DUST - im.alpha = 80 - im.blend_mode = BLEND_ADD - dust_cache["[i]"] = im - // Copypaste of parent for performance. /turf/space/Initialize() - icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" - if (!dust_cache) - build_dust_cache() - - add_overlay(dust_cache[icon_state]) + appearance = SSicon_cache.space_cache["[((x + y) ^ ~(x * y) + z) % 25]"] update_starlight() if (initialized) @@ -76,7 +61,8 @@ set_light(config.starlight) return - set_light(0) + if (light_range) + set_light(0) /turf/space/attackby(obj/item/C as obj, mob/user as mob) diff --git a/code/modules/ambient_occlusion/ao_turf.dm b/code/modules/ambient_occlusion/ao_turf.dm index c1e1b143021..5a649a17dac 100644 --- a/code/modules/ambient_occlusion/ao_turf.dm +++ b/code/modules/ambient_occlusion/ao_turf.dm @@ -26,15 +26,21 @@ var/turf/T CALCULATE_NEIGHBORS(src, ao_neighbors, T, AO_TURF_CHECK(T)) -/proc/make_ao_image(corner, i) +/proc/make_ao_image(corner, i, px = 0, py = 0, pz = 0, pw = 0) var/list/cache = SSicon_cache.ao_cache var/cstr = "[corner]" - var/key = "[cstr]-[i]" + var/key = "[cstr]-[i]-[px]/[py]/[pz]/[pw]" var/image/I = image('icons/turf/flooring/shadows.dmi', cstr, dir = 1 << (i-1)) I.alpha = WALL_AO_ALPHA I.blend_mode = BLEND_OVERLAY I.appearance_flags = RESET_ALPHA|RESET_COLOR|TILE_BOUND + // If there's an offset, counteract it. + if (px || py || pz || pw) + I.pixel_x = -px + I.pixel_y = -py + I.pixel_z = -pz + I.pixel_w = -pw . = cache[key] = I @@ -71,22 +77,11 @@ corner |= 4 if (corner != 7) // 7 is the 'no shadows' state, no reason to add overlays for it. - var/image/I = cache["[corner]-[i]"] + var/image/I = cache["[corner]-[i]-[pixel_x]/[pixel_y]/[pixel_z]/[pixel_w]"] if (!I) - I = make_ao_image(corner, i) // this will also add the image to the cache. + I = make_ao_image(corner, i, pixel_x, pixel_y, pixel_z, pixel_w) // this will also add the image to the cache. - if (!pixel_x && !pixel_y && !pixel_w && !pixel_z) // We can only use the cache if we're not shifting. - LAZYADD(ao_overlays, I) - else - // There's a pixel var set, so we're going to need to make a new instance just for this type. - var/mutable_appearance/MA = new(I) - // We invert the offsets here to counteract the pixel shifting of the parent turf. - MA.pixel_x = -(pixel_x) - MA.pixel_y = -(pixel_y) - MA.pixel_w = -(pixel_w) - MA.pixel_z = -(pixel_z) - - LAZYADD(ao_overlays, MA) + LAZYADD(ao_overlays, I) UNSETEMPTY(ao_overlays) diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index 715233d8686..4757f8ac849 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -45,7 +45,7 @@ /atom/movable/lighting_overlay/proc/update_overlay() var/turf/T = loc - if (!istype(T)) // Erm... + if (!isturf(T)) // Erm... if (loc) warning("A lighting overlay realised its loc was NOT a turf (actual loc: [loc], [loc.type]) in update_overlay() and got deleted!") @@ -92,7 +92,7 @@ else if (!luminosity) icon_state = LIGHTING_DARKNESS_ICON_STATE color = null - else if (ALL_EQUAL && rr == LIGHTING_DEFAULT_TUBE_R && rg == LIGHTING_DEFAULT_TUBE_G && rb == LIGHTING_DEFAULT_TUBE_B) + else if (rr == LIGHTING_DEFAULT_TUBE_R && rg == LIGHTING_DEFAULT_TUBE_G && rb == LIGHTING_DEFAULT_TUBE_B && ALL_EQUAL) icon_state = LIGHTING_STATION_ICON_STATE color = null else diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 417cc888dc9..66a23d10c21 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -15,13 +15,15 @@ gender = PLURAL var/icon/actual_icon = 'icons/turf/smooth/rock_wall.dmi' layer = 2.01 - smooth = SMOOTH_MORE | SMOOTH_BORDER + smooth = SMOOTH_MORE | SMOOTH_BORDER | SMOOTH_NO_CLEAR_ICON + smoothing_hints = SMOOTHHINT_CUT_ON_ALL_F | SMOOTHHINT_ONLY_MATCH_TURF | SMOOTHHINT_TARGETS_NOT_UNIQUE canSmoothWith = list( /turf/simulated/mineral, /turf/simulated/wall, /turf/unsimulated/wall, /turf/simulated/shuttle ) + oxygen = 0 nitrogen = 0 opacity = 1 @@ -509,6 +511,7 @@ icon_state = "ash" desc = "A fine grey ash. Looks pretty tightly packed." smooth = SMOOTH_MORE | SMOOTH_BORDER | SMOOTH_NO_CLEAR_ICON + smoothing_hints = SMOOTHHINT_CUT_ON_ALL_F | SMOOTHHINT_ONLY_MATCH_TURF | SMOOTHHINT_TARGETS_NOT_UNIQUE gender = PLURAL canSmoothWith = list( /turf/simulated/floor/asteroid, diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index 6f753b20552..04c9478fef1 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -162,7 +162,7 @@ ..() update() -/turf/simulated/open/Initialize() +/turf/simulated/open/Initialize(mapload) . = ..() icon_state = "" // Clear out the debug icon. SSopenturf.openspace_turfs += src @@ -170,23 +170,31 @@ if (no_mutate && plane == PLANE_SPACE_BACKGROUND) // If the plane is default and we're a no_mutate turf, force it to 0 so the icon works properly. plane = 0 - update() + update(mapload) /** * Updates the turf with open turf's variables and basically resets it properly. */ -/turf/simulated/open/proc/update() +/turf/simulated/open/proc/update(mapload = FALSE) below = GetBelow(src) // Edge case for when an open turf is above space on the lowest level. if (below) below.above = src - levelupdate() - if (is_hole) - for (var/atom/movable/A in src) - ADD_FALLING_ATOM(A) - update_icon() + if (mapload) + for (var/obj/O in src) // We're not going to try to make mobs fall here for performance reasons - they shouldn't be mapped in on openturfs anyways. + if (is_hole && O.simulated) + ADD_FALLING_ATOM(O) + else + for (var/thing in src) + var/obj/O = thing // This might not be an obj. + if (isobj(O)) + O.hide(0) + if (is_hole && O.simulated) + ADD_FALLING_ATOM(O) + + update_icon(mapload) /turf/simulated/open/update_dirt() return 0 @@ -196,12 +204,12 @@ for(var/obj/O in src) O.hide(0) -/turf/simulated/open/update_icon() +/turf/simulated/open/update_icon(mapload) if(!updating && below) updating = TRUE SSopenturf.queued_turfs += src - if (above) // Even if we're already updating, the turf above us might not be. + if (!mapload && above) // Even if we're already updating, the turf above us might not be. // Cascade updates until we hit the top openturf. above.update_icon() diff --git a/code/modules/random_map/random_map.dm b/code/modules/random_map/random_map.dm index faae9b37854..10f20064fb6 100644 --- a/code/modules/random_map/random_map.dm +++ b/code/modules/random_map/random_map.dm @@ -26,6 +26,7 @@ var/global/list/map_count = list() // Storage for the final iteration of the map. var/list/map = list() // Actual map. + var/tmp/map_len = 0 // If set, all sleep(-1) calls will be skipped. // Test to see if rand_seed() can be used reliably. @@ -100,23 +101,28 @@ var/global/list/map_count = list() if(!user) user = world - var/dat = "+------+
" + map_len = map.len + + var/list/dat = "+------+
" for(var/x = 1, x <= limit_x, x++) for(var/y = 1, y <= limit_y, y++) - var/current_cell = get_map_cell(x,y) - if(current_cell) - dat += get_map_char(map[current_cell]) + var/tmp_cell + TRANSLATE_AND_VERIFY_COORD_MLEN(x, y, map_len) + if(tmp_cell) + dat += get_map_char(map[tmp_cell]) dat += "
" - user << "[dat]+------+
" + dat += "+------+
" + user << dat.Join() /datum/random_map/proc/set_map_size() map = list() map.len = limit_x * limit_y /datum/random_map/proc/seed_map() + map_len = map.len for(var/x = 1, x <= limit_x, x++) for(var/y = 1, y <= limit_y, y++) - var/current_cell = get_map_cell(x,y) + var/current_cell = TRANSLATE_COORD(x, y) // Coordinate cannot be invalid here, so use the faster no-validate one. if(prob(initial_wall_cell)) map[current_cell] = WALL_CHAR else @@ -125,7 +131,7 @@ var/global/list/map_count = list() /datum/random_map/proc/clear_map() for(var/x = 1, x <= limit_x, x++) for(var/y = 1, y <= limit_y, y++) - map[get_map_cell(x,y)] = 0 + map[TRANSLATE_COORD(x, y)] = 0 /datum/random_map/proc/generate() seed_map() @@ -154,6 +160,8 @@ var/global/list/map_count = list() if(!origin_y) origin_y = 1 if(!origin_z) origin_z = 1 + map_len = map.len + for(var/x = 1, x <= limit_x, x++) for(var/y = 1, y <= limit_y, y++) if(!priority_process) @@ -161,16 +169,17 @@ var/global/list/map_count = list() apply_to_turf(x,y) /datum/random_map/proc/apply_to_turf(var/x,var/y) - var/current_cell = get_map_cell(x,y) - if(!current_cell) + var/tmp_cell + TRANSLATE_AND_VERIFY_COORD_MLEN(x, y, map_len) + if(!tmp_cell) return 0 var/turf/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z) if(!T || (target_turf_type && !istype(T,target_turf_type))) return 0 - var/newpath = get_appropriate_path(map[current_cell]) + var/newpath = get_appropriate_path(map[tmp_cell]) if(newpath) T.ChangeTurf(newpath) - get_additional_spawns(map[current_cell],T,get_spawn_dir(x, y)) + get_additional_spawns(map[tmp_cell],T,get_spawn_dir(x, y)) return T /datum/random_map/proc/get_spawn_dir()