mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 01:49:19 +00:00
* okay * ok * ok * ok * ok * why am i doing this * WHY DID I DO THIS * mirror doesn't work * compile * shuttles should work * fix engine * fix engine * off by 1 * ok * adds proccall to write next map * haha post processing funny * fixes * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> * Update code/modules/mapping/map_template.dm Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com> Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
212 lines
8.5 KiB
Plaintext
212 lines
8.5 KiB
Plaintext
/datum/map_template
|
|
var/name = "Default Template Name"
|
|
var/width = 0 //all these are for SOUTH!
|
|
var/height = 0
|
|
var/zdepth = 1
|
|
var/mappath
|
|
var/loaded = 0 // Times loaded this round
|
|
var/datum/parsed_map/cached_map
|
|
var/keep_cached_map = FALSE
|
|
var/default_annihilate = FALSE
|
|
var/list/ztraits //zlevel traits for load_new_z
|
|
|
|
/datum/map_template/New(path = null, rename = null, cache = FALSE)
|
|
if(path)
|
|
mappath = path
|
|
if(mappath)
|
|
preload_size(mappath, cache)
|
|
if(rename)
|
|
name = rename
|
|
|
|
/datum/map_template/Destroy()
|
|
QDEL_NULL(cached_map)
|
|
return ..()
|
|
|
|
/datum/map_template/proc/preload_size(path = mappath, force_cache = FALSE)
|
|
if(cached_map)
|
|
return cached_map.parsed_bounds
|
|
var/datum/parsed_map/parsed = new(file(path))
|
|
var/bounds = parsed?.parsed_bounds
|
|
if(bounds)
|
|
width = bounds[MAP_MAXX] - bounds[MAP_MINX] + 1
|
|
height = bounds[MAP_MAXY] - bounds[MAP_MINY] + 1
|
|
zdepth = bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
|
|
if(force_cache || keep_cached_map)
|
|
cached_map = parsed
|
|
return bounds
|
|
|
|
/datum/map_template/proc/get_parsed_bounds()
|
|
return preload_size(mappath)
|
|
|
|
/datum/map_template/proc/get_last_loaded_bounds()
|
|
if(cached_map)
|
|
return cached_map.bounds
|
|
return get_parsed_bounds()
|
|
|
|
/datum/map_template/proc/get_last_loaded_turf_block()
|
|
if(!cached_map)
|
|
CRASH("Improper use of get_last_loaded_turf_block, no cached_map.")
|
|
var/list/B = cached_map.bounds
|
|
return block(locate(B[MAP_MINX], B[MAP_MINY], B[MAP_MINZ]), locate(B[MAP_MAXX], B[MAP_MAXY], B[MAP_MAXZ]))
|
|
|
|
/datum/map_template/proc/get_size(orientation = SOUTH)
|
|
if(!width || !height || !zdepth)
|
|
preload_size(mappath)
|
|
var/rotate = (orientation & (NORTH|SOUTH)) != NONE
|
|
if(rotate)
|
|
return list(height, width, zdepth)
|
|
return list(width, height, zdepth)
|
|
|
|
/datum/parsed_map/proc/initTemplateBounds()
|
|
var/list/obj/machinery/atmospherics/atmos_machines = list()
|
|
var/list/obj/structure/cable/cables = list()
|
|
var/list/atom/atoms = list()
|
|
var/list/area/areas = list()
|
|
|
|
var/list/turfs = block( locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]),
|
|
locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))
|
|
var/list/border = block(locate(max(bounds[MAP_MINX]-1, 1), max(bounds[MAP_MINY]-1, 1), bounds[MAP_MINZ]),
|
|
locate(min(bounds[MAP_MAXX]+1, world.maxx), min(bounds[MAP_MAXY]+1, world.maxy), bounds[MAP_MAXZ])) - turfs
|
|
for(var/L in turfs)
|
|
var/turf/B = L
|
|
atoms += B
|
|
areas |= B.loc
|
|
for(var/A in B)
|
|
atoms += A
|
|
if(istype(A, /obj/structure/cable))
|
|
cables += A
|
|
continue
|
|
if(istype(A, /obj/machinery/atmospherics))
|
|
atmos_machines += A
|
|
for(var/L in border)
|
|
var/turf/T = L
|
|
T.air_update_turf(TRUE) //calculate adjacent turfs along the border to prevent runtimes
|
|
|
|
SSmapping.reg_in_areas_in_z(areas)
|
|
SSatoms.InitializeAtoms(atoms)
|
|
SSmachines.setup_template_powernets(cables)
|
|
SSair.setup_template_machinery(atmos_machines)
|
|
|
|
/datum/map_template/proc/load_new_z(orientation = SOUTH, list/ztraits = src.ztraits || list(ZTRAIT_AWAY = TRUE), centered = TRUE)
|
|
var/x = centered? max(round((world.maxx - width) / 2), 1) : 1
|
|
var/y = centered? max(round((world.maxy - height) / 2), 1) : 1
|
|
|
|
var/datum/space_level/level = SSmapping.add_new_zlevel(name, ztraits)
|
|
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop = TRUE, orientation = orientation)
|
|
var/list/bounds = parsed.bounds
|
|
if(!bounds)
|
|
return FALSE
|
|
|
|
repopulate_sorted_areas()
|
|
|
|
//initialize things that are normally initialized after map load
|
|
parsed.initTemplateBounds()
|
|
smooth_zlevel(world.maxz)
|
|
log_game("Z-level [name] loaded at [x],[y],[world.maxz]")
|
|
on_map_loaded(world.maxz, parsed.bounds)
|
|
|
|
return level
|
|
|
|
//Override for custom behavior
|
|
/datum/map_template/proc/on_map_loaded(z, list/bounds)
|
|
loaded++
|
|
|
|
/**
|
|
* Proc to trigger a load at a specific area. Calls on_map_loaded(T.z, loaded_bounds) afterwards.
|
|
*
|
|
* @params
|
|
* * turf/T - Turf to load at
|
|
* * centered - Center at T or load with the bottomright corner being at T
|
|
* * orientation - SOUTH is default, anything else rotates the map to face it with the point of reference being the map itself is facing south by default. Cardinals only, don't be a 4head and put in multiple flags. It won't work or be pretty if you try.
|
|
* * annihilate - Should we destroy stuff in our bounds while loading
|
|
* * force_cache - Should we force the parsed shuttle to cache instead of being GC'd post loading if it wasn't going to be cached by default
|
|
* * rotate_placement_to_orientation - Has no effect if centered. Should we rotate where we load it around the turf we're loading at? Used for stuff like engine submaps when the station is rotated.
|
|
*
|
|
*/
|
|
/datum/map_template/proc/load(turf/T, centered = FALSE, orientation = SOUTH, annihilate = default_annihilate, force_cache = FALSE, rotate_placement_to_orientation = FALSE)
|
|
var/old_T = T
|
|
if(centered)
|
|
T = locate(T.x - round(((orientation & (NORTH|SOUTH))? width : height) / 2) , T.y - round(((orientation & (NORTH|SOUTH)) ? height : width) / 2) , T.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false
|
|
else if(rotate_placement_to_orientation && (orientation != SOUTH))
|
|
var/newx = T.x
|
|
var/newy = T.y
|
|
if(orientation == NORTH)
|
|
newx -= width
|
|
newy -= height - 1
|
|
else if(orientation == WEST)
|
|
newy -= width
|
|
else if(orientation == EAST)
|
|
newx -= height - 1
|
|
// eh let's not silently fail.
|
|
if(!ISINRANGE(newx, 1, world.maxx) || !ISINRANGE(newy, 1, world.maxy))
|
|
stack_trace("Warning: Rotation placed a map template load spot ([COORD(T)]) out of bounds of the game world. Clamping to world borders, this might cause issues.")
|
|
T = locate(clamp(newx, 1, world.maxx), clamp(newy, 1, world.maxy), T.z)
|
|
if(!T)
|
|
return
|
|
if(T.x+width-1 > world.maxx)
|
|
return
|
|
if(T.y+height-1 > world.maxy)
|
|
return
|
|
|
|
var/list/border = block(locate(max(T.x - 1, 1), max(T.y - 1, 1), T.z),
|
|
locate(min(T.x + width + 1, world.maxx), min(T.y + height + 1, world.maxy), T.z))
|
|
for(var/i in border)
|
|
var/turf/turf_to_disable = i
|
|
SSair.remove_from_active(turf_to_disable) //stop processing turfs along the border to prevent runtimes, we return it in initTemplateBounds()
|
|
turf_to_disable.atmos_adjacent_turfs?.Cut()
|
|
|
|
if(annihilate == MAP_TEMPLATE_ANNIHILATE_PRELOAD)
|
|
annihilate_bounds(old_T, centered, orientation)
|
|
|
|
// Accept cached maps, but don't save them automatically - we don't want
|
|
// ruins clogging up memory for the whole round.
|
|
var/is_cached = cached_map
|
|
var/datum/parsed_map/parsed = is_cached || new(file(mappath))
|
|
cached_map = (force_cache || keep_cached_map) ? parsed : is_cached
|
|
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE, orientation = orientation, annihilate_tiles = (annihilate == MAP_TEMPLATE_ANNIHILATE_LOADING)))
|
|
return
|
|
var/list/bounds = parsed.bounds
|
|
if(!bounds)
|
|
return
|
|
|
|
if(!SSmapping.loading_ruins) //Will be done manually during mapping ss init
|
|
repopulate_sorted_areas()
|
|
|
|
//initialize things that are normally initialized after map load
|
|
parsed.initTemplateBounds()
|
|
|
|
log_game("[name] loaded at [T.x],[T.y],[T.z]")
|
|
on_map_loaded(T.z, parsed.bounds)
|
|
|
|
return bounds
|
|
|
|
//This, get_affected_turfs, and load() calculations for bounds/center can probably be optimized. Later.
|
|
/datum/map_template/proc/annihilate_bounds(turf/origin, centered = FALSE, orientation = SOUTH)
|
|
var/deleted_atoms = 0
|
|
log_world("Annihilating objects in map loading location.")
|
|
var/list/turfs_to_clean = get_affected_turfs(origin, centered, orientation)
|
|
if(turfs_to_clean.len)
|
|
var/list/kill_these = list()
|
|
for(var/i in turfs_to_clean)
|
|
var/turf/T = i
|
|
kill_these += T.contents
|
|
for(var/i in kill_these)
|
|
qdel(i)
|
|
CHECK_TICK
|
|
deleted_atoms++
|
|
log_world("Annihilated [deleted_atoms] objects.")
|
|
|
|
//for your ever biggening badminnery kevinz000
|
|
//❤ - Cyberboss
|
|
/proc/load_new_z_level(file, name, orientation, list/ztraits)
|
|
var/datum/map_template/template = new(file, name)
|
|
return template.load_new_z(orientation, ztraits)
|
|
|
|
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE, orientation = SOUTH)
|
|
var/turf/placement = T
|
|
if(centered)
|
|
var/turf/corner = locate(placement.x - round(((orientation & (NORTH|SOUTH))? width : height) / 2), placement.y - round(((orientation & (NORTH|SOUTH))? height : width) / 2), placement.z) // %180 catches East/West (90,270) rotations on true, North/South (0,180) rotations on false
|
|
if(corner)
|
|
placement = corner
|
|
return block(placement, locate(placement.x + ((orientation & (NORTH|SOUTH)) ? width : height) - 1, placement.y + ((orientation & (NORTH|SOUTH))? height : width) - 1, placement.z))
|