Files
Paradise/code/modules/space_management/space_level.dm
Crazylemon64 bf2a895658 Makes space transition checks more consistent
Fixes a runtime on map start due to not having updated all the border
definitions all at once - the new defines will now resolve this.
2016-08-22 19:46:23 -07:00

200 lines
6.0 KiB
Plaintext

/datum/space_level
var/name = "Your config settings failed, you need to fix this for the datum space levels to work"
var/zpos = 1
var/flags = list() // We'll use this to keep track of whether you can teleport/etc
// Map transition stuff
var/list/neighbors = list()
// # How this level connects with others. See __MAP_DEFINES.dm for defines
// It's UNAFFECTED by default because none of the space turfs are normally linked up
// so we don't need to rebuild transitions if an UNAFFECTED level is requested
var/linkage = UNAFFECTED
// # imaginary placements on the grid - these reflect the point it is linked to
var/xi
var/yi
var/list/transit_north = list()
var/list/transit_south = list()
var/list/transit_east = list()
var/list/transit_west = list()
// Init deferral stuff
var/dirt_count = 0
var/list/init_list = list()
/datum/space_level/New(z, name, transition_type = SELFLOOPING, traits = list(BLOCK_TELEPORT))
zpos = z
flags = traits
build_space_destination_arrays()
set_linkage(transition_type)
/datum/space_level/Destroy()
if(linkage == CROSSLINKED)
if(space_manager.linkage_map)
remove_from_space_network(space_manager.linkage_map)
space_manager.unbuilt_space_transitions -= src
space_manager.z_list -= "[zpos]"
return ..()
/datum/space_level/proc/build_space_destination_arrays()
// We skip `add_to_transit` here because we want to skip the checks in order to save time
// Bottom border
for(var/turf/space/S in block(locate(1,1,zpos),locate(world.maxx,TRANSITION_BORDER_SOUTH,zpos)))
transit_south |= S
// Top border
for(var/turf/space/S in block(locate(1,world.maxy,zpos),locate(world.maxx,TRANSITION_BORDER_NORTH,zpos)))
transit_north |= S
// Left border
for(var/turf/space/S in block(locate(1,TRANSITION_BORDER_SOUTH + 1,zpos),locate(TRANSITION_BORDER_WEST,TRANSITION_BORDER_NORTH - 1,zpos)))
transit_west |= S
// Right border
for(var/turf/space/S in block(locate(TRANSITION_BORDER_EAST,TRANSITION_BORDER_SOUTH + 1,zpos),locate(world.maxx,TRANSITION_BORDER_NORTH - 1,zpos)))
transit_east |= S
/datum/space_level/proc/add_to_transit(turf/space/S)
if(S.y <= TRANSITION_BORDER_SOUTH)
transit_south |= S
return
// Top border
if(S.y >= TRANSITION_BORDER_NORTH)
transit_north |= S
return
// Left border
if(S.x <= TRANSITION_BORDER_WEST)
transit_west |= S
return
// Right border
if(S.x >= TRANSITION_BORDER_EAST)
transit_east |= S
/datum/space_level/proc/remove_from_transit(turf/space/S)
if(S.y <= TRANSITION_BORDER_SOUTH)
transit_south -= S
return
// Top border
if(S.y >= TRANSITION_BORDER_NORTH)
transit_north -= S
return
// Left border
if(S.x <= TRANSITION_BORDER_WEST)
transit_west -= S
return
// Right border
if(S.x >= TRANSITION_BORDER_EAST)
transit_east -= S
/datum/space_level/proc/apply_transition(turf/space/S)
if(src in space_manager.unbuilt_space_transitions)
return // Let the space manager handle this one
switch(linkage)
if(UNAFFECTED)
S.remove_transitions()
if(SELFLOOPING,CROSSLINKED)
var/datum/space_level/E = get_connection()
if(S in transit_north)
E = get_connection(Z_LEVEL_NORTH)
S.set_transition_north(E.zpos)
if(S in transit_south)
E = get_connection(Z_LEVEL_SOUTH)
S.set_transition_south(E.zpos)
if(S in transit_east)
E = get_connection(Z_LEVEL_EAST)
S.set_transition_east(E.zpos)
if(S in transit_west)
E = get_connection(Z_LEVEL_WEST)
S.set_transition_west(E.zpos)
/datum/space_level/proc/get_turfs()
return block(locate(1, 1, zpos), locate(world.maxx, world.maxy, zpos))
/datum/space_level/proc/set_linkage(transition_type)
if(linkage == transition_type)
return
// Remove ourselves from the linkage map if we were cross-linked
if(linkage == CROSSLINKED)
if(space_manager.linkage_map)
remove_from_space_network(space_manager.linkage_map)
space_manager.unbuilt_space_transitions |= src
linkage = transition_type
switch(transition_type)
if(UNAFFECTED)
reset_connections()
if(SELFLOOPING)
link_to_self() // `link_to_self` is defined in space_transitions.dm
/datum/space_level/proc/resume_init()
if(dirt_count > 0)
throw EXCEPTION("Init told to resume when z-level still dirty. Z level: '[zpos]'")
log_debug("Releasing freeze on z-level '[zpos]'!")
log_debug("Beginning initialization!")
var/list/our_atoms = init_list // OURS NOW!!! (Keeping this list to ourselves will prevent hijack)
init_list = list()
var/list/late_maps = list()
var/list/pipes = list()
var/list/cables = list()
var/watch = start_watch()
for(var/schmoo in our_atoms)
var/atom/movable/AM = schmoo
if(AM) // to catch stuff like the nuke disk that no longer exists
// This can mess with our state - we leave these for last
if(istype(AM, /obj/effect/landmark/map_loader))
late_maps.Add(AM)
continue
AM.initialize()
if(istype(AM, /obj/machinery/atmospherics))
pipes.Add(AM)
else if(istype(AM, /obj/structure/cable))
cables.Add(AM)
log_debug("Primary initialization finished in [stop_watch(watch)]s.")
our_atoms.Cut()
if(pipes.len)
do_pipes(pipes)
if(cables.len)
do_cables(cables)
if(late_maps.len)
do_late_maps(late_maps)
/datum/space_level/proc/do_pipes(list/pipes)
var/watch = start_watch()
log_debug("Building pipenets on z-level '[zpos]'!")
for(var/schmoo in pipes)
var/obj/machinery/atmospherics/machine = schmoo
if(machine)
machine.build_network()
pipes.Cut()
log_debug("Took [stop_watch(watch)]s")
/datum/space_level/proc/do_cables(list/cables)
var/watch = start_watch()
log_debug("Building powernets on z-level '[zpos]'!")
for(var/schmoo in cables)
var/obj/structure/cable/C = schmoo
if(C)
makepowernet_for(C)
cables.Cut()
log_debug("Took [stop_watch(watch)]s")
/datum/space_level/proc/do_late_maps(list/late_maps)
var/watch = start_watch()
log_debug("Loading map templates on z-level '[zpos]'!")
space_manager.add_dirt(zpos) // Let's not repeatedly resume init for each template
for(var/schmoo in late_maps)
var/obj/effect/landmark/map_loader/ML = schmoo
if(ML)
ML.initialize()
late_maps.Cut()
space_manager.remove_dirt(zpos)
log_debug("Took [stop_watch(watch)]s")