Files
GS13NG/code/game/turfs/ChangeTurf.dm
Jordan Brown 829cf4d180 Merge pull request #34623 from ninjanomnom/template-placeontop
Makes templates able to use PlaceOnTop
2018-01-24 18:18:31 -06:00

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