diff --git a/code/__HELPERS/areas.dm b/code/__HELPERS/areas.dm index 07996b978117..c37c47e67fda 100644 --- a/code/__HELPERS/areas.dm +++ b/code/__HELPERS/areas.dm @@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng if(break_if_found[checkT.type] || break_if_found[checkT.loc.type]) return FALSE var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE) - if(!cardinal_cache["[dir]"] || checkT.blocks_air || !TURFS_CAN_SHARE(sourceT, checkT)) + if(!cardinal_cache["[dir]"] || !TURFS_CAN_SHARE(sourceT, checkT)) continue found_turfs += checkT // Since checkT is connected, add it to the list to be processed @@ -226,13 +226,11 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng // Now their turfs var/list/turfs = list() for(var/area/pull_from as anything in areas_to_pull) - var/list/our_turfs = pull_from.get_contained_turfs() - if(target_z == 0) - turfs += our_turfs + if (target_z == 0) + for (var/list/zlevel_turfs as anything in pull_from.get_zlevel_turf_lists()) + turfs += zlevel_turfs else - for(var/turf/turf_in_area as anything in our_turfs) - if(target_z == turf_in_area.z) - turfs += turf_in_area + turfs += pull_from.get_turfs_by_zlevel(target_z) return turfs diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index b33bfa950244..21e0b623080d 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -1,4 +1,8 @@ -#define CULT_POLL_WAIT 2400 +///Time before being allowed to select a new cult leader again +#define CULT_POLL_WAIT (240 SECONDS) + +/// Returns either the error landmark or the location of the room. Needless to say, if this is used, it means things have gone awry. +#define GET_ERROR_ROOM ((locate(/obj/effect/landmark/error) in GLOB.landmarks_list) || locate(4,4,1)) /proc/get_area_name(atom/X, format_text = FALSE, is_sensor = FALSE) var/area/A = isarea(X) ? X : get_area(X) diff --git a/code/controllers/subsystem/area_contents.dm b/code/controllers/subsystem/area_contents.dm index 83555a2c0e95..9319c0eab0f3 100644 --- a/code/controllers/subsystem/area_contents.dm +++ b/code/controllers/subsystem/area_contents.dm @@ -1,4 +1,4 @@ -#define ALLOWED_LOOSE_TURFS 500 +#define ALLOWED_LOOSE_TURFS 100 /** * Responsible for managing the sizes of area.contained_turfs and area.turfs_to_uncontain * These lists do not check for duplicates, which is fine, but it also means they can balloon in size over time @@ -17,8 +17,11 @@ SUBSYSTEM_DEF(area_contents) var/total_clearing_from = 0 var/total_to_clear = 0 for(var/area/to_clear as anything in marked_for_clearing) - total_to_clear += length(to_clear.turfs_to_uncontain) - total_clearing_from += length(to_clear.contained_turfs) + for (var/area_zlevel in 1 to length(to_clear.turfs_to_uncontain_by_zlevel)) + if (length(to_clear.turfs_to_uncontain_by_zlevel[area_zlevel])) + total_to_clear += length(to_clear.turfs_to_uncontain_by_zlevel[area_zlevel]) + if (length(to_clear.turfs_by_zlevel) >= area_zlevel) //this should always be true, but stat_entry is no place for runtimes. fire() can handle that + total_clearing_from += length(to_clear.turfs_by_zlevel[area_zlevel]) msg = "A:[length(currentrun)] MR:[length(marked_for_clearing)] TC:[total_to_clear] CF:[total_clearing_from]" return ..() @@ -27,8 +30,11 @@ SUBSYSTEM_DEF(area_contents) var/total_clearing_from = 0 var/total_to_clear = 0 for(var/area/to_clear as anything in marked_for_clearing) - total_to_clear += length(to_clear.turfs_to_uncontain) - total_clearing_from += length(to_clear.contained_turfs) + for (var/area_zlevel in 1 to length(to_clear.turfs_to_uncontain_by_zlevel)) + if (length(to_clear.turfs_to_uncontain_by_zlevel[area_zlevel])) + total_to_clear += length(to_clear.turfs_to_uncontain_by_zlevel[area_zlevel]) + if (length(to_clear.turfs_by_zlevel) >= area_zlevel) //this should always be true, but stat_entry is no place for runtimes. fire() can handle that + total_clearing_from += length(to_clear.turfs_by_zlevel[area_zlevel]) .["areas"] = length(currentrun) .["marked_for_clearing"] = length(marked_for_clearing) .["total_to_clear"] = total_to_clear @@ -40,8 +46,10 @@ SUBSYSTEM_DEF(area_contents) while(length(currentrun)) var/area/test = currentrun[length(currentrun)] - if(length(test.turfs_to_uncontain) > ALLOWED_LOOSE_TURFS) - marked_for_clearing |= test + for (var/area_zlevel in 1 to length(test.turfs_to_uncontain_by_zlevel)) + if(length(test.turfs_to_uncontain_by_zlevel[area_zlevel]) > ALLOWED_LOOSE_TURFS) + marked_for_clearing |= test + break currentrun.len-- if(MC_TICK_CHECK) return @@ -50,17 +58,27 @@ SUBSYSTEM_DEF(area_contents) while(length(marked_for_clearing)) var/area/clear = marked_for_clearing[length(marked_for_clearing)] - // The operation of cutting large lists can be expensive - // It scales almost directly with the size of the list we're cutting with - // Because of this, we're gonna stick to cutting 1 entry at a time - // There's no reason to batch it I promise, this is faster. No overtime too - var/amount_cut = 0 - var/list/cut_from = clear.turfs_to_uncontain - for(amount_cut in 1 to length(cut_from)) - clear.contained_turfs -= cut_from[amount_cut] - if(MC_TICK_CHECK) - cut_from.Cut(1, amount_cut + 1) - return + for (var/area_zlevel in 1 to length(clear.turfs_to_uncontain_by_zlevel)) + if (!length(clear.turfs_to_uncontain_by_zlevel[area_zlevel])) + continue + if (length(clear.turfs_by_zlevel) < area_zlevel) + stack_trace("[clear]([clear.type])'s turfs_by_zlevel is length [length(clear.turfs_by_zlevel)] but we are being asked to remove turfs from zlevel [area_zlevel] from it.") + clear.turfs_to_uncontain_by_zlevel[area_zlevel] = list() + continue - clear.turfs_to_uncontain = list() + // The operation of cutting large lists can be expensive + // It scales almost directly with the size of the list we're cutting with + // Because of this, we're gonna stick to cutting 1 entry at a time + // There's no reason to batch it I promise, this is faster. No overtime too + var/amount_cut = 0 + var/list/cut_from = clear.turfs_to_uncontain_by_zlevel[area_zlevel] + for(amount_cut in 1 to length(cut_from)) + clear.turfs_by_zlevel[area_zlevel] -= cut_from[amount_cut] + if(MC_TICK_CHECK) + cut_from.Cut(1, amount_cut + 1) + return + + clear.turfs_to_uncontain_by_zlevel = list() marked_for_clearing.len-- + +#undef ALLOWED_LOOSE_TURFS diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 7e6526220de5..8edd143de148 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -890,10 +890,16 @@ SUBSYSTEM_DEF(job) M.forceMove(get_turf(src)) /obj/structure/chair/JoinPlayerHere(mob/M, buckle) + . = ..() // Placing a mob in a chair will attempt to buckle it, or else fall back to default. if (buckle && isliving(M) && buckle_mob(M, FALSE, FALSE)) return - ..() + +/obj/machinery/cryopod/JoinPlayerHere(mob/M, buckle) + . = ..() + open_machine() + if(iscarbon(M)) + apply_effects_to_mob(M) /datum/controller/subsystem/job/proc/SendToLateJoin(mob/M, buckle = TRUE) var/atom/destination @@ -909,65 +915,49 @@ SUBSYSTEM_DEF(job) //bad mojo if(SSmapping.config.cryo_spawn) - var/area/shuttle/arrival/A = GLOB.areas_by_type[/area/crew_quarters/cryopods] - if(A) - var/list/pods = list() - var/list/unoccupied_pods = list() - for(var/obj/machinery/cryopod/pod in A) - pods |= pod - if(!pod.occupant) - unoccupied_pods |= pod - if(length(unoccupied_pods)) //if we have any unoccupied ones - destination = pick(unoccupied_pods) - else if(length(pods)) - destination = pick(pods) //if they're all full somehow?? - else //no pods at all - var/list/available = list() - for(var/turf/T in A) - if(!T.is_blocked_turf(TRUE)) - available += T - if(length(available)) - destination = pick(available) - if(destination) - destination.JoinPlayerHere(M, FALSE) - else - var/msg = "Unable to send mob [M] to late join (CRYOPODS)!" - message_admins(msg) - CRASH(msg) - + destination = get_cryo_spawn_points() else - var/area/shuttle/arrival/A = GLOB.areas_by_type[/area/shuttle/arrival] - if(A) - //first check if we can find a chair - var/obj/structure/chair/C = locate() in A - if(C) - C.JoinPlayerHere(M, buckle) - return + destination = get_last_resort_spawn_points() + + destination.JoinPlayerHere(M, buckle) - //last hurrah - var/list/avail = list() - for(var/turf/T in A) - if(!T.is_blocked_turf(TRUE)) - avail += T - if(avail.len) - destination = pick(avail) - destination.JoinPlayerHere(M, FALSE) - return +/datum/controller/subsystem/job/proc/get_cryo_spawn_points() + var/area/shuttle/arrival/cryo_spawn_area = GLOB.areas_by_type[/area/crew_quarters/cryopods] + if(!isnull(cryo_spawn_area)) + var/list/turf/available_turfs = list() + for (var/list/zlevel_turfs as anything in cryo_spawn_area.get_zlevel_turf_lists()) + for (var/turf/arrivals_turf as anything in zlevel_turfs) + var/obj/machinery/cryopod/spawn_pod = locate() in arrivals_turf + if(!isnull(spawn_pod)) + return spawn_pod + if(arrivals_turf.is_blocked_turf(TRUE)) + continue + available_turfs += arrivals_turf - //pick an open spot on arrivals and dump em - var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival)) - if(arrivals_turfs.len) - for(var/turf/T in arrivals_turfs) - if(!T.is_blocked_turf(TRUE)) - T.JoinPlayerHere(M, FALSE) - return - //last chance, pick ANY spot on arrivals and dump em - destination = arrivals_turfs[1] - destination.JoinPlayerHere(M, FALSE) - else - var/msg = "Unable to send mob [M] to late join!" - message_admins(msg) - CRASH(msg) + if(length(available_turfs)) + return pick(available_turfs) + + stack_trace("Unable to find cryo spawn point.") + return GET_ERROR_ROOM + +/datum/controller/subsystem/job/proc/get_last_resort_spawn_points() + var/area/shuttle/arrival/arrivals_area = GLOB.areas_by_type[/area/shuttle/arrival] + if(!isnull(arrivals_area)) + var/list/turf/available_turfs = list() + for (var/list/zlevel_turfs as anything in arrivals_area.get_zlevel_turf_lists()) + for (var/turf/arrivals_turf as anything in zlevel_turfs) + var/obj/structure/chair/shuttle_chair = locate() in arrivals_turf + if(!isnull(shuttle_chair)) + return shuttle_chair + if(arrivals_turf.is_blocked_turf(TRUE)) + continue + available_turfs += arrivals_turf + + if(length(available_turfs)) + return pick(available_turfs) + + stack_trace("Unable to find last resort spawn point.") + return GET_ERROR_ROOM ///Lands specified mob at a random spot in the hallways /datum/controller/subsystem/job/proc/DropLandAtRandomHallwayPoint(mob/living/living_mob) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 6047a67063e4..bdcf6de548f8 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -231,7 +231,7 @@ SUBSYSTEM_DEF(mapping) // Cache for sonic speed var/list/unused_turfs = src.unused_turfs var/list/world_contents = GLOB.areas_by_type[world.area].contents - var/list/world_turf_contents = GLOB.areas_by_type[world.area].contained_turfs + var/list/world_turf_contents_by_z = GLOB.areas_by_type[world.area].turfs_by_zlevel var/list/lists_to_reserve = src.lists_to_reserve var/index = 0 while(index < length(lists_to_reserve)) @@ -247,10 +247,12 @@ SUBSYSTEM_DEF(mapping) LAZYINITLIST(unused_turfs["[T.z]"]) unused_turfs["[T.z]"] |= T var/area/old_area = T.loc - old_area.turfs_to_uncontain += T + LISTASSERTLEN(old_area.turfs_to_uncontain_by_zlevel, T.z, list()) + old_area.turfs_to_uncontain_by_zlevel[T.z] += T T.turf_flags = UNUSED_RESERVATION_TURF world_contents += T - world_turf_contents += T + LISTASSERTLEN(world_turf_contents_by_z, T.z, list()) + world_turf_contents_by_z[T.z] += T packet.len-- packetlen = length(packet) @@ -874,12 +876,14 @@ GLOBAL_LIST_EMPTY(the_station_areas) // Faster if(space_guaranteed) var/area/global_area = GLOB.areas_by_type[world.area] - global_area.contained_turfs += Z_TURFS(z_level) + LISTASSERTLEN(global_area.turfs_by_zlevel, z_level, list()) + global_area.turfs_by_zlevel[z_level] = Z_TURFS(z_level) return for(var/turf/to_contain as anything in Z_TURFS(z_level)) var/area/our_area = to_contain.loc - our_area.contained_turfs += to_contain + LISTASSERTLEN(our_area.turfs_by_zlevel, z_level, list()) + our_area.turfs_by_zlevel[z_level] += to_contain /datum/controller/subsystem/mapping/proc/update_plane_tracking(datum/space_level/update_with) // We're essentially going to walk down the stack of connected z levels, and set their plane offset as we go diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 9395509e69f9..0152b6e9494d 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -616,13 +616,16 @@ SUBSYSTEM_DEF(shuttle) if(!midpoint) qdel(proposal) return FALSE + var/area/old_area = midpoint.loc - old_area.turfs_to_uncontain += proposal.reserved_turfs + LISTASSERTLEN(old_area.turfs_to_uncontain_by_zlevel, bottomleft.z, list()) + old_area.turfs_to_uncontain_by_zlevel[bottomleft.z] += proposal.reserved_turfs var/area/shuttle/transit/new_area = new() new_area.parallax_movedir = travel_dir new_area.contents = proposal.reserved_turfs - new_area.contained_turfs = proposal.reserved_turfs + LISTASSERTLEN(new_area.turfs_by_zlevel, bottomleft.z, list()) + new_area.turfs_by_zlevel[bottomleft.z] = proposal.reserved_turfs var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint) new_transit_dock.reserved_area = proposal diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 21c5ea46e9fd..0c0de1afd49b 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -91,27 +91,27 @@ STI KALY - blind if(!theareas||!theareas.len) return - var/area/thearea = pick(theareas) + var/area/last_chosen_area_name = pick(theareas) var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - if(T.z != affected_mob.z) + for(var/turf/possible_destination as anything in get_area_turfs(GLOB.teleportlocs[last_chosen_area_name])) + if(possible_destination.z != affected_mob.z) continue - if(T.name == "space") + if(isspaceturf(possible_destination)) continue - if(!T.density) + if(!possible_destination.density) var/clear = 1 - for(var/obj/O in T) + for(var/obj/O in possible_destination) if(O.density) clear = 0 break if(clear) - L+=T + L += possible_destination if(!L) return - affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!", forced = "wizarditis teleport") + affected_mob.say("SCYAR NILA [uppertext(last_chosen_area_name.name)]!", forced = "wizarditis teleport") affected_mob.forceMove(pick(L)) return diff --git a/code/datums/mapgen/dungeon_generators/dungeon_room.dm b/code/datums/mapgen/dungeon_generators/dungeon_room.dm index e80c000a1942..144188f9f844 100644 --- a/code/datums/mapgen/dungeon_generators/dungeon_room.dm +++ b/code/datums/mapgen/dungeon_generators/dungeon_room.dm @@ -193,11 +193,8 @@ for(var/turf/room_turf in (interior + exterior)) var/area/old_area = get_area(room_turf) if(area_ref != old_area && !generator_ref.areas_included.Find(old_area)) - area_ref.contents += room_turf - area_ref.contained_turfs += room_turf - old_area.turfs_to_uncontain += room_turf room_turf.change_area(old_area, area_ref) - + return TRUE ///For each tile in the exterior, build a wall to keep the assistants out. Or a window if the room theme calls for it diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 92cb1053db07..b41a91e0ea0b 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -13,14 +13,16 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT invisibility = INVISIBILITY_LIGHTING - /// List of all turfs currently inside this area. Acts as a filtered bersion of area.contents - /// For faster lookup (area.contents is actually a filtered loop over world) + /// List of all turfs currently inside this area as nested lists indexed by zlevel. + /// Acts as a filtered version of area.contents For faster lookup + /// (area.contents is actually a filtered loop over world) /// Semi fragile, but it prevents stupid so I think it's worth it - var/list/turf/contained_turfs = list() - /// Contained turfs is a MASSIVE list, so rather then adding/removing from it each time we have a problem turf + var/list/list/turf/turfs_by_zlevel = list() + /// turfs_by_z_level can hold MASSIVE lists, so rather then adding/removing from it each time we have a problem turf /// We should instead store a list of turfs to REMOVE from it, then hook into a getter for it /// There is a risk of this and contained_turfs leaking, so a subsystem will run it down to 0 incrementally if it gets too large - var/list/turf/turfs_to_uncontain = list() + /// This uses the same nested list format as turfs_by_zlevel + var/list/list/turf/turfs_to_uncontain_by_zlevel = list() var/area_flags = NONE @@ -146,14 +148,14 @@ GLOBAL_LIST_EMPTY(teleportlocs) /** - * Generate a list of turfs you can teleport to from the areas list - * - * Includes areas if they're not a shuttle or not not teleport or have no contents - * - * The chosen turf is the first item in the areas contents that is a station level - * - * The returned list of turfs is sorted by name - */ + * Generate a list of turfs you can teleport to from the areas list + * + * Includes areas if they're not a shuttle or not not teleport or have no contents + * + * The chosen turf is the first item in the areas contents that is a station level + * + * The returned list of turfs is sorted by name + */ /proc/process_teleport_locs() for(var/area/AR as anything in get_sorted_areas()) if(istype(AR, /area/shuttle) || AR.noteleport) @@ -249,34 +251,100 @@ GLOBAL_LIST_EMPTY(teleportlocs) turfs += T map_generator.generate_terrain(turfs, src) -/area/proc/get_contained_turfs() - if(length(turfs_to_uncontain)) +/// Returns the highest zlevel that this area contains turfs for +/area/proc/get_highest_zlevel() + for (var/area_zlevel in length(turfs_by_zlevel) to 1 step -1) + if (length(turfs_to_uncontain_by_zlevel) >= area_zlevel) + if (length(turfs_by_zlevel[area_zlevel]) - length(turfs_to_uncontain_by_zlevel[area_zlevel]) > 0) + return area_zlevel + else + if (length(turfs_by_zlevel[area_zlevel])) + return area_zlevel + return 0 + +/// Returns a nested list of lists with all turfs split by zlevel. +/// only zlevels with turfs are returned. The order of the list is not guaranteed. +/area/proc/get_zlevel_turf_lists() + if(length(turfs_to_uncontain_by_zlevel)) cannonize_contained_turfs() - return contained_turfs + + var/list/zlevel_turf_lists = list() + + for (var/list/zlevel_turfs as anything in turfs_by_zlevel) + if (length(zlevel_turfs)) + zlevel_turf_lists += list(zlevel_turfs) + + return zlevel_turf_lists + +/// Returns a list with all turfs in this zlevel. +/area/proc/get_turfs_by_zlevel(zlevel) + if (length(turfs_to_uncontain_by_zlevel) >= zlevel && length(turfs_to_uncontain_by_zlevel[zlevel])) + cannonize_contained_turfs_by_zlevel(zlevel) + + if (length(turfs_by_zlevel) < zlevel) + return list() + + return turfs_by_zlevel[zlevel] + + +/// Merges a list containing all of the turfs zlevel lists from get_zlevel_turf_lists inside one list. Use get_zlevel_turf_lists() or get_turfs_by_zlevel() unless you need all the turfs in one list to avoid generating large lists +/area/proc/get_turfs_from_all_zlevels() + . = list() + for (var/list/zlevel_turfs as anything in get_zlevel_turf_lists()) + . += zlevel_turfs /// Ensures that the contained_turfs list properly represents the turfs actually inside us -/area/proc/cannonize_contained_turfs() +/area/proc/cannonize_contained_turfs_by_zlevel(zlevel_to_clean, _autoclean = TRUE) // This is massively suboptimal for LARGE removal lists // Try and keep the mass removal as low as you can. We'll do this by ensuring // We only actually add to contained turfs after large changes (Also the management subsystem) // Do your damndest to keep turfs out of /area/space as a stepping stone - // That sucker gets HUGE and will make this take actual tens of seconds if you stuff turfs_to_uncontain - contained_turfs -= turfs_to_uncontain - turfs_to_uncontain = list() + // That sucker gets HUGE and will make this take actual seconds + if (zlevel_to_clean <= length(turfs_by_zlevel) && zlevel_to_clean <= length(turfs_to_uncontain_by_zlevel)) + turfs_by_zlevel[zlevel_to_clean] -= turfs_to_uncontain_by_zlevel[zlevel_to_clean] + + if (!_autoclean) // Removes empty lists from the end of this list + turfs_to_uncontain_by_zlevel[zlevel_to_clean] = list() + return + + var/new_length = length(turfs_to_uncontain_by_zlevel) + // Walk backwards thru the list + for (var/i in length(turfs_to_uncontain_by_zlevel) to 0 step -1) + if (i && length(turfs_to_uncontain_by_zlevel[i])) + break // Stop the moment we find a useful list + new_length = i + + if (new_length < length(turfs_to_uncontain_by_zlevel)) + turfs_to_uncontain_by_zlevel.len = new_length + + if (new_length >= zlevel_to_clean) + turfs_to_uncontain_by_zlevel[zlevel_to_clean] = list() + + +/// Ensures that the contained_turfs list properly represents the turfs actually inside us +/area/proc/cannonize_contained_turfs() + for (var/area_zlevel in 1 to length(turfs_to_uncontain_by_zlevel)) + cannonize_contained_turfs_by_zlevel(area_zlevel, _autoclean = FALSE) + + turfs_to_uncontain_by_zlevel = list() + /// Returns TRUE if we have contained turfs, FALSE otherwise /area/proc/has_contained_turfs() - return length(contained_turfs) - length(turfs_to_uncontain) > 0 + for (var/area_zlevel in 1 to length(turfs_by_zlevel)) + if (length(turfs_to_uncontain_by_zlevel) >= area_zlevel) + if (length(turfs_by_zlevel[area_zlevel]) - length(turfs_to_uncontain_by_zlevel[area_zlevel]) > 0) + return TRUE + else + if (length(turfs_by_zlevel[area_zlevel])) + return TRUE + return FALSE /** - * Register this area as belonging to a z level - * - * Ensures the item is added to the SSmapping.areas_in_z list for this z - * - * It also goes through every item in this areas contents and sets the area level z to it - * breaking the exat first time it does this, this seems crazy but what would I know, maybe - * areas don't have a valid z themself or something - */ + * Register this area as belonging to a z level + * + * Ensures the item is added to the SSmapping.areas_in_z list for this z + */ /area/proc/reg_in_areas_in_z() if(!has_contained_turfs()) return @@ -304,10 +372,23 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/Destroy() if(GLOB.areas_by_type[type] == src) GLOB.areas_by_type[type] = null - GLOB.sortedAreas -= src - GLOB.areas -= src - GLOB.delta_areas -= src + //this is not initialized until get_sorted_areas() is called so we have to do a null check + if(!isnull(GLOB.sortedAreas)) + GLOB.sortedAreas -= src + //just for sanity sake cause why not + if(!isnull(GLOB.areas)) + GLOB.areas -= src + + //YOG + if(!isnull(GLOB.delta_areas)) + GLOB.delta_areas -= src + + //machinery cleanup STOP_PROCESSING(SSobj, src) + //turf cleanup + turfs_by_zlevel = null + turfs_to_uncontain_by_zlevel = null + //parent cleanup return ..() /** @@ -780,8 +861,9 @@ GLOBAL_LIST_EMPTY(teleportlocs) if(outdoors) return FALSE areasize = 0 - for(var/turf/open/T in get_contained_turfs()) - areasize++ + for(var/list/zlevel_turfs as anything in get_zlevel_turf_lists()) + for(var/turf/open/thisvarisunused in zlevel_turfs) + areasize++ /** * Causes a runtime error diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 6f103db25ced..ec4850157003 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -450,12 +450,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers) message_admins("[key_name_admin(target)] entered a stasis pod. (JMP)") add_fingerprint(target) -/obj/machinery/cryopod/JoinPlayerHere(mob/M, buckle) - . = ..() - open_machine() - if(iscarbon(M)) - apply_effects_to_mob(M) - /obj/machinery/cryopod/proc/apply_effects_to_mob(mob/living/carbon/sleepyhead) to_chat(sleepyhead, span_boldnotice("You begin to wake from cryosleep...")) sleepyhead.set_nutrition(200) diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 031b8588c500..2b77fe12829a 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -227,17 +227,22 @@ return TRUE -/proc/set_area_machinery_title(area/A, title, oldtitle) +/proc/set_area_machinery_title(area/area, title, oldtitle) if(!oldtitle) // or replacetext goes to infinite loop return - for(var/obj/machinery/airalarm/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/power/apc/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/atmospherics/components/unary/vent_pump/M in A) - M.name = replacetext(M.name,oldtitle,title) - for(var/obj/machinery/door/M in A) - M.name = replacetext(M.name,oldtitle,title) + + //stuff tied to the area to rename + var/static/list/to_rename = typecacheof(list( + /obj/machinery/airalarm, + /obj/machinery/atmospherics/components/unary/vent_scrubber, + /obj/machinery/atmospherics/components/unary/vent_pump, + /obj/machinery/door, + /obj/machinery/firealarm, + /obj/machinery/light_switch, + /obj/machinery/power/apc, + )) + for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) + for (var/turf/area_turf as anything in zlevel_turfs) + for(var/obj/machine as anything in typecache_filter_list(area_turf.contents, to_rename)) + machine.name = replacetext(machine.name, oldtitle, title) //TODO: much much more. Unnamed airlocks, cameras, etc. diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b0956aab2ad2..a195e07f1a49 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -231,14 +231,17 @@ GLOBAL_LIST_EMPTY(station_turfs) return user.Move_Pulled(src) +/// Call to move a turf from its current area to a new one /turf/proc/change_area(area/old_area, area/new_area) //dont waste our time if(old_area == new_area) return //move the turf - old_area.turfs_to_uncontain += src - new_area.contained_turfs += src + LISTASSERTLEN(old_area.turfs_to_uncontain_by_zlevel, z, list()) + LISTASSERTLEN(new_area.turfs_by_zlevel, z, list()) + old_area.turfs_to_uncontain_by_zlevel[z] += src + new_area.turfs_by_zlevel[z] += src new_area.contents += src //changes to make after turf has moved diff --git a/code/game/world.dm b/code/game/world.dm index 78c4098c7d45..53e3fe22b904 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -365,10 +365,14 @@ GLOBAL_VAR(restart_counter) if(!map_load_z_cutoff) return var/area/global_area = GLOB.areas_by_type[world.area] // We're guaranteed to be touching the global area, so we'll just do this - var/list/to_add = block( - locate(old_max + 1, 1, 1), - locate(maxx, maxy, map_load_z_cutoff)) - global_area.contained_turfs += to_add + LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list()) + for (var/zlevel in 1 to map_load_z_cutoff) + var/list/to_add = block( + locate(old_max + 1, 1, zlevel), + locate(maxx, maxy, zlevel)) + + global_area.turfs_by_zlevel[zlevel] += to_add + /world/proc/increase_max_y(new_maxy, map_load_z_cutoff = maxz) if(new_maxy <= maxy) @@ -378,10 +382,12 @@ GLOBAL_VAR(restart_counter) if(!map_load_z_cutoff) return var/area/global_area = GLOB.areas_by_type[world.area] // We're guarenteed to be touching the global area, so we'll just do this - var/list/to_add = block( - locate(1, old_maxy + 1, 1), - locate(maxx, maxy, map_load_z_cutoff)) - global_area.contained_turfs += to_add + LISTASSERTLEN(global_area.turfs_by_zlevel, map_load_z_cutoff, list()) + for (var/zlevel in 1 to map_load_z_cutoff) + var/list/to_add = block( + locate(1, old_maxy + 1, 1), + locate(maxx, maxy, map_load_z_cutoff)) + global_area.turfs_by_zlevel[zlevel] += to_add /world/proc/incrementMaxZ() maxz++ diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 8125bc2e223c..4fa982dfb1a2 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -10,10 +10,10 @@ return var/list/turfs = list() - for(var/turf/T in A) - if(T.density) - continue - turfs.Add(T) + for (var/list/zlevel_turfs as anything in A.get_zlevel_turf_lists()) + for (var/turf/area_turf as anything in zlevel_turfs) + if(!area_turf.density) + turfs.Add(area_turf) var/turf/T = pick(turfs) if(!T) diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm index 21851ec5ea5f..bb618425314c 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm @@ -521,7 +521,7 @@ var/area/current_area = get_area(src) if(current_area == bloodsuckerdatum.bloodsucker_lair_area) return - bloodsuckerdatum.bloodsucker_lair_area.contained_turfs += current_area.contained_turfs + bloodsuckerdatum.bloodsucker_lair_area.turfs_by_zlevel[z] += current_area.turfs_by_zlevel[z] /obj/structure/bloodsucker/bloodstatue/command/unbolt() . = ..() @@ -529,7 +529,7 @@ var/area/current_area = get_area(src) if(current_area == bloodsuckerdatum.bloodsucker_lair_area) return - bloodsuckerdatum.bloodsucker_lair_area.turfs_to_uncontain += current_area.contained_turfs + bloodsuckerdatum.bloodsucker_lair_area.turfs_to_uncontain_by_zlevel[z] += current_area.turfs_by_zlevel[z] /obj/structure/bloodsucker/bloodstatue/greytide name = "greytider bust" diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 391945664105..b86c8b2a352e 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -180,7 +180,7 @@ if (!landingzone) WARNING("[src] couldnt find a Quartermaster/Storage (aka cargobay) area on the station, and as such it has set the supplypod landingzone to the area it resides in.") landingzone = get_area(src) - for(var/turf/open/floor/T in landingzone.get_contained_turfs())//uses default landing zone + for(var/turf/open/floor/T in landingzone.get_turfs_from_all_zlevels())//uses default landing zone if(T.is_blocked_turf()) continue LAZYADD(empty_turfs, T) @@ -197,7 +197,7 @@ else if(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^) landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone - for(var/turf/open/floor/T in landingzone.get_contained_turfs()) + for(var/turf/open/floor/T in landingzone.get_turfs_from_all_zlevels()) if(T.is_blocked_turf()) continue LAZYADD(empty_turfs, T) diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 07d7a05eda3c..a70de70337e9 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -108,7 +108,7 @@ return var/list/shuttle_areas = port.shuttle_areas for(var/area/region as anything in shuttle_areas) - for(var/turf/place as anything in region.get_contained_turfs()) + for(var/turf/place as anything in region.get_turfs_from_all_zlevels()) if(get_dist(user, place) > 7) continue var/image/pic diff --git a/code/modules/events/aurora_caelus.dm b/code/modules/events/aurora_caelus.dm index b6e4c3ccba8f..bac40545f858 100644 --- a/code/modules/events/aurora_caelus.dm +++ b/code/modules/events/aurora_caelus.dm @@ -51,7 +51,7 @@ set_starlight(aurora_color) for(var/area/crew_quarters/kitchen/affected_area in GLOB.areas) - for(var/turf/open/kitchen_floor in affected_area.get_contained_turfs()) + for(var/turf/open/kitchen_floor in affected_area.get_turfs_from_all_zlevels()) kitchen_floor.set_light(l_color = aurora_color) /datum/round_event/aurora_caelus/end() @@ -107,9 +107,9 @@ var/walked_range = LERP(start_range, end_range, i/5) var/walked_power = LERP(start_power, end_power, i/5) for(var/area/crew_quarters/kitchen/affected_area in GLOB.areas) - for(var/turf/open/kitchen_floor in affected_area.get_contained_turfs()) + for(var/turf/open/kitchen_floor in affected_area.get_turfs_from_all_zlevels()) kitchen_floor.set_light(walked_range, walked_power, walked_color) sleep(8 SECONDS) for(var/area/crew_quarters/kitchen/affected_area in GLOB.areas) - for(var/turf/open/kitchen_floor in affected_area.get_contained_turfs()) + for(var/turf/open/kitchen_floor in affected_area.get_turfs_from_all_zlevels()) kitchen_floor.set_light(end_range, end_power, end_color) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 9cce3d6b51fd..058539a89aa1 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -14,7 +14,7 @@ var/obj/structure/spacevine/SV = new() for(var/area/maintenance/A in GLOB.areas) - for(var/turf/F as anything in A.get_contained_turfs()) + for(var/turf/F in A.get_turfs_from_all_zlevels()) if(F.Enter(SV)) turfs += F diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm index c6f427f592f6..ea31f61c8bec 100644 --- a/code/modules/lighting/lighting_area.dm +++ b/code/modules/lighting/lighting_area.dm @@ -51,9 +51,10 @@ UnregisterSignal(SSdcs, COMSIG_STARLIGHT_COLOR_CHANGED) var/list/z_offsets = SSmapping.z_level_to_plane_offset if(length(lighting_effects) > 1) - for(var/turf/T as anything in get_contained_turfs()) - if(z_offsets[T.z]) - T.cut_overlay(lighting_effects[z_offsets[T.z] + 1]) + for(var/area_zlevel in 1 to get_highest_zlevel()) + if(z_offsets[area_zlevel]) + for(var/turf/T as anything in get_turfs_by_zlevel(area_zlevel)) + T.cut_overlay(lighting_effects[z_offsets[T.z] + 1]) cut_overlay(lighting_effects[1]) lighting_effects = null area_has_base_lighting = FALSE @@ -91,17 +92,18 @@ add_overlay(lighting_effects[1]) var/list/z_offsets = SSmapping.z_level_to_plane_offset - if(length(lighting_effects) > 1) - // This inside loop is EXTREMELY hot because it's run by space tiles. Don't want no part in that - for(var/turf/T as anything in get_contained_turfs()) - T.luminosity = 1 - // We will only add overlays to turfs not on the first z layer, because that's a significantly lesser portion - // And we need to do them separate, or lighting will go fuckey - if(z_offsets[T.z]) - T.add_overlay(lighting_effects[z_offsets[T.z] + 1]) - else - for(var/turf/T as anything in get_contained_turfs()) - T.luminosity = 1 + for (var/area_zlevel in 1 to get_highest_zlevel()) + // We will only add overlays to turfs not on the first z layer, because that's a significantly lesser portion + // And we need to do them separate, or lighting will go fuckey + // This inside loop is EXTREMELY hot because it's run by space tiles, so we do the if check once on the outside + if(length(lighting_effects) > 1 && z_offsets[area_zlevel]) + var/lighting_effect_to_add = lighting_effects[z_offsets[area_zlevel] + 1] + for(var/turf/area_turf as anything in get_turfs_by_zlevel(area_zlevel)) + area_turf.luminosity = 1 + area_turf.add_overlay(lighting_effect_to_add) + else + for(var/turf/area_turf as anything in get_turfs_by_zlevel(area_zlevel)) + area_turf.luminosity = 1 area_has_base_lighting = TRUE diff --git a/code/modules/lighting/lighting_setup.dm b/code/modules/lighting/lighting_setup.dm index d6bf19711ef7..c148530d1cd8 100644 --- a/code/modules/lighting/lighting_setup.dm +++ b/code/modules/lighting/lighting_setup.dm @@ -1,12 +1,12 @@ /proc/create_all_lighting_objects() - for(var/area/A as anything in GLOB.areas) - if(!A.static_lighting) + for(var/area/area as anything in GLOB.areas) + if(!area.static_lighting) continue - - for(var/turf/T as anything in A.get_contained_turfs()) - if(T.space_lit) - continue - new /datum/lighting_object(T) + for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) + for(var/turf/area_turf as anything in zlevel_turfs) + if(area_turf.space_lit) + continue + new /datum/lighting_object(area_turf) CHECK_TICK CHECK_TICK diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index 5a5bbc8a23e1..cf3d2c8e56a8 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -931,8 +931,10 @@ GLOBAL_LIST_EMPTY(map_model_default) if(!new_z) old_area = crds.loc - old_area.turfs_to_uncontain += crds - area_instance.contained_turfs.Add(crds) + LISTASSERTLEN(old_area.turfs_to_uncontain_by_zlevel, crds.z, list()) + LISTASSERTLEN(area_instance.turfs_by_zlevel, crds.z, list()) + old_area.turfs_to_uncontain_by_zlevel[crds.z] += crds + area_instance.turfs_by_zlevel[crds.z] += crds area_instance.contents.Add(crds) if(GLOB.use_preloader) diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm index 74185cebb4ba..65ffd8ee2ac1 100644 --- a/code/modules/mapping/space_management/space_reservation.dm +++ b/code/modules/mapping/space_management/space_reservation.dm @@ -81,13 +81,13 @@ for(var/turf/cordon_turf as anything in cordon_turfs) var/area/misc/cordon/cordon_area = GLOB.areas_by_type[/area/misc/cordon] || new var/area/old_area = cordon_turf.loc - - //LISTASSERTLEN(old_area.turfs_to_uncontain, cordon_turf.z, list()) - //LISTASSERTLEN(cordon_area.contained_turfs, cordon_turf.z, list()) - old_area.turfs_to_uncontain += cordon_turf - cordon_area.contained_turfs += cordon_turf + + LISTASSERTLEN(old_area.turfs_to_uncontain_by_zlevel, cordon_turf.z, list()) + LISTASSERTLEN(cordon_area.turfs_by_zlevel, cordon_turf.z, list()) + old_area.turfs_to_uncontain_by_zlevel[cordon_turf.z] += cordon_turf + cordon_area.turfs_by_zlevel[cordon_turf.z] += cordon_turf cordon_area.contents += cordon_turf - + // Its no longer unused, but its also not "used" cordon_turf.turf_flags &= ~UNUSED_RESERVATION_TURF cordon_turf.ChangeTurf(/turf/cordon, /turf/cordon) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3f8e9b2dea74..58114311b8e0 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -1075,9 +1075,10 @@ /obj/item/areaeditor/blueprints/slime/edit_area() ..() - var/area/A = get_area(src) - for(var/turf/T in A) - T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - T.add_atom_colour("#2956B2", FIXED_COLOUR_PRIORITY) - A.xenobiology_compatible = TRUE + var/area/area = get_area(src) + for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) + for(var/turf/area_turf as anything in zlevel_turfs) + area_turf.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) + area_turf.add_atom_colour("#2956B2", FIXED_COLOUR_PRIORITY) + area.xenobiology_compatible = TRUE qdel(src) diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 068add880c5e..9fee34683a26 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -133,21 +133,23 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) GLOBAL_VAR_INIT(emergency_access, FALSE) /proc/make_maint_all_access() - for(var/area/maintenance/A in GLOB.areas) - for(var/turf/in_area as anything in A.get_contained_turfs()) - for(var/obj/machinery/door/airlock/D in in_area) - D.emergency = TRUE - D.update_icon(state=ALL, override=0) + for(var/area/maintenance/area in GLOB.areas) + for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) + for(var/turf/area_turf as anything in zlevel_turfs) + for(var/obj/machinery/door/airlock/airlock in area_turf) + airlock.emergency = TRUE + airlock.update_icon(ALL, 0) minor_announce("Access restrictions on maintenance and external airlocks have been lifted.", "Attention! Station-wide emergency declared!",1) GLOB.emergency_access = TRUE SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "enabled")) /proc/revoke_maint_all_access() - for(var/area/maintenance/A in GLOB.areas) - for(var/turf/in_area as anything in A.get_contained_turfs()) - for(var/obj/machinery/door/airlock/D in in_area) - D.emergency = FALSE - D.update_icon(state=ALL, override=0) + for(var/area/maintenance/area in GLOB.areas) + for (var/list/zlevel_turfs as anything in area.get_zlevel_turf_lists()) + for(var/turf/area_turf as anything in zlevel_turfs) + for(var/obj/machinery/door/airlock/airlock in area_turf) + airlock.emergency = FALSE + airlock.update_icon(ALL, 0) minor_announce("Access restrictions in maintenance areas have been restored.", "Attention! Station-wide emergency rescinded:") GLOB.emergency_access = FALSE SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("emergency maintenance access", "disabled")) diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm index 23559483ed53..f2af05af02e0 100644 --- a/code/modules/shuttle/custom_shuttle.dm +++ b/code/modules/shuttle/custom_shuttle.dm @@ -127,10 +127,10 @@ calculated_non_operational_thrusters = 0 //Calculate all the data var/list/areas = M.shuttle_areas - for(var/shuttleArea in areas) - for(var/turf/T in shuttleArea) + for(var/area/shuttle_area in areas) + for(var/turf/T in shuttle_area.get_turfs_by_zlevel(z)) calculated_mass += 1 - for(var/obj/machinery/shuttle/engine/E in shuttleArea) + for(var/obj/machinery/shuttle/engine/E in shuttle_area) E.check_setup() if(!E.thruster_active) //Skipover thrusters with no valid heater calculated_non_operational_thrusters ++ diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 5d874f097e4f..641c146845be 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -96,17 +96,18 @@ the_eye.setDir(shuttle_port.dir) var/turf/origin = locate(shuttle_port.x + x_offset, shuttle_port.y + y_offset, shuttle_port.z) for(var/area/shuttle_area as anything in shuttle_port.shuttle_areas) - for(var/turf/shuttle_turf as anything in shuttle_area.get_contained_turfs()) - if(shuttle_turf.z != origin.z) - continue - var/image/I = image('icons/effects/alphacolors.dmi', origin, "red") - var/x_off = shuttle_turf.x - origin.x - var/y_off = shuttle_turf.y - origin.y - I.loc = locate(origin.x + x_off, origin.y + y_off, origin.z) //we have to set this after creating the image because it might be null, and images created in nullspace are immutable. - I.layer = ABOVE_NORMAL_TURF_LAYER - SET_PLANE(I, ABOVE_GAME_PLANE, shuttle_turf) - I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - the_eye.placement_images[I] = list(x_off, y_off) + for (var/list/zlevel_turfs as anything in shuttle_area.get_zlevel_turf_lists()) + for(var/turf/shuttle_turf as anything in zlevel_turfs) + if(shuttle_turf.z != origin.z) + continue + var/image/I = image('icons/effects/alphacolors.dmi', origin, "red") + var/x_off = shuttle_turf.x - origin.x + var/y_off = shuttle_turf.y - origin.y + I.loc = locate(origin.x + x_off, origin.y + y_off, origin.z) //we have to set this after creating the image because it might be null, and images created in nullspace are immutable. + I.layer = ABOVE_NORMAL_TURF_LAYER + SET_PLANE(I, ABOVE_GAME_PLANE, shuttle_turf) + I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + the_eye.placement_images[I] = list(x_off, y_off) /obj/machinery/computer/camera_advanced/shuttle_docker/give_eye_control(mob/user) ..() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 3449b6f3b6df..e6feab8ec934 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -513,13 +513,14 @@ var/min_y = -1 var/max_x = WORLDMAXX_CUTOFF var/max_y = WORLDMAXY_CUTOFF - for(var/area/area as anything in shuttle_areas) - for(var/turf/turf as anything in area.get_contained_turfs()) - min_x = max(turf.x, min_x) - max_x = min(turf.x, max_x) - min_y = max(turf.y, min_y) - max_y = min(turf.y, max_y) - CHECK_TICK + for(var/area/shuttle_area as anything in shuttle_areas) + for (var/list/zlevel_turfs as anything in shuttle_area.get_zlevel_turf_lists()) + for(var/turf/turf as anything in zlevel_turfs) + min_x = max(turf.x, min_x) + max_x = min(turf.x, max_x) + min_y = max(turf.y, min_y) + max_y = min(turf.y, max_y) + CHECK_TICK if(min_x == -1 || max_x == WORLDMAXX_CUTOFF) CRASH("Failed to locate shuttle boundaries when iterating through shuttle areas, somehow.") diff --git a/yogstation/code/datums/mapgen/JungleGen.dm b/yogstation/code/datums/mapgen/JungleGen.dm index f00e852bf255..fa81ea8d09b6 100644 --- a/yogstation/code/datums/mapgen/JungleGen.dm +++ b/yogstation/code/datums/mapgen/JungleGen.dm @@ -248,17 +248,13 @@ var/datum/biome/jungleland/selected_biome = possible_biomes[toxic_pick][humid_pick] selected_biome = SSmapping.biomes[selected_biome] //Get the instance of this biome from SSmapping - var/turf/GT = selected_biome.generate_turf(gen_turf,density_strings) - if(istype(GT,/turf/open/floor/plating/dirt/jungleland)) - var/turf/open/floor/plating/dirt/jungleland/J = GT + var/turf/generated_terrain = selected_biome.generate_turf(gen_turf,density_strings) + if(istype(generated_terrain,/turf/open/floor/plating/dirt/jungleland)) + var/turf/open/floor/plating/dirt/jungleland/J = generated_terrain J.ore_present = ore_map[world.maxx * (gen_turf.y - 1) + gen_turf.x] var/area/jungleland/jungle_area = selected_biome.this_area - var/area/old_area = GT.loc - old_area.contents -= GT - old_area.contained_turfs -= GT - jungle_area.contents += GT - jungle_area.contained_turfs += GT - GT.change_area(old_area,jungle_area) + var/area/old_area = generated_terrain.loc + generated_terrain.change_area(old_area, jungle_area) CHECK_TICK for(var/biome in subtypesof(/datum/biome/jungleland)) diff --git a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm index be5e3d95852c..ea1b8a3b9d89 100644 --- a/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm +++ b/yogstation/code/game/gamemodes/battle_royale/battleroyale.dm @@ -271,7 +271,7 @@ GLOBAL_VAR(final_zone) continue //also, ideally keeps people out of maints, and in larger open areas that are more interesting if(is_type_in_list(lootlake, weathered)) continue //if the area is covered with a storm, don't spawn loot (less lag) - var/number = LAZYLEN(lootlake.get_contained_turfs())//so bigger areas spawn more crates + var/number = LAZYLEN(lootlake.get_zlevel_turf_lists())//so bigger areas spawn more crates var/amount = round(number / ROOMSIZESCALING) + prob(((number % ROOMSIZESCALING)/ROOMSIZESCALING)*100) //any remaining tiles gives a probability to have an extra crate for(var/I = 0, I < amount, I++) var/turf/turfy = pick(get_area_turfs(lootlake))