mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
[MIRROR] Builds logic that manages turfs contained inside an area [MDB IGNORE] (#17379)
* Builds logic that manages turfs contained inside an area * Mirror Conflict * Modular! Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: Funce <funce.973@gmail.com> Co-authored-by: tastyfish <crazychris32@gmail.com>
This commit is contained in:
co-authored by
LemonInTheDark
Funce
tastyfish
parent
bd4e73411d
commit
24eb8217c0
@@ -22,6 +22,9 @@
|
||||
///Returns all turfs in a zlevel
|
||||
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
|
||||
|
||||
///Returns all currently loaded turfs
|
||||
#define ALL_TURFS(...) block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
|
||||
|
||||
#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3]))
|
||||
|
||||
/// The pipes, disposals, and wires are hidden
|
||||
|
||||
+28
-22
@@ -123,7 +123,9 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/station/en
|
||||
for(var/i in 1 to length(turfs))
|
||||
var/turf/thing = turfs[i]
|
||||
var/area/old_area = thing.loc
|
||||
old_area.turfs_to_uncontain += thing
|
||||
newA.contents += thing
|
||||
newA.contained_turfs += thing
|
||||
thing.transfer_area_lighting(old_area, newA)
|
||||
|
||||
newA.reg_in_areas_in_z()
|
||||
@@ -143,18 +145,14 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/station/en
|
||||
|
||||
#undef BP_MAX_ROOM_SIZE
|
||||
|
||||
//Repopulates sortedAreas list
|
||||
/proc/repopulate_sorted_areas()
|
||||
GLOB.sortedAreas = list()
|
||||
/proc/require_area_resort()
|
||||
GLOB.sortedAreas = null
|
||||
|
||||
for(var/area/A in world)
|
||||
GLOB.sortedAreas.Add(A)
|
||||
|
||||
sortTim(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))
|
||||
|
||||
/area/proc/addSorted()
|
||||
GLOB.sortedAreas.Add(src)
|
||||
sortTim(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))
|
||||
/// Returns a sorted version of GLOB.areas, by name
|
||||
/proc/get_sorted_areas()
|
||||
if(!GLOB.sortedAreas)
|
||||
GLOB.sortedAreas = sortTim(GLOB.areas.Copy(), /proc/cmp_name_asc)
|
||||
return GLOB.sortedAreas
|
||||
|
||||
//Takes: Area type as a text string from a variable.
|
||||
//Returns: Instance for the area in the world.
|
||||
@@ -177,11 +175,11 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/station/en
|
||||
var/list/areas = list()
|
||||
if(subtypes)
|
||||
var/list/cache = typecacheof(areatype)
|
||||
for(var/area/area_to_check as anything in GLOB.sortedAreas)
|
||||
for(var/area/area_to_check as anything in GLOB.areas)
|
||||
if(cache[area_to_check.type])
|
||||
areas += area_to_check
|
||||
else
|
||||
for(var/area/area_to_check as anything in GLOB.sortedAreas)
|
||||
for(var/area/area_to_check as anything in GLOB.areas)
|
||||
if(area_to_check.type == areatype)
|
||||
areas += area_to_check
|
||||
return areas
|
||||
@@ -204,25 +202,33 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/station/en
|
||||
areatype = areatemp.type
|
||||
else if(!ispath(areatype))
|
||||
return null
|
||||
|
||||
var/list/turfs = list()
|
||||
// Pull out the areas
|
||||
var/list/areas_to_pull = list()
|
||||
if(subtypes)
|
||||
var/list/cache = typecacheof(areatype)
|
||||
for(var/area/area_to_check as anything in GLOB.sortedAreas)
|
||||
for(var/area/area_to_check as anything in GLOB.areas)
|
||||
if(!cache[area_to_check.type])
|
||||
continue
|
||||
for(var/turf/turf_in_area in area_to_check)
|
||||
if(target_z == 0 || target_z == turf_in_area.z)
|
||||
turfs += turf_in_area
|
||||
areas_to_pull += area_to_check
|
||||
else
|
||||
for(var/area/area_to_check as anything in GLOB.sortedAreas)
|
||||
for(var/area/area_to_check as anything in GLOB.areas)
|
||||
if(area_to_check.type != areatype)
|
||||
continue
|
||||
for(var/turf/turf_in_area in area_to_check)
|
||||
if(target_z == 0 || target_z == turf_in_area.z)
|
||||
areas_to_pull += area_to_check
|
||||
|
||||
// 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
|
||||
else
|
||||
for(var/turf/turf_in_area as anything in our_turfs)
|
||||
if(target_z == turf_in_area.z)
|
||||
turfs += turf_in_area
|
||||
return turfs
|
||||
|
||||
|
||||
///Takes: list of area types
|
||||
///Returns: all mobs that are in an area type
|
||||
/proc/mobs_in_area_type(list/area/checked_areas)
|
||||
|
||||
@@ -119,10 +119,14 @@ GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
|
||||
GLOBAL_LIST_EMPTY(ruin_landmarks)
|
||||
GLOBAL_LIST_EMPTY(bar_areas)
|
||||
|
||||
//away missions
|
||||
/// Away missions
|
||||
GLOBAL_LIST_EMPTY(vr_spawnpoints)
|
||||
|
||||
//used by jump-to-area etc. Updated by area/updateName()
|
||||
/// Just a list of all the area objects in the game
|
||||
/// Note, areas can have duplicate types
|
||||
GLOBAL_LIST_EMPTY(areas)
|
||||
/// Used by jump-to-area etc. Updated by area/updateName()
|
||||
/// If this is null, it needs to be recalculated. Use get_sorted_areas() as a getter please
|
||||
GLOBAL_LIST_EMPTY(sortedAreas)
|
||||
/// An association from typepath to area instance. Only includes areas with `unique` set.
|
||||
GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
|
||||
|
||||
@@ -523,7 +523,6 @@ SUBSYSTEM_DEF(air)
|
||||
queued_for_activation.Cut()
|
||||
|
||||
/datum/controller/subsystem/air/proc/setup_allturfs()
|
||||
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
|
||||
var/list/active_turfs = src.active_turfs
|
||||
times_fired++
|
||||
|
||||
@@ -537,7 +536,7 @@ SUBSYSTEM_DEF(air)
|
||||
active_turfs.Cut()
|
||||
var/time = 0
|
||||
|
||||
for(var/turf/T as anything in turfs_to_init)
|
||||
for(var/turf/T as anything in ALL_TURFS())
|
||||
if (!T.init_air)
|
||||
continue
|
||||
// We pass the tick as the current step so if we sleep the step changes
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#define ALLOWED_LOOSE_TURFS 500
|
||||
/**
|
||||
* 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
|
||||
* as a consequence of repeated changes in area in a space
|
||||
* They additionally may not always resolve often enough to avoid memory leaks
|
||||
* This is annoying, so lets keep an eye on them and cut them down to size if needed
|
||||
*/
|
||||
SUBSYSTEM_DEF(area_contents)
|
||||
name = "Area Contents"
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
var/list/area/marked_for_clearing = list()
|
||||
|
||||
/datum/controller/subsystem/area_contents/stat_entry(msg)
|
||||
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)
|
||||
msg = "A:[length(currentrun)] MR:[length(marked_for_clearing)] TC:[total_to_clear] CF:[total_clearing_from]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/area_contents/fire(resumed)
|
||||
if(!resumed)
|
||||
currentrun = GLOB.areas.Copy()
|
||||
|
||||
while(length(currentrun))
|
||||
var/area/test = currentrun[length(currentrun)]
|
||||
if(length(test.turfs_to_uncontain) > ALLOWED_LOOSE_TURFS)
|
||||
marked_for_clearing |= test
|
||||
currentrun.len--
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
// Alright, if we've done a scan on all our areas, it's time to knock the existing ones down to size
|
||||
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
|
||||
|
||||
clear.turfs_to_uncontain = list()
|
||||
marked_for_clearing.len--
|
||||
@@ -115,7 +115,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
initialize_biomes()
|
||||
loadWorld()
|
||||
determine_fake_sale()
|
||||
repopulate_sorted_areas()
|
||||
require_area_resort()
|
||||
process_teleport_locs() //Sets up the wizard teleport locations
|
||||
preloadTemplates()
|
||||
|
||||
@@ -142,7 +142,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
run_map_generation()
|
||||
// Add the transit level
|
||||
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
|
||||
repopulate_sorted_areas()
|
||||
require_area_resort()
|
||||
// Set up Z-level transitions.
|
||||
setup_map_transitions()
|
||||
generate_station_area_list()
|
||||
@@ -155,6 +155,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/lists_to_reserve = src.lists_to_reserve
|
||||
var/index = 0
|
||||
while(index < length(lists_to_reserve))
|
||||
@@ -168,8 +169,11 @@ SUBSYSTEM_DEF(mapping)
|
||||
T.empty(RESERVED_TURF_TYPE, RESERVED_TURF_TYPE, null, TRUE)
|
||||
LAZYINITLIST(unused_turfs["[T.z]"])
|
||||
unused_turfs["[T.z]"] |= T
|
||||
var/area/old_area = T.loc
|
||||
old_area.turfs_to_uncontain += T
|
||||
T.flags_1 |= UNUSED_RESERVATION_TURF
|
||||
world_contents += T
|
||||
world_turf_contents += T
|
||||
packet.len--
|
||||
packetlen = length(packet)
|
||||
|
||||
@@ -362,7 +366,7 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
var/start_z = world.maxz + 1
|
||||
var/i = 0
|
||||
for (var/level in traits)
|
||||
add_new_zlevel("[name][i ? " [i + 1]" : ""]", level)
|
||||
add_new_zlevel("[name][i ? " [i + 1]" : ""]", level, contain_turfs = FALSE)
|
||||
++i
|
||||
|
||||
SSautomapper.preload_templates_from_toml(files) // SKYRAT EDIT ADDITION - We need to load our templates AFTER the Z level exists, otherwise, there is no z level to preload.
|
||||
@@ -372,7 +376,7 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
for (var/P in parsed_maps)
|
||||
var/datum/parsed_map/pm = P
|
||||
pm.turf_blacklist = turf_blacklist // SKYRAT EDIT ADDITION - apply blacklist
|
||||
if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE))
|
||||
if (!pm.load(1, 1, start_z + parsed_maps[P], no_changeturf = TRUE, new_z = TRUE))
|
||||
errorList |= pm.original_path
|
||||
// SKYRAT EDIT ADDITION BEGIN - We need to load our templates from cache after our space has been carved out.
|
||||
if(!LAZYLEN(errorList))
|
||||
@@ -431,7 +435,7 @@ Used by the AI doomsday and the self-destruct nuke.
|
||||
GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/generate_station_area_list()
|
||||
for(var/area/station/station_area in world)
|
||||
for(var/area/station/station_area in GLOB.areas)
|
||||
if (!(station_area.area_flags & UNIQUE_AREA))
|
||||
continue
|
||||
if (is_station_level(station_area.z))
|
||||
@@ -441,7 +445,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
log_world("ERROR: Station areas list failed to generate!")
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/run_map_generation()
|
||||
for(var/area/A in world)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
A.RunGeneration()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/maprotate()
|
||||
@@ -724,7 +728,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
/// Takes a z level datum, and tells the mapping subsystem to manage it
|
||||
/// Also handles things like plane offset generation, and other things that happen on a z level to z level basis
|
||||
/datum/controller/subsystem/mapping/proc/manage_z_level(datum/space_level/new_z)
|
||||
/datum/controller/subsystem/mapping/proc/manage_z_level(datum/space_level/new_z, filled_with_space, contain_turfs = TRUE)
|
||||
// First, add the z
|
||||
z_list += new_z
|
||||
|
||||
@@ -743,11 +747,26 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
if(below_offset)
|
||||
update_plane_tracking(new_z)
|
||||
|
||||
if(contain_turfs)
|
||||
build_area_turfs(z_value, filled_with_space)
|
||||
|
||||
// And finally, misc global generation
|
||||
|
||||
// We'll have to update this if offsets change, because we load lowest z to highest z
|
||||
generate_lighting_appearance_by_z(z_value)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/build_area_turfs(z_level, space_guaranteed)
|
||||
// If we know this is filled with default tiles, we can use the default area
|
||||
// Faster
|
||||
if(space_guaranteed)
|
||||
var/area/global_area = GLOB.areas_by_type[world.area]
|
||||
global_area.contained_turfs += 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
|
||||
|
||||
/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
|
||||
// Yes this will cause infinite loops if our templating is fucked. Fuck off
|
||||
|
||||
@@ -65,7 +65,7 @@ SUBSYSTEM_DEF(networks)
|
||||
|
||||
/datum/controller/subsystem/networks/Initialize()
|
||||
station_network.register_map_supremecy() // sigh
|
||||
assign_areas_root_ids(GLOB.sortedAreas) // setup area names before Initialize
|
||||
assign_areas_root_ids(get_sorted_areas()) // setup area names before Initialize
|
||||
station_network.build_software_lists()
|
||||
syndie_network.build_software_lists()
|
||||
|
||||
|
||||
@@ -619,9 +619,12 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/turf/midpoint = locate(transit_x, transit_y, bottomleft.z)
|
||||
if(!midpoint)
|
||||
return FALSE
|
||||
var/area/old_area = midpoint.loc
|
||||
old_area.turfs_to_uncontain += proposal.reserved_turfs
|
||||
var/area/shuttle/transit/A = new()
|
||||
A.parallax_movedir = travel_dir
|
||||
A.contents = proposal.reserved_turfs
|
||||
A.contained_turfs = proposal.reserved_turfs
|
||||
var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint)
|
||||
new_transit_dock.reserved_area = proposal
|
||||
new_transit_dock.name = "Transit for [M.shuttle_id]/[M.name]"
|
||||
|
||||
+35
-10
@@ -13,6 +13,15 @@
|
||||
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)
|
||||
/// 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
|
||||
/// 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()
|
||||
|
||||
var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED
|
||||
|
||||
///Do we have an active fire alarm?
|
||||
@@ -127,20 +136,16 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
* The returned list of turfs is sorted by name
|
||||
*/
|
||||
/proc/process_teleport_locs()
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/AR = V
|
||||
for(var/area/AR as anything in get_sorted_areas())
|
||||
if(istype(AR, /area/shuttle) || AR.area_flags & NOTELEPORT)
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
continue
|
||||
if (!AR.contents.len)
|
||||
if (!AR.has_contained_turfs())
|
||||
continue
|
||||
var/turf/picked = AR.contents[1]
|
||||
if (picked && is_station_level(picked.z))
|
||||
if (is_station_level(AR.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
|
||||
sortTim(GLOB.teleportlocs, GLOBAL_PROC_REF(cmp_text_asc))
|
||||
|
||||
/**
|
||||
* Called when an area loads
|
||||
*
|
||||
@@ -151,6 +156,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
// rather than waiting for atoms to initialize.
|
||||
if (area_flags & UNIQUE_AREA)
|
||||
GLOB.areas_by_type[type] = src
|
||||
GLOB.areas += src
|
||||
power_usage = new /list(AREA_USAGE_LEN) // Some atoms would like to use power in Initialize()
|
||||
alarm_manager = new(src) // just in case
|
||||
return ..()
|
||||
@@ -219,6 +225,24 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
turfs += T
|
||||
map_generator.generate_terrain(turfs, src)
|
||||
|
||||
/area/proc/get_contained_turfs()
|
||||
if(length(turfs_to_uncontain))
|
||||
cannonize_contained_turfs()
|
||||
return contained_turfs
|
||||
|
||||
/// Ensures that the contained_turfs list properly represents the turfs actually inside us
|
||||
/area/proc/cannonize_contained_turfs()
|
||||
// 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()
|
||||
|
||||
/// Returns TRUE if we have contained turfs, FALSE otherwise
|
||||
/area/proc/has_contained_turfs()
|
||||
return length(contained_turfs) - length(turfs_to_uncontain) > 0
|
||||
|
||||
/**
|
||||
* Register this area as belonging to a z level
|
||||
@@ -226,7 +250,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
* Ensures the item is added to the SSmapping.areas_in_z list for this z
|
||||
*/
|
||||
/area/proc/reg_in_areas_in_z()
|
||||
if(!length(contents))
|
||||
if(!has_contained_turfs())
|
||||
return
|
||||
var/list/areas_in_z = SSmapping.areas_in_z
|
||||
update_areasize()
|
||||
@@ -249,6 +273,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if(GLOB.areas_by_type[type] == src)
|
||||
GLOB.areas_by_type[type] = null
|
||||
GLOB.sortedAreas -= src
|
||||
GLOB.areas -= src
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(alarm_manager)
|
||||
return ..()
|
||||
@@ -472,7 +497,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
always_unpowered = FALSE
|
||||
area_flags &= ~VALID_TERRITORY
|
||||
area_flags &= ~BLOBS_ALLOWED
|
||||
addSorted()
|
||||
require_area_resort()
|
||||
/**
|
||||
* Set the area size of the area
|
||||
*
|
||||
@@ -483,7 +508,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
if(outdoors)
|
||||
return FALSE
|
||||
areasize = 0
|
||||
for(var/turf/open/T in contents)
|
||||
for(var/turf/open/T in get_contained_turfs())
|
||||
areasize++
|
||||
|
||||
/**
|
||||
|
||||
@@ -973,7 +973,7 @@ GLOBAL_LIST_EMPTY(possible_items_special)
|
||||
/datum/objective/contract/proc/generate_dropoff()
|
||||
var/found = FALSE
|
||||
while (!found)
|
||||
var/area/dropoff_area = pick(GLOB.sortedAreas)
|
||||
var/area/dropoff_area = pick(GLOB.areas)
|
||||
if(dropoff_area && (dropoff_area.type in GLOB.the_station_areas) && !dropoff_area.outdoors)
|
||||
dropoff = dropoff_area
|
||||
found = TRUE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/client/proc/jumptoarea(area/A in GLOB.sortedAreas)
|
||||
/client/proc/jumptoarea(area/A in get_sorted_areas())
|
||||
set name = "Jump to Area"
|
||||
set desc = "Area to jump to"
|
||||
set category = "Admin.Game"
|
||||
@@ -159,10 +159,11 @@
|
||||
if(!src.holder)
|
||||
to_chat(src, "Only administrators may use this command.", confidential = TRUE)
|
||||
return
|
||||
if(!length(GLOB.sortedAreas))
|
||||
var/list/sorted_areas = get_sorted_areas()
|
||||
if(!length(sorted_areas))
|
||||
to_chat(src, "No areas found.", confidential = TRUE)
|
||||
return
|
||||
var/area/target_area = tgui_input_list(src, "Pick an area", "Send Mob", GLOB.sortedAreas)
|
||||
var/area/target_area = tgui_input_list(src, "Pick an area", "Send Mob", sorted_areas)
|
||||
if(isnull(target_area))
|
||||
return
|
||||
if(!istype(target_area))
|
||||
|
||||
@@ -286,7 +286,7 @@
|
||||
message_admins(span_adminnotice("[key_name_admin(usr)] used the Test Areas debug command checking [log_message]."))
|
||||
log_admin("[key_name(usr)] used the Test Areas debug command checking [log_message].")
|
||||
|
||||
for(var/area/A in world)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
if(on_station)
|
||||
var/list/area_turfs = get_area_turfs(A.type)
|
||||
if (!length(area_turfs))
|
||||
|
||||
@@ -180,7 +180,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
else
|
||||
L.fully_heal(admin_revive = FALSE)
|
||||
|
||||
for(var/area/A in GLOB.sortedAreas)
|
||||
for(var/area/A in GLOB.areas)
|
||||
if(!(A.type in GLOB.the_station_areas))
|
||||
continue
|
||||
if(!(A.area_flags & BLOBS_ALLOWED))
|
||||
|
||||
@@ -424,7 +424,7 @@
|
||||
..()
|
||||
var/sanity = 0
|
||||
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
|
||||
var/area/summon_area = pick(GLOB.sortedAreas - summon_spots)
|
||||
var/area/summon_area = pick(GLOB.areas - summon_spots)
|
||||
if(summon_area && is_station_level(summon_area.z) && (summon_area.area_flags & VALID_TERRITORY))
|
||||
summon_spots += summon_area
|
||||
sanity++
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
//Explosive plant, the bomb will register its completion on priming
|
||||
var/datum/objective/plant_explosive/bombobjective = new /datum/objective/plant_explosive()
|
||||
for(var/sanity in 1 to 100) // 100 checks at most.
|
||||
var/area/selected_area = pick(GLOB.sortedAreas)
|
||||
var/area/selected_area = pick(GLOB.areas)
|
||||
if(!is_station_level(selected_area.z) || !(selected_area.area_flags & VALID_TERRITORY))
|
||||
continue
|
||||
bombobjective.detonation_location = selected_area
|
||||
|
||||
@@ -81,9 +81,9 @@
|
||||
else
|
||||
var/mob/user_mob = user
|
||||
holder = user_mob.client //if its a mob, assign the mob's client to holder
|
||||
bay = locate(/area/centcom/central_command_areas/supplypod/loading/one) in GLOB.sortedAreas //Locate the default bay (one) from the centcom map
|
||||
bay = locate(/area/centcom/central_command_areas/supplypod/loading/one) in GLOB.areas //Locate the default bay (one) from the centcom map
|
||||
bayNumber = bay.loading_id //Used as quick reference to what bay we're taking items from
|
||||
var/area/pod_storage_area = locate(/area/centcom/central_command_areas/supplypod/pod_storage) in GLOB.sortedAreas
|
||||
var/area/pod_storage_area = locate(/area/centcom/central_command_areas/supplypod/pod_storage) in GLOB.areas
|
||||
temp_pod = new(pick(get_area_turfs(pod_storage_area))) //Create a new temp_pod in the podStorage area on centcom (so users are free to look at it and change other variables if needed)
|
||||
orderedArea = createOrderedArea(bay) //Order all the turfs in the selected bay (top left to bottom right) to a single list. Used for the "ordered" mode (launchChoice = 1)
|
||||
selector = new(null, holder.mob)
|
||||
|
||||
@@ -191,7 +191,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.contents)//uses default landing zone
|
||||
for(var/turf/open/floor/T in landingzone.get_contained_turfs())//uses default landing zone
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
LAZYADD(empty_turfs, T)
|
||||
@@ -210,7 +210,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.contents)
|
||||
for(var/turf/open/floor/T in landingzone.get_contained_turfs())
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
LAZYADD(empty_turfs, T)
|
||||
|
||||
@@ -99,9 +99,8 @@
|
||||
if(!port)
|
||||
return
|
||||
var/list/shuttle_areas = port.shuttle_areas
|
||||
for(var/r in shuttle_areas)
|
||||
var/area/region = r
|
||||
for(var/turf/place in region.contents)
|
||||
for(var/area/region as anything in shuttle_areas)
|
||||
for(var/turf/place as anything in region.get_contained_turfs())
|
||||
if(get_dist(user, place) > 7)
|
||||
continue
|
||||
var/image/pic
|
||||
@@ -185,7 +184,7 @@
|
||||
if(open.blocks_air)
|
||||
continue
|
||||
var/datum/gas_mixture/environment = open.return_air()
|
||||
var/temp = round(environment.return_temperature())
|
||||
var/temp = round(environment.return_temperature())
|
||||
var/image/pic = image('icons/turf/overlays.dmi', open, "greyOverlay", ABOVE_ALL_MOB_LAYER)
|
||||
// Lower than TEMP_SHADE_CYAN should be deep blue
|
||||
switch(temp)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/datum/anomaly_placer/proc/findValidArea()
|
||||
if(!allowed_areas)
|
||||
generateAllowedAreas()
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.areas, allowed_areas)
|
||||
if (!length(possible_areas))
|
||||
CRASH("No valid areas for anomaly found.")
|
||||
|
||||
|
||||
@@ -29,13 +29,12 @@
|
||||
M.playsound_local(M, 'sound/ambience/aurora_caelus.ogg', 20, FALSE, pressure_affected = FALSE)
|
||||
|
||||
/datum/round_event/aurora_caelus/start()
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
var/area/affected_area = area
|
||||
for(var/area/affected_area as anything in GLOB.areas)
|
||||
if(affected_area.area_flags & AREA_USES_STARLIGHT)
|
||||
for(var/turf/open/space/spess in affected_area)
|
||||
for(var/turf/open/space/spess in affected_area.get_contained_turfs())
|
||||
spess.set_light(spess.light_range * 3, spess.light_power * 0.5)
|
||||
if(istype(affected_area, /area/station/service/kitchen))
|
||||
for(var/turf/open/kitchen in affected_area)
|
||||
for(var/turf/open/kitchen in affected_area.get_contained_turfs())
|
||||
kitchen.set_light(1, 0.75)
|
||||
if(!prob(1) && !check_holidays(APRIL_FOOLS))
|
||||
continue
|
||||
@@ -56,23 +55,22 @@
|
||||
if(activeFor % 5 == 0)
|
||||
aurora_progress++
|
||||
var/aurora_color = aurora_colors[aurora_progress]
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
var/area/affected_area = area
|
||||
for(var/area/affected_area as anything in GLOB.areas)
|
||||
if(affected_area.area_flags & AREA_USES_STARLIGHT)
|
||||
for(var/turf/open/space/spess as anything in affected_area)
|
||||
for(var/turf/open/space/spess in affected_area.get_contained_turfs())
|
||||
spess.set_light(l_color = aurora_color)
|
||||
if(istype(affected_area, /area/station/service/kitchen))
|
||||
for(var/turf/open/kitchen_floor in affected_area)
|
||||
for(var/turf/open/kitchen_floor in affected_area.get_contained_turfs())
|
||||
kitchen_floor.set_light(l_color = aurora_color)
|
||||
|
||||
/datum/round_event/aurora_caelus/end()
|
||||
for(var/area in GLOB.sortedAreas)
|
||||
for(var/area in GLOB.areas)
|
||||
var/area/affected_area = area
|
||||
if(affected_area.area_flags & AREA_USES_STARLIGHT)
|
||||
for(var/turf/open/space/spess in affected_area)
|
||||
for(var/turf/open/space/spess in affected_area.get_contained_turfs())
|
||||
fade_to_black(spess)
|
||||
if(istype(affected_area, /area/station/service/kitchen))
|
||||
for(var/turf/open/superturfentent in affected_area)
|
||||
for(var/turf/open/superturfentent in affected_area.get_contained_turfs())
|
||||
fade_to_black(superturfentent)
|
||||
priority_announce("The aurora caelus event is now ending. Starlight conditions will slowly return to normal. When this has concluded, please return to your workplace and continue work as normal. Have a pleasant shift, [station_name()], and thank you for watching with us.",
|
||||
sound = 'sound/misc/notice2.ogg',
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
severity = rand(1,3)
|
||||
for(var/i in 1 to severity)
|
||||
var/picked_area = pick_n_take(potential_areas)
|
||||
for(var/area/A in world)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
if(istype(A, picked_area))
|
||||
areasToOpen += A
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
|
||||
var/obj/structure/spacevine/vine = new()
|
||||
|
||||
for(var/area/station/hallway/area in world)
|
||||
for(var/turf/floor in area)
|
||||
for(var/area/station/hallway/area in GLOB.areas)
|
||||
for(var/turf/floor as anything in area.get_contained_turfs())
|
||||
if(floor.Enter(vine))
|
||||
turfs += floor
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(ispath(pack_type, /datum/supply_pack))
|
||||
SP = new pack_type
|
||||
else // treat this as a supply pack id and resolving it with SSshuttle
|
||||
SP = SSshuttle.supply_packs[pack_type]
|
||||
SP = SSshuttle.supply_packs[pack_type]
|
||||
var/obj/structure/closet/crate/crate = SP.generate(null)
|
||||
if(crate) //empty supply packs are a thing! get memed on.
|
||||
crate.locked = FALSE //Unlock secure crates
|
||||
@@ -84,7 +84,7 @@
|
||||
///Subtypes from the above that actually should explode.
|
||||
var/static/list/unsafe_area_subtypes = typecacheof(list(/area/station/engineering/break_room))
|
||||
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
|
||||
var/list/possible_areas = typecache_filter_list(GLOB.areas, allowed_areas)
|
||||
if (length(possible_areas))
|
||||
return pick(possible_areas)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
/area/proc/remove_base_lighting()
|
||||
var/list/z_offsets = SSmapping.z_level_to_plane_offset
|
||||
for(var/turf/T in src)
|
||||
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])
|
||||
cut_overlay(lighting_effects[1])
|
||||
@@ -69,7 +69,7 @@
|
||||
lighting_effects += lighting_effect
|
||||
add_overlay(lighting_effects[1])
|
||||
var/list/z_offsets = SSmapping.z_level_to_plane_offset
|
||||
for(var/turf/T in src)
|
||||
for(var/turf/T as anything in get_contained_turfs())
|
||||
T.luminosity = 1
|
||||
// This outside loop is EXTREMELY hot because it's run by space tiles. Don't want no part in that
|
||||
// We will only add overlays to turfs not on the first z layer, because that's a significantly lesser portion
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
/proc/create_all_lighting_objects()
|
||||
for(var/area/A in world)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
if(!A.static_lighting)
|
||||
continue
|
||||
|
||||
// I hate this so much dude. why do areas not track their turfs lummyyyyyyy
|
||||
for(var/turf/T in A)
|
||||
for(var/turf/T as anything in A.get_contained_turfs())
|
||||
if(T.always_lit)
|
||||
continue
|
||||
new/datum/lighting_object(T)
|
||||
|
||||
@@ -133,14 +133,13 @@
|
||||
var/x = round((world.maxx - width) * 0.5) + 1
|
||||
var/y = round((world.maxy - height) * 0.5) + 1
|
||||
|
||||
var/datum/space_level/level = SSmapping.add_new_zlevel(name, secret ? ZTRAITS_AWAY_SECRET : ZTRAITS_AWAY)
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top)
|
||||
var/datum/space_level/level = SSmapping.add_new_zlevel(name, secret ? ZTRAITS_AWAY_SECRET : ZTRAITS_AWAY, contain_turfs = FALSE)
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top, new_z = TRUE)
|
||||
var/list/bounds = parsed.bounds
|
||||
if(!bounds)
|
||||
return FALSE
|
||||
|
||||
repopulate_sorted_areas()
|
||||
|
||||
require_area_resort()
|
||||
//initialize things that are normally initialized after map load
|
||||
initTemplateBounds(bounds)
|
||||
smooth_zlevel(world.maxz)
|
||||
@@ -181,8 +180,7 @@
|
||||
if(!bounds)
|
||||
return
|
||||
|
||||
if(!SSmapping.loading_ruins) //Will be done manually during mapping ss init
|
||||
repopulate_sorted_areas()
|
||||
require_area_resort()
|
||||
|
||||
//initialize things that are normally initialized after map load
|
||||
initTemplateBounds(bounds)
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
/// - `no_changeturf`: When true, [/turf/proc/AfterChange] won't be called on loaded turfs
|
||||
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
|
||||
/// - `placeOnTop`: Whether to use [/turf/proc/PlaceOnTop] rather than [/turf/proc/ChangeTurf] (Optional).
|
||||
/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num)
|
||||
/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num, new_z)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly)
|
||||
if(parsed.bounds && !measureOnly)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z = new_z)
|
||||
return parsed
|
||||
|
||||
/// Parse a map, possibly cropping it.
|
||||
@@ -157,10 +157,10 @@
|
||||
src.key_len = key_len
|
||||
|
||||
/// Load the parsed map into the world. See [/proc/load_map] for arguments.
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, whitelist = FALSE)
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, whitelist = FALSE, new_z)
|
||||
//How I wish for RAII
|
||||
Master.StartLoadingMap()
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
. = _load_impl(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, new_z)
|
||||
Master.StopLoadingMap()
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
SSatoms.map_loader_begin(); \
|
||||
}
|
||||
// Do not call except via load() above.
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE)
|
||||
/datum/parsed_map/proc/_load_impl(x_offset = 1, y_offset = 1, z_offset = world.maxz + 1, cropMap = FALSE, no_changeturf = FALSE, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, placeOnTop = FALSE, new_z = FALSE)
|
||||
PRIVATE_PROC(TRUE)
|
||||
var/list/modelCache = build_cache(no_changeturf)
|
||||
var/space_key = modelCache[SPACE_KEY]
|
||||
@@ -288,7 +288,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop()
|
||||
CRASH("Undefined model key in DMM: [line]")
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop)
|
||||
build_coordinate(cache, locate(true_xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
@@ -320,7 +320,7 @@
|
||||
if(!cache)
|
||||
SSatoms.map_loader_stop()
|
||||
CRASH("Undefined model key in DMM: [model_key]")
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop)
|
||||
build_coordinate(cache, locate(xcrd, ycrd, zcrd), no_afterchange, placeOnTop, new_z)
|
||||
|
||||
// only bother with bounds that actually exist
|
||||
if(!first_found)
|
||||
@@ -347,6 +347,10 @@
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(CHANGETURF_IGNORE_AIR)
|
||||
|
||||
if(new_z)
|
||||
for(var/z_index in bounds[MAP_MINZ] to bounds[MAP_MAXZ])
|
||||
SSmapping.build_area_turfs(z_index)
|
||||
|
||||
if(has_expanded_world_maxx || has_expanded_world_maxy)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_EXPANDED_WORLD_BOUNDS, has_expanded_world_maxx, has_expanded_world_maxy)
|
||||
|
||||
@@ -437,7 +441,7 @@ GLOBAL_LIST_EMPTY(map_model_default)
|
||||
|
||||
.[model_key] = list(members, members_attributes)
|
||||
|
||||
/datum/parsed_map/proc/build_coordinate(list/model, turf/crds, no_changeturf as num, placeOnTop as num)
|
||||
/datum/parsed_map/proc/build_coordinate(list/model, turf/crds, no_changeturf as num, placeOnTop as num, new_z)
|
||||
// If we don't have a turf, nothing we will do next will actually acomplish anything, so just go back
|
||||
// Note, this would actually drop area vvs in the tile, but like, why tho
|
||||
if(!crds)
|
||||
@@ -458,29 +462,34 @@ GLOBAL_LIST_EMPTY(map_model_default)
|
||||
//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile
|
||||
//first instance the /area and remove it from the members list
|
||||
index = members.len
|
||||
var/atom/instance
|
||||
if(members[index] != /area/template_noop)
|
||||
var/area/area_instance
|
||||
if(members_attributes[index] != default_list)
|
||||
world.preloader_setup(members_attributes[index], members[index])//preloader for assigning set variables on atom creation
|
||||
instance = loaded_areas[members[index]]
|
||||
if(!instance)
|
||||
area_instance = loaded_areas[members[index]]
|
||||
if(!area_instance)
|
||||
var/area_type = members[index]
|
||||
// If this parsed map doesn't have that area already, we check the global cache
|
||||
instance = GLOB.areas_by_type[area_type]
|
||||
area_instance = GLOB.areas_by_type[area_type]
|
||||
// If the global list DOESN'T have this area it's either not a unique area, or it just hasn't been created yet
|
||||
if (!instance)
|
||||
instance = new area_type(null)
|
||||
if(!instance)
|
||||
if (!area_instance)
|
||||
area_instance = new area_type(null)
|
||||
if(!area_instance)
|
||||
CRASH("[area_type] failed to be new'd, what'd you do?")
|
||||
loaded_areas[area_type] = instance
|
||||
loaded_areas[area_type] = area_instance
|
||||
|
||||
instance.contents.Add(crds)
|
||||
if(!new_z)
|
||||
var/area/old_area = crds.loc
|
||||
old_area.turfs_to_uncontain += crds
|
||||
area_instance.contained_turfs.Add(crds)
|
||||
area_instance.contents.Add(crds)
|
||||
|
||||
if(GLOB.use_preloader)
|
||||
world.preloader_load(instance)
|
||||
world.preloader_load(area_instance)
|
||||
|
||||
// Index right before /area is /turf
|
||||
index--
|
||||
var/atom/instance
|
||||
//then instance the /turf
|
||||
//NOTE: this used to place any turfs before the last "underneath" it using .appearance and underlays
|
||||
//We don't actually use this, and all it did was cost cpu, so we don't do this anymore
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
for (var/I in 1 to default_map_traits.len)
|
||||
var/list/features = default_map_traits[I]
|
||||
var/datum/space_level/S = new(I, features[DL_NAME], features[DL_TRAITS])
|
||||
manage_z_level(S)
|
||||
manage_z_level(S, filled_with_space = FALSE)
|
||||
generate_z_level_linkages() // Default Zs don't use add_new_zlevel() so they don't automatically generate z-linkages.
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, traits = list(), z_type = /datum/space_level)
|
||||
/datum/controller/subsystem/mapping/proc/add_new_zlevel(name, traits = list(), z_type = /datum/space_level, contain_turfs = TRUE)
|
||||
UNTIL(!adding_new_zlevel)
|
||||
adding_new_zlevel = TRUE
|
||||
var/new_z = z_list.len + 1
|
||||
@@ -28,7 +28,7 @@
|
||||
CHECK_TICK
|
||||
// TODO: sleep here if the Z level needs to be cleared
|
||||
var/datum/space_level/S = new z_type(new_z, name, traits)
|
||||
manage_z_level(S)
|
||||
manage_z_level(S, filled_with_space = TRUE, contain_turfs = contain_turfs)
|
||||
generate_linkages_for_z_level(new_z)
|
||||
calculate_z_level_gravity(new_z)
|
||||
adding_new_zlevel = FALSE
|
||||
|
||||
@@ -465,8 +465,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(usr, span_warning("Not when you're not dead!"))
|
||||
return
|
||||
var/list/filtered = list()
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/A = V
|
||||
for(var/area/A as anything in get_sorted_areas())
|
||||
if(!(A.area_flags & HIDDEN_AREA))
|
||||
filtered += A
|
||||
var/area/thearea = tgui_input_list(usr, "Area to jump to", "BOOYEA", filtered)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var/list/obj/structure/cable/cables = list()
|
||||
var/list/atom/atoms = list()
|
||||
|
||||
repopulate_sorted_areas()
|
||||
require_area_resort()
|
||||
|
||||
for(var/L in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], SSmapping.station_start),
|
||||
locate(bounds[MAP_MAXX], bounds[MAP_MAXY], z_offset - 1)))
|
||||
|
||||
@@ -656,7 +656,7 @@
|
||||
|
||||
/datum/religion_rites/declare_arena/perform_rite(mob/living/user, atom/religious_tool)
|
||||
var/list/filtered = list()
|
||||
for(var/area/unfiltered_area as anything in GLOB.sortedAreas)
|
||||
for(var/area/unfiltered_area as anything in get_sorted_areas())
|
||||
if(istype(unfiltered_area, /area/centcom)) //youuu dont need thaaat
|
||||
continue
|
||||
if(!(unfiltered_area.area_flags & HIDDEN_AREA))
|
||||
|
||||
@@ -151,19 +151,21 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/keycard_auth, 26)
|
||||
|
||||
GLOBAL_VAR_INIT(emergency_access, FALSE)
|
||||
/proc/make_maint_all_access()
|
||||
for(var/area/station/maintenance/A in world)
|
||||
for(var/obj/machinery/door/airlock/D in A)
|
||||
D.emergency = TRUE
|
||||
D.update_icon(ALL, 0)
|
||||
for(var/area/station/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(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/station/maintenance/A in world)
|
||||
for(var/obj/machinery/door/airlock/D in A)
|
||||
D.emergency = FALSE
|
||||
D.update_icon(ALL, 0)
|
||||
for(var/area/station/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(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"))
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
areas = list()
|
||||
|
||||
var/list/new_latejoin = list()
|
||||
for(var/area/shuttle/arrival/A in GLOB.sortedAreas)
|
||||
for(var/area/shuttle/arrival/A in GLOB.areas)
|
||||
for(var/obj/structure/chair/C in A)
|
||||
new_latejoin += C
|
||||
if(!console)
|
||||
|
||||
@@ -481,7 +481,7 @@
|
||||
if(time_left <= 50 && !sound_played) //4 seconds left:REV UP THOSE ENGINES BOYS. - should sync up with the launch
|
||||
sound_played = 1 //Only rev them up once.
|
||||
var/list/areas = list()
|
||||
for(var/area/shuttle/escape/E in GLOB.sortedAreas)
|
||||
for(var/area/shuttle/escape/E in GLOB.areas)
|
||||
areas += E
|
||||
hyperspace_sound(HYPERSPACE_WARMUP, areas)
|
||||
|
||||
@@ -493,7 +493,7 @@
|
||||
|
||||
//now move the actual emergency shuttle to its transit dock
|
||||
var/list/areas = list()
|
||||
for(var/area/shuttle/escape/E in GLOB.sortedAreas)
|
||||
for(var/area/shuttle/escape/E in GLOB.areas)
|
||||
areas += E
|
||||
hyperspace_sound(HYPERSPACE_LAUNCH, areas)
|
||||
enterTransit()
|
||||
@@ -512,7 +512,7 @@
|
||||
if(SHUTTLE_ESCAPE)
|
||||
if(sound_played && time_left <= HYPERSPACE_END_TIME)
|
||||
var/list/areas = list()
|
||||
for(var/area/shuttle/escape/E in GLOB.sortedAreas)
|
||||
for(var/area/shuttle/escape/E in GLOB.areas)
|
||||
areas += E
|
||||
hyperspace_sound(HYPERSPACE_END, areas)
|
||||
if(time_left <= PARALLAX_LOOP_TIME)
|
||||
|
||||
@@ -171,7 +171,9 @@ All ShuttleMove procs go here
|
||||
return TRUE
|
||||
|
||||
contents -= oldT
|
||||
turfs_to_uncontain += oldT
|
||||
underlying_old_area.contents += oldT
|
||||
underlying_old_area.contained_turfs += oldT
|
||||
oldT.transfer_area_lighting(src, underlying_old_area)
|
||||
//The old turf has now been given back to the area that turf originaly belonged to
|
||||
|
||||
@@ -179,7 +181,9 @@ All ShuttleMove procs go here
|
||||
parallax_movedir = old_dest_area.parallax_movedir
|
||||
|
||||
old_dest_area.contents -= newT
|
||||
old_dest_area.turfs_to_uncontain += newT
|
||||
contents += newT
|
||||
contained_turfs += newT
|
||||
newT.transfer_area_lighting(old_dest_area, src)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -673,7 +673,9 @@
|
||||
if(!oldT || !istype(oldT.loc, area_type))
|
||||
continue
|
||||
var/area/old_area = oldT.loc
|
||||
old_area.turfs_to_uncontain += oldT
|
||||
underlying_area.contents += oldT
|
||||
underlying_area.contained_turfs += oldT
|
||||
oldT.transfer_area_lighting(old_area, underlying_area)
|
||||
oldT.empty(FALSE)
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
|
||||
#define TEST_PRE 0
|
||||
#define TEST_DEFAULT 1
|
||||
/// This should be one of the last tests to run, because we run it for a little bit over 30 seconds by design and we want to run all of the tests that take a trivial amount of time to complete beforehand.
|
||||
#define TEST_MONKEY_BUSINESS 10
|
||||
/// After most test steps, used for tests that run long so shorter issues can be noticed faster
|
||||
#define TEST_LONGER 10
|
||||
/// This must be the last test to run due to the inherent nature of the test iterating every single tangible atom in the game and qdeleting all of them (while taking long sleeps to make sure the garbage collector fires properly) taking a large amount of time.
|
||||
#define TEST_CREATE_AND_DESTROY INFINITY
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "achievements.dm"
|
||||
#include "anchored_mobs.dm"
|
||||
#include "anonymous_themes.dm"
|
||||
#include "area_contents.dm"
|
||||
#include "autowiki.dm"
|
||||
#include "barsigns.dm"
|
||||
#include "bespoke_id.dm"
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/// Verifies that an area's perception of their "turfs" is correct, and no other area overlaps with them
|
||||
/// Quite slow, but needed
|
||||
/datum/unit_test/area_contents
|
||||
priority = TEST_LONGER
|
||||
|
||||
/datum/unit_test/area_contents/Run()
|
||||
/// assoc list of turfs -> areas
|
||||
var/list/turf_to_area = list()
|
||||
// First, we check that there are no entries in more then one area
|
||||
// That or duplicate entries
|
||||
for(var/area/space in GLOB.areas)
|
||||
for(var/turf/position as anything in space.get_contained_turfs())
|
||||
if(!isturf(position))
|
||||
TEST_FAIL("Found a [position.type] in [space.type]'s turf listing")
|
||||
var/area/existing = turf_to_area[position]
|
||||
if(existing == space)
|
||||
TEST_FAIL("Found a duplicate turf [position.type] inside [space.type]'s turf listing")
|
||||
else if(existing)
|
||||
TEST_FAIL("Found a shared turf [position.type] between [space.type] and [existing.type]'s turf listings")
|
||||
|
||||
var/area/dream_spot = position.loc
|
||||
if(dream_spot != space)
|
||||
TEST_FAIL("Found a turf [position.type] which is IN [dream_spot.type], but is registered as being in [space.type]")
|
||||
|
||||
turf_to_area[position] = space
|
||||
|
||||
for(var/turf/position in ALL_TURFS())
|
||||
if(!turf_to_area[position])
|
||||
TEST_FAIL("Found a turf [position.type] inside [position.loc.type] that is NOT stored in any area's turf listing")
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* but its also hilarious and fun to watch locally.
|
||||
*/
|
||||
/datum/unit_test/monkey_business
|
||||
priority = TEST_MONKEY_BUSINESS
|
||||
priority = TEST_LONGER
|
||||
var/monkey_timer = 30 SECONDS
|
||||
var/monkey_angry_nth = 5 // every nth monkey will be angry
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
|
||||
var/obj/structure/spacevine/vine = new()
|
||||
|
||||
for(var/area/station/maintenance/maint_area in world)
|
||||
for(var/turf/floor in maint_area)
|
||||
for(var/area/station/maintenance/maint_area in GLOB.areas)
|
||||
for(var/turf/floor as anything in maint_area.get_contained_turfs())
|
||||
if(floor.Enter(vine))
|
||||
turfs += floor
|
||||
|
||||
|
||||
@@ -204,8 +204,8 @@
|
||||
|
||||
var/obj/structure/test_structure = new() // This is apparently the most intuative way to check if a turf is able to support entering.
|
||||
|
||||
for(var/area/station/maintenance/maint_area in world)
|
||||
for(var/turf/floor in maint_area)
|
||||
for(var/area/station/maintenance/maint_area in GLOB.areas)
|
||||
for(var/turf/floor as anything in maint_area.get_contained_turfs())
|
||||
if(!is_station_level(floor.z))
|
||||
continue
|
||||
if(floor.Enter(test_structure))
|
||||
|
||||
@@ -82,7 +82,7 @@ SUBSYSTEM_DEF(area_spawn)
|
||||
turf_list = area_turf_info["[mode]"] = list()
|
||||
|
||||
// Get highest priority items
|
||||
for(var/turf/iterating_turf in area)
|
||||
for(var/turf/iterating_turf as anything in area.get_contained_turfs())
|
||||
// Only retain turfs of the highest priority
|
||||
var/priority = process_turf(iterating_turf, mode)
|
||||
if(priority > 0)
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
|
||||
var/list/possible_spawn_areas = typecacheof(typesof(/area/station/maintenance, /area/station/security/prison, /area/station/construction))
|
||||
|
||||
for(var/area/A in world)
|
||||
for(var/area/A as anything in GLOB.areas)
|
||||
if(!is_station_level(A.z))
|
||||
continue
|
||||
if(!is_type_in_typecache(A, possible_spawn_areas))
|
||||
continue
|
||||
for(var/turf/open/floor in A)
|
||||
for(var/turf/open/floor in A.get_contained_turfs())
|
||||
if(!floor.Enter(resintest))
|
||||
continue
|
||||
if(locate(/turf/closed) in range(2, floor))
|
||||
|
||||
@@ -45,18 +45,17 @@ SUBSYSTEM_DEF(decay)
|
||||
log_world("SSDecay will not interact with this round.")
|
||||
return SS_INIT_NO_NEED
|
||||
|
||||
for(var/turf/iterating_turf in world)
|
||||
if(!is_station_level(iterating_turf.z))
|
||||
continue
|
||||
if(!(iterating_turf.flags_1 & CAN_BE_DIRTY_1))
|
||||
continue
|
||||
possible_turfs += iterating_turf
|
||||
|
||||
for(var/area/iterating_area in world)
|
||||
for(var/area/iterating_area as anything in GLOB.areas)
|
||||
if(!is_station_level(iterating_area.z))
|
||||
continue
|
||||
possible_areas += iterating_area
|
||||
|
||||
// Now add the turfs
|
||||
for(var/turf/iterating_turf as anything in iterating_area.get_contained_turfs())
|
||||
if(!(iterating_turf.flags_1 & CAN_BE_DIRTY_1))
|
||||
continue
|
||||
possible_turfs += iterating_turf
|
||||
|
||||
if(!possible_turfs)
|
||||
CRASH("SSDecay had no possible turfs to use!")
|
||||
|
||||
|
||||
@@ -562,6 +562,7 @@
|
||||
#include "code\controllers\subsystem\ai_controllers.dm"
|
||||
#include "code\controllers\subsystem\air.dm"
|
||||
#include "code\controllers\subsystem\ambience.dm"
|
||||
#include "code\controllers\subsystem\area_contents.dm"
|
||||
#include "code\controllers\subsystem\asset_loading.dm"
|
||||
#include "code\controllers\subsystem\assets.dm"
|
||||
#include "code\controllers\subsystem\atoms.dm"
|
||||
|
||||
Reference in New Issue
Block a user