that should be all of them. i hope this doesn't break custom shuttles again (#21902)

This commit is contained in:
Chubbygummibear
2024-04-24 17:15:43 -07:00
committed by GitHub
parent e0baf0ccef
commit 02aa084b1e
30 changed files with 361 additions and 252 deletions

View File

@@ -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
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

View File

@@ -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)

View File

@@ -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)
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)]
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
// 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
var/list/cut_from = clear.turfs_to_uncontain_by_zlevel[area_zlevel]
for(amount_cut in 1 to length(cut_from))
clear.contained_turfs -= cut_from[amount_cut]
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 = list()
clear.turfs_to_uncontain_by_zlevel = list()
marked_for_clearing.len--
#undef ALLOWED_LOOSE_TURFS

View File

@@ -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)
destination = get_cryo_spawn_points()
else
var/msg = "Unable to send mob [M] to late join (CRYOPODS)!"
message_admins(msg)
CRASH(msg)
destination = get_last_resort_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.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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -193,9 +193,6 @@
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

View File

@@ -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
@@ -249,33 +251,99 @@ 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
*/
/area/proc/reg_in_areas_in_z()
if(!has_contained_turfs())
@@ -304,10 +372,23 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/Destroy()
if(GLOB.areas_by_type[type] == src)
GLOB.areas_by_type[type] = null
//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,7 +861,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if(outdoors)
return FALSE
areasize = 0
for(var/turf/open/T in get_contained_turfs())
for(var/list/zlevel_turfs as anything in get_zlevel_turf_lists())
for(var/turf/open/thisvarisunused in zlevel_turfs)
areasize++
/**

View File

@@ -450,12 +450,6 @@ GLOBAL_LIST_EMPTY(cryopod_computers)
message_admins("[key_name_admin(target)] entered a stasis pod. (<A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
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)

View File

@@ -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.

View File

@@ -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

View File

@@ -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
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, 1),
locate(maxx, maxy, map_load_z_cutoff))
global_area.contained_turfs += to_add
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
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.contained_turfs += to_add
global_area.turfs_by_zlevel[zlevel] += to_add
/world/proc/incrementMaxZ()
maxz++

View File

@@ -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)

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -51,8 +51,9 @@
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])
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
@@ -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
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
if(z_offsets[T.z])
T.add_overlay(lighting_effects[z_offsets[T.z] + 1])
// 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/T as anything in get_contained_turfs())
T.luminosity = 1
for(var/turf/area_turf as anything in get_turfs_by_zlevel(area_zlevel))
area_turf.luminosity = 1
area_has_base_lighting = TRUE

View File

@@ -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)
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(T)
new /datum/lighting_object(area_turf)
CHECK_TICK
CHECK_TICK

View File

@@ -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)

View File

@@ -82,10 +82,10 @@
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"

View File

@@ -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)

View File

@@ -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"))

View File

@@ -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 ++

View File

@@ -96,7 +96,8 @@
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())
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")

View File

@@ -513,8 +513,9 @@
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())
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)

View File

@@ -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))

View File

@@ -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))