274 lines
8.9 KiB
Plaintext
274 lines
8.9 KiB
Plaintext
// This is a list of turf types we dont want to assign to baseturfs unless through initialization or explicitly
|
|
GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
|
|
/turf/open/space,
|
|
)))
|
|
|
|
/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, flags)
|
|
// Remove all atoms except observers, landmarks, docking ports
|
|
var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark, /obj/docking_port, /atom/movable/lighting_object))
|
|
var/list/allowed_contents = typecache_filter_list_reverse(GetAllContentsIgnoring(ignore_typecache), ignored_atoms)
|
|
allowed_contents -= src
|
|
for(var/i in 1 to allowed_contents.len)
|
|
var/thing = allowed_contents[i]
|
|
qdel(thing, force=TRUE)
|
|
|
|
var/turf/newT = ChangeTurf(turf_type, baseturf_type, flags)
|
|
|
|
SSair.remove_from_active(newT)
|
|
newT.CalculateAdjacentTurfs()
|
|
SSair.add_to_active(newT,1)
|
|
|
|
/turf/proc/copyTurf(turf/T)
|
|
if(T.type != type)
|
|
var/obj/O
|
|
if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay
|
|
O = new()
|
|
O.underlays.Add(T)
|
|
T.ChangeTurf(type)
|
|
for(var/group in decals)
|
|
T.add_decal(decals[group],group)
|
|
if(underlays.len)
|
|
T.underlays = O.underlays
|
|
if(T.icon_state != icon_state)
|
|
T.icon_state = icon_state
|
|
if(T.icon != icon)
|
|
T.icon = icon
|
|
if(color)
|
|
T.atom_colours = atom_colours.Copy()
|
|
T.update_atom_colour()
|
|
if(T.dir != dir)
|
|
T.setDir(dir)
|
|
return T
|
|
|
|
//wrapper for ChangeTurf()s that you want to prevent/affect without overriding ChangeTurf() itself
|
|
/turf/proc/TerraformTurf(path, new_baseturf, flags)
|
|
return ChangeTurf(path, new_baseturf, flags)
|
|
|
|
// Creates a new turf
|
|
// new_baseturfs can be either a single type or list of types, formated the same as baseturfs. see turf.dm
|
|
/turf/proc/ChangeTurf(path, list/new_baseturfs, flags)
|
|
if(!path)
|
|
return
|
|
if(path == /turf/open/space/basic)
|
|
// basic doesn't initialize and this will cause issues
|
|
// no warning though because this can happen naturaly as a result of it being built on top of
|
|
path = /turf/open/space
|
|
if(!GLOB.use_preloader && path == type && !(flags & CHANGETURF_FORCEOP)) // Don't no-op if the map loader requires it to be reconstructed
|
|
return src
|
|
if(flags & CHANGETURF_SKIP)
|
|
return new path(src)
|
|
|
|
var/old_opacity = opacity
|
|
var/old_dynamic_lighting = dynamic_lighting
|
|
var/old_affecting_lights = affecting_lights
|
|
var/old_lighting_object = lighting_object
|
|
var/old_corners = corners
|
|
|
|
var/old_exl = explosion_level
|
|
var/old_exi = explosion_id
|
|
var/old_bp = blueprint_data
|
|
blueprint_data = null
|
|
|
|
var/list/old_baseturfs = baseturfs
|
|
changing_turf = TRUE
|
|
|
|
qdel(src) //Just get the side effects and call Destroy
|
|
var/turf/W = new path(src)
|
|
|
|
if(new_baseturfs)
|
|
W.baseturfs = new_baseturfs
|
|
else
|
|
W.baseturfs = old_baseturfs
|
|
|
|
W.explosion_id = old_exi
|
|
W.explosion_level = old_exl
|
|
|
|
if(!(flags & CHANGETURF_DEFER_CHANGE))
|
|
W.AfterChange(flags)
|
|
|
|
W.blueprint_data = old_bp
|
|
|
|
if(SSlighting.initialized)
|
|
recalc_atom_opacity()
|
|
lighting_object = old_lighting_object
|
|
affecting_lights = old_affecting_lights
|
|
corners = old_corners
|
|
if (old_opacity != opacity || dynamic_lighting != old_dynamic_lighting)
|
|
reconsider_lights()
|
|
|
|
if (dynamic_lighting != old_dynamic_lighting)
|
|
if (IS_DYNAMIC_LIGHTING(src))
|
|
lighting_build_overlay()
|
|
else
|
|
lighting_clear_overlay()
|
|
|
|
for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
|
|
S.update_starlight()
|
|
|
|
return W
|
|
|
|
// Take off the top layer turf and replace it with the next baseturf down
|
|
/turf/proc/ScrapeAway()
|
|
if(length(baseturfs))
|
|
var/list/new_baseturfs = baseturfs
|
|
var/turf_type = new_baseturfs[new_baseturfs.len]
|
|
new_baseturfs.len--
|
|
switch(new_baseturfs.len)
|
|
if(1)
|
|
new_baseturfs = new_baseturfs[1]
|
|
if(0)
|
|
new_baseturfs = turf_type
|
|
// We must never end up with a situation where there is no baseturf
|
|
WARNING("turf of type [type] had a baseturfs length 1 still in list form.")
|
|
return ChangeTurf(turf_type, new_baseturfs)
|
|
|
|
if(baseturfs == type)
|
|
return src
|
|
|
|
return ChangeTurf(baseturfs, baseturfs) // The bottom baseturf will never go away
|
|
|
|
// Take the input as baseturfs and put it underneath the current baseturfs
|
|
// If fake_turf_type is provided and new_baseturfs is not the baseturfs list will be created identical to the turf type's
|
|
// If both or just new_baseturfs is provided they will be inserted below the existing baseturfs
|
|
/turf/proc/PlaceOnBottom(list/new_baseturfs, turf/fake_turf_type)
|
|
if(fake_turf_type)
|
|
if(!new_baseturfs)
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
var/list/old_baseturfs = baseturfs.Copy()
|
|
assemble_baseturfs(fake_turf_type)
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
baseturfs -= baseturfs & GLOB.blacklisted_automated_baseturfs
|
|
baseturfs += old_baseturfs
|
|
return
|
|
else if(!length(new_baseturfs))
|
|
new_baseturfs = list(new_baseturfs, fake_turf_type)
|
|
else
|
|
new_baseturfs += fake_turf_type
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
baseturfs.Insert(1, new_baseturfs)
|
|
|
|
// Make a new turf and put it on top
|
|
// The args behave identical to PlaceOnBottom except they go on top
|
|
// Things placed on top of closed turfs will ignore the topmost closed turf
|
|
// Returns the new turf
|
|
/turf/proc/PlaceOnTop(list/new_baseturfs, turf/fake_turf_type, flags)
|
|
var/turf/newT
|
|
if(flags & CHANGETURF_SKIP) // We haven't been initialized
|
|
if(initialized)
|
|
stack_trace("CHANGETURF_SKIP was used in a PlaceOnTop call for a turf that's initialized. This is a mistake. [src]([type])")
|
|
assemble_baseturfs()
|
|
if(fake_turf_type)
|
|
if(!new_baseturfs) // If no baseturfs list then we want to create one from the turf type
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
var/list/old_baseturfs = baseturfs.Copy()
|
|
if(!istype(src, /turf/closed))
|
|
old_baseturfs += type
|
|
newT = ChangeTurf(fake_turf_type, null, flags)
|
|
newT.assemble_baseturfs(initial(fake_turf_type.baseturfs)) // The baseturfs list is created like roundstart
|
|
if(!length(newT.baseturfs))
|
|
newT.baseturfs = list(baseturfs)
|
|
newT.baseturfs -= newT.baseturfs & GLOB.blacklisted_automated_baseturfs
|
|
newT.baseturfs.Insert(1, old_baseturfs) // The old baseturfs are put underneath
|
|
return newT
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
if(!istype(src, /turf/closed))
|
|
baseturfs += type
|
|
baseturfs += new_baseturfs
|
|
return ChangeTurf(fake_turf_type, null, flags)
|
|
if(!length(baseturfs))
|
|
baseturfs = list(baseturfs)
|
|
if(!istype(src, /turf/closed))
|
|
baseturfs += type
|
|
var/turf/change_type
|
|
if(length(new_baseturfs))
|
|
change_type = new_baseturfs[new_baseturfs.len]
|
|
new_baseturfs.len--
|
|
if(new_baseturfs.len)
|
|
baseturfs += new_baseturfs
|
|
else
|
|
change_type = new_baseturfs
|
|
return ChangeTurf(change_type, null, flags)
|
|
|
|
// Copy an existing turf and put it on top
|
|
// Returns the new turf
|
|
/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY)
|
|
var/list/new_baseturfs = list()
|
|
new_baseturfs += baseturfs
|
|
new_baseturfs += type
|
|
|
|
if(depth)
|
|
var/list/target_baseturfs = copytarget.baseturfs
|
|
target_baseturfs -= target_baseturfs & GLOB.blacklisted_automated_baseturfs
|
|
var/base_len = length(target_baseturfs)
|
|
if(!base_len)
|
|
if(!ignore_bottom)
|
|
new_baseturfs += target_baseturfs
|
|
else if(base_len > ignore_bottom)
|
|
if(base_len - ignore_bottom <= depth)
|
|
new_baseturfs += target_baseturfs.Copy(ignore_bottom + 1)
|
|
else
|
|
new_baseturfs += target_baseturfs.Copy(base_len - depth)
|
|
|
|
var/turf/newT = copytarget.copyTurf(src)
|
|
newT.baseturfs = new_baseturfs
|
|
return newT
|
|
|
|
|
|
//If you modify this function, ensure it works correctly with lateloaded map templates.
|
|
/turf/proc/AfterChange(flags) //called after a turf has been replaced in ChangeTurf()
|
|
levelupdate()
|
|
CalculateAdjacentTurfs()
|
|
|
|
//update firedoor adjacency
|
|
var/list/turfs_to_check = get_adjacent_open_turfs(src) | src
|
|
for(var/I in turfs_to_check)
|
|
var/turf/T = I
|
|
for(var/obj/machinery/door/firedoor/FD in T)
|
|
FD.CalculateAffectingAreas()
|
|
|
|
queue_smooth_neighbors(src)
|
|
|
|
HandleTurfChange(src)
|
|
|
|
/turf/open/AfterChange(flags)
|
|
..()
|
|
RemoveLattice()
|
|
if(!(flags & CHANGETURF_IGNORE_AIR))
|
|
Assimilate_Air()
|
|
|
|
//////Assimilate Air//////
|
|
/turf/open/proc/Assimilate_Air()
|
|
var/turf_count = LAZYLEN(atmos_adjacent_turfs)
|
|
if(blocks_air || !turf_count) //if there weren't any open turfs, no need to update.
|
|
return
|
|
|
|
var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs
|
|
var/list/total_gases = total.gases
|
|
|
|
for(var/T in atmos_adjacent_turfs)
|
|
var/turf/open/S = T
|
|
if(!S.air)
|
|
continue
|
|
var/list/S_gases = S.air.gases
|
|
for(var/id in S_gases)
|
|
ASSERT_GAS(id, total)
|
|
total_gases[id][MOLES] += S_gases[id][MOLES]
|
|
total.temperature += S.air.temperature
|
|
|
|
air.copy_from(total)
|
|
|
|
var/list/air_gases = air.gases
|
|
for(var/id in air_gases)
|
|
air_gases[id][MOLES] /= turf_count //Averages contents of the turfs, ignoring walls and the like
|
|
|
|
air.temperature /= turf_count
|
|
SSair.add_to_active(src)
|
|
|
|
/turf/proc/ReplaceWithLattice()
|
|
ScrapeAway()
|
|
new /obj/structure/lattice(locate(x, y, z)) |