[MIRROR] Refactors Holodeck to Use Map Templates, Again! Black Magic OOM Crashing No Longer Included (#2957)

* Refactors Holodeck to Use Map Templates, Again! Black Magic OOM Crashing No Longer Included (#55645)

Refactors the holodeck to use map templates instead of copy_contents_to, which every maintainer seems to have complaints about.

Fixes #41485 because the matches become part of the spawned list created by ssatoms
Fixes #54789 because the holodeck area no longer has the NO_TELEPORT flag
Fixes #55676 because the map templates cant be changed midround unlike the program copies in the centcom z level
Fixes #49318 because the holodeck no longer creates new areas like the original did

This pr also changes initTemplateBounds to be a /datum/map_template proc instead of a parsed_map proc. This was mainly so I wouldn't have to duplicate vars between map_template and parsed_map. It's also nice because there's no longer a parsed_map proc inside the map_template file, especially when it didn't need to be a parsed_map proc.

The holodeck sims wont take up space in the centcom z level any more (which allows for more possible programs in the future), and map templates are more heavily tested. This is also a chance to future proof the holodeck against bugs. Holodeck also seems more responsive. This should allow for a second custom holodeck in some future ruin as well, although that of course will not be in play for the near future because of the offstation content ban. Also I documented the fuck out of the holodeck

* Refactors Holodeck to Use Map Templates, Again! Black Magic OOM Crashing No Longer Included

Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
This commit is contained in:
SkyratBot
2021-01-30 16:40:12 +00:00
committed by GitHub
co-authored by Kylerace
parent 81e1323a0f
commit 4dbe8a2659
40 changed files with 10042 additions and 7017 deletions
+28 -11
View File
@@ -8,6 +8,16 @@
var/keep_cached_map = FALSE
var/station_id = null // used to override the root id when generating
///if true, turfs loaded from this template are placed on top of the turfs already there, defaults to TRUE
var/should_place_on_top = TRUE
///if true, creates a list of all atoms created by this template loading, defaults to FALSE
var/returns_created_atoms = FALSE
///the list of atoms created by this template being loaded, only populated if returns_created_atoms is TRUE
var/list/created_atoms = list()
//make sure this list is accounted for/cleared if you request it from ssatoms!
/datum/map_template/New(path = null, rename = null, cache = FALSE)
if(path)
mappath = path
@@ -26,8 +36,10 @@
cached_map = parsed
return bounds
/datum/parsed_map/proc/initTemplateBounds(datum/map_template/template)
/datum/map_template/proc/initTemplateBounds(list/bounds)
if (!bounds) //something went wrong
stack_trace("[name] template failed to initialize correctly!")
return
var/list/obj/machinery/atmospherics/atmos_machines = list()
var/list/obj/structure/cable/cables = list()
@@ -65,14 +77,11 @@
// first or not. Its defined In Initialize yet its run first in templates
// BEFORE so... hummm
SSmapping.reg_in_areas_in_z(areas)
// We have to do this hack here because its the ONLY place we can get the
// meta data from the template so we can properly set up the area
SSnetworks.assign_areas_root_ids(areas, template)
// If the world is starting up stop here and the world will do the rest
SSnetworks.assign_areas_root_ids(areas, src)
if(!SSatoms.initialized)
return
SSatoms.InitializeAtoms(areas + turfs + atoms)
SSatoms.InitializeAtoms(areas + turfs + atoms, returns_created_atoms ? created_atoms : null)
// NOTE, now that Initialize and LateInitialize run correctly, do we really
// need these two below?
SSmachines.setup_template_powernets(cables)
@@ -101,7 +110,7 @@
var/y = round((world.maxy - height) * 0.5) + 1
var/datum/space_level/level = SSmapping.add_new_zlevel(name, list(ZTRAIT_AWAY = TRUE))
var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE)
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/list/bounds = parsed.bounds
if(!bounds)
return FALSE
@@ -109,7 +118,7 @@
repopulate_sorted_areas()
//initialize things that are normally initialized after map load
parsed.initTemplateBounds(src)
initTemplateBounds(bounds)
smooth_zlevel(world.maxz)
log_game("Z-level [name] loaded at [x],[y],[world.maxz]")
@@ -136,7 +145,12 @@
// ruins clogging up memory for the whole round.
var/datum/parsed_map/parsed = cached_map || new(file(mappath))
cached_map = keep_cached_map ? parsed : null
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE))
var/list/turf_blacklist = list()
update_blacklist(T, turf_blacklist)
parsed.turf_blacklist = turf_blacklist
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=should_place_on_top))
return
var/list/bounds = parsed.bounds
if(!bounds)
@@ -146,7 +160,7 @@
repopulate_sorted_areas()
//initialize things that are normally initialized after map load
parsed.initTemplateBounds(src)
initTemplateBounds(bounds)
log_game("[name] loaded at [T.x],[T.y],[T.z]")
return bounds
@@ -154,6 +168,9 @@
/datum/map_template/proc/post_load()
return
/datum/map_template/proc/update_blacklist(turf/T, list/input_blacklist)
return
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
var/turf/placement = T
if(centered)
+12
View File
@@ -22,6 +22,9 @@
/// Offset bounds. Same as parsed_bounds until load().
var/list/bounds
///any turf in this list is skipped inside of build_coordinate
var/list/turf_blacklist = list()
// raw strings used to represent regexes more accurately
// '' used to avoid confusing syntax highlighting
var/static/regex/dmmRegex = new(@'"([a-zA-Z]+)" = \(((?:.|\n)*?)\)\n(?!\t)|\((\d+),(\d+),(\d+)\) = \{"([a-zA-Z\n]*)"\}', "g")
@@ -304,6 +307,10 @@
//Instanciation
////////////////
for (var/turf_in_blacklist in turf_blacklist)
if (crds == turf_in_blacklist) //if the given turf is blacklisted, dont do anything with it
return
//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
@@ -474,4 +481,9 @@
/datum/parsed_map/Destroy()
..()
turf_blacklist.Cut()
parsed_bounds.Cut()
bounds.Cut()
grid_models.Cut()
gridSets.Cut()
return QDEL_HINT_HARDDEL_NOW