Refactor dmm_suite for readability

Clean up arguments, comments and paths of
/dmm_suite (now /datum/dmm_suite) to
increase readability should other developers
want to take a look at it
This commit is contained in:
mochi
2020-06-19 12:04:55 +02:00
parent ab957a66ea
commit a640335c29
4 changed files with 236 additions and 241 deletions

View File

@@ -17,7 +17,7 @@
name = rename name = rename
/datum/map_template/proc/preload_size(path) /datum/map_template/proc/preload_size(path)
var/bounds = GLOB.maploader.load_map(file(path), 1, 1, 1, cropMap = 0, measureOnly = 1) var/bounds = GLOB.maploader.load_map(file(path), 1, 1, 1, shouldCropMap = FALSE, measureOnly = TRUE)
if(bounds) if(bounds)
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
height = bounds[MAP_MAXY] height = bounds[MAP_MAXY]
@@ -49,7 +49,7 @@
// if given a multi-z template // if given a multi-z template
// it might need to be adapted for that when that time comes // it might need to be adapted for that when that time comes
GLOB.space_manager.add_dirt(placement.z) GLOB.space_manager.add_dirt(placement.z)
var/list/bounds = GLOB.maploader.load_map(get_file(), min_x, min_y, placement.z, cropMap = 1) var/list/bounds = GLOB.maploader.load_map(get_file(), min_x, min_y, placement.z, shouldCropMap = TRUE)
if(!bounds) if(!bounds)
return 0 return 0
if(bot_left == null || top_right == null) if(bot_left == null || top_right == null)

View File

@@ -1,5 +1,3 @@
GLOBAL_DATUM_INIT(maploader, /dmm_suite, new())
dmm_suite{
/* /*
dmm_suite version 1.0 dmm_suite version 1.0
@@ -52,21 +50,7 @@ dmm_suite{
*/ */
verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, do_sleep as num){ GLOBAL_DATUM_INIT(maploader, /datum/dmm_suite, new())
// dmm_file: A .dmm file to load (Required).
// z_offset: A number representing the z-level on which to start loading the map (Optional).
}
verb/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num){
// t1: A turf representing one corner of a three dimensional grid (Required).
// t2: Another turf representing the other corner of the same grid (Required).
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
}
// save_map is included as a legacy proc. Use write_map instead. /datum/dmm_suite
verb/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num){ var/static/quote = "\""
// t1: A turf representing one corner of a three dimensional grid (Required).
// t2: Another turf representing the other corner of the same grid (Required).
// map_name: A valid name for the map to be saved, such as "castle" (Required).
// flags: Any, or a combination, of several bit flags (Optional, see documentation).
}
}

View File

@@ -5,9 +5,9 @@
// As of 3.6.2016 // As of 3.6.2016
// global datum that will preload variables on atoms instanciation // global datum that will preload variables on atoms instanciation
GLOBAL_VAR_INIT(use_preloader, FALSE) GLOBAL_VAR_INIT(use_preloader, FALSE)
GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new()) GLOBAL_DATUM_INIT(_preloader, /datum/dmm_suite/preloader, new())
/dmm_suite /datum/dmm_suite
// These regexes are global - meaning that starting the maploader again mid-load will // These regexes are global - meaning that starting the maploader again mid-load will
// reset progress - which means we need to track our index per-map, or we'll // reset progress - which means we need to track our index per-map, or we'll
// eternally recurse // eternally recurse
@@ -37,13 +37,13 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
* atmos will attempt to start before it's ready, causing runtimes galore if init is * atmos will attempt to start before it's ready, causing runtimes galore if init is
* allowed to romp unchecked. * allowed to romp unchecked.
*/ */
/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num) /datum/dmm_suite/proc/load_map(dmm_file, x_offset = 0, y_offset = 0, z_offset = 0, shouldCropMap = FALSE, measureOnly = FALSE)
var/tfile = dmm_file// the map file we're creating var/tfile = dmm_file// the map file we're creating
var/fname = "Lambda" var/fname = "Lambda"
if(isfile(tfile)) if(isfile(tfile))
fname = "[tfile]" fname = "[tfile]"
tfile = file2text(tfile) tfile = file2text(tfile)
if(length(tfile) == 0) if(!length(tfile))
throw EXCEPTION("Map path '[fname]' does not exist!") throw EXCEPTION("Map path '[fname]' does not exist!")
if(!x_offset) if(!x_offset)
@@ -57,7 +57,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
var/list/grid_models = list() var/list/grid_models = list()
var/key_len = 0 var/key_len = 0
var/dmm_suite/loaded_map/LM = new var/datum/dmm_suite/loaded_map/LM = new
// This try-catch is used as a budget "Finally" clause, as the dirt count // This try-catch is used as a budget "Finally" clause, as the dirt count
// needs to be reset // needs to be reset
var/watch = start_watch() var/watch = start_watch()
@@ -76,7 +76,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
if(!key_len) if(!key_len)
key_len = length(key) key_len = length(key)
else else
throw EXCEPTION("Inconsistant key length in DMM") throw EXCEPTION("Inconsistent key length in DMM")
if(!measureOnly) if(!measureOnly)
grid_models[key] = dmmRegex.group[2] grid_models[key] = dmmRegex.group[2]
@@ -93,7 +93,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
if(!measureOnly) if(!measureOnly)
if(zcrd > world.maxz) if(zcrd > world.maxz)
if(cropMap) if(shouldCropMap)
continue continue
else else
GLOB.space_manager.increase_max_zlevel_to(zcrd) // create a new z_level if needed GLOB.space_manager.increase_max_zlevel_to(zcrd) // create a new z_level if needed
@@ -118,7 +118,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd) bounds[MAP_MINY] = min(bounds[MAP_MINY], ycrd)
ycrd += gridLines.len - 1 // Start at the top and work down ycrd += gridLines.len - 1 // Start at the top and work down
if(!cropMap && ycrd > world.maxy) if(!shouldCropMap && ycrd > world.maxy)
if(!measureOnly) if(!measureOnly)
world.maxy = ycrd // Expand Y here. X is expanded in the loop below world.maxy = ycrd // Expand Y here. X is expanded in the loop below
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd) bounds[MAP_MAXY] = max(bounds[MAP_MAXY], ycrd)
@@ -133,9 +133,9 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
for(var/line in gridLines) for(var/line in gridLines)
if(ycrd <= world.maxy && ycrd >= 1) if(ycrd <= world.maxy && ycrd >= 1)
xcrd = xcrdStart xcrd = xcrdStart
for(var/tpos = 1 to length(line) - key_len + 1 step key_len) for(var/tpos = 1 to (length(line) - key_len + 1) step key_len)
if(xcrd > world.maxx) if(xcrd > world.maxx)
if(cropMap) if(shouldCropMap)
break break
else else
world.maxx = xcrd world.maxx = xcrd
@@ -152,7 +152,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
maxx = max(maxx, xcrd) maxx = max(maxx, xcrd)
++xcrd ++xcrd
--ycrd --ycrd
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], cropMap ? min(maxx, world.maxx) : maxx) bounds[MAP_MAXX] = max(bounds[MAP_MAXX], shouldCropMap ? min(maxx, world.maxx) : maxx)
CHECK_TICK CHECK_TICK
catch(var/exception/e) catch(var/exception/e)
@@ -176,7 +176,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ]))) for(var/t in block(locate(bounds[MAP_MINX], bounds[MAP_MINY], bounds[MAP_MINZ]), locate(bounds[MAP_MAXX], bounds[MAP_MAXY], bounds[MAP_MAXZ])))
var/turf/T = t var/turf/T = t
// we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs // we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
T.AfterChange(1, keep_cabling = TRUE) T.AfterChange(TRUE, keep_cabling = TRUE)
return bounds return bounds
/** /**
@@ -196,7 +196,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
* 4) Instanciates the atom with its variables * 4) Instanciates the atom with its variables
* *
*/ */
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num, dmm_suite/loaded_map/LM) /datum/dmm_suite/proc/parse_grid(model = "", xcrd = 0, ycrd = 0, zcrd = 0, datum/dmm_suite/loaded_map/LM)
/*Method parse_grid() /*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the - Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them. same construction as those contained in a .dmm file, and instantiates them.
@@ -270,9 +270,8 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
if(!ispath(members[index], /area)) if(!ispath(members[index], /area))
throw EXCEPTION("Oh no, I thought this was an area!") throw EXCEPTION("Oh no, I thought this was an area!")
var/atom/instance
GLOB._preloader.setup(members_attributes[index]) // preloader for assigning set variables on atom creation GLOB._preloader.setup(members_attributes[index]) // preloader for assigning set variables on atom creation
instance = LM.area_path_to_real_area(members[index]) var/atom/instance = LM.area_path_to_real_area(members[index])
if(crds) if(crds)
instance.contents.Add(crds) instance.contents.Add(crds)
@@ -314,7 +313,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
//////////////// ////////////////
// Instance an atom at (x, y, z) and gives it the variables in attributes // Instance an atom at (x, y, z) and gives it the variables in attributes
/dmm_suite/proc/instance_atom(path,list/attributes, x, y, z) /datum/dmm_suite/proc/instance_atom(path, list/attributes, x = 0, y = 0, z = 0)
var/atom/instance var/atom/instance
GLOB._preloader.setup(attributes, path) GLOB._preloader.setup(attributes, path)
@@ -335,16 +334,15 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
// text trimming (both directions) helper proc // text trimming (both directions) helper proc
// optionally removes quotes before and after the text (for variable name) // optionally removes quotes before and after the text (for variable name)
/dmm_suite/proc/trim_text(what as text,trim_quotes=0) /datum/dmm_suite/proc/trim_text(what = "", trim_quotes = FALSE)
if(trim_quotes) if(trim_quotes)
return trimQuotesRegex.Replace(what, "") return trimQuotesRegex.Replace(what, "")
else else
return trimRegex.Replace(what, "") return trimRegex.Replace(what, "")
// find the position of the next delimiter, skipping whatever is comprised between opening_escape and closing_escape // find the position of the next delimiter, skipping whatever is comprised between opening_escape and closing_escape
// returns 0 if reached the last delimiter // returns 0 if reached the last delimiter
/dmm_suite/proc/find_next_delimiter_position(text as text,initial_position as num, delimiter=",",opening_escape=quote,closing_escape=quote) /datum/dmm_suite/proc/find_next_delimiter_position(text = "", initial_position = 0, delimiter = ",", opening_escape = quote, closing_escape = quote)
var/position = initial_position var/position = initial_position
var/next_delimiter = findtext(text, delimiter, position, 0) var/next_delimiter = findtext(text, delimiter, position, 0)
var/next_opening = findtext(text, opening_escape, position, 0) var/next_opening = findtext(text, opening_escape, position, 0)
@@ -356,11 +354,9 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
return next_delimiter return next_delimiter
// build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7)) // build a list from variables in text form (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
// return the filled list // return the filled list
/dmm_suite/proc/readlist(text as text, delimiter=",") /datum/dmm_suite/proc/readlist(text = "", delimiter = ",")
var/list/to_return = list() var/list/to_return = list()
var/position var/position
@@ -419,7 +415,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
return to_return return to_return
/dmm_suite/Destroy() /datum/dmm_suite/Destroy()
..() ..()
return QDEL_HINT_HARDDEL_NOW return QDEL_HINT_HARDDEL_NOW
@@ -428,13 +424,13 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
////////////////// //////////////////
// This ain't re-entrant, but we had this before the maploader update // This ain't re-entrant, but we had this before the maploader update
/dmm_suite/preloader /datum/dmm_suite/preloader
parent_type = /datum parent_type = /datum
var/list/attributes var/list/attributes
var/target_path var/target_path
var/json_ready = 0 var/json_ready = 0
/dmm_suite/preloader/proc/setup(list/the_attributes, path) /datum/dmm_suite/preloader/proc/setup(list/the_attributes, path)
if(the_attributes.len) if(the_attributes.len)
json_ready = 0 json_ready = 0
if("map_json_data" in the_attributes) if("map_json_data" in the_attributes)
@@ -443,25 +439,24 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
attributes = the_attributes attributes = the_attributes
target_path = path target_path = path
/dmm_suite/preloader/proc/load(atom/what) /datum/dmm_suite/preloader/proc/load(atom/A)
if(json_ready) if(json_ready)
var/json_data = attributes["map_json_data"] var/json_data = dmm_decode(attributes["map_json_data"])
attributes -= "map_json_data" attributes -= "map_json_data"
json_data = dmm_decode(json_data)
try try
what.deserialize(json_decode(json_data)) A.deserialize(json_decode(json_data))
catch(var/exception/e) catch(var/exception/E)
log_runtime(EXCEPTION("Bad json data: '[json_data]'"), src) log_runtime(EXCEPTION("Bad json data: '[json_data]'"), src)
throw e throw E
for(var/attribute in attributes) for(var/attribute in attributes)
var/value = attributes[attribute] var/value = attributes[attribute]
if(islist(value)) if(islist(value))
value = deepCopyList(value) value = deepCopyList(value)
what.vars[attribute] = value A.vars[attribute] = value
GLOB.use_preloader = FALSE GLOB.use_preloader = FALSE
// If the map loader fails, make this safe // If the map loader fails, make this safe
/dmm_suite/preloader/proc/reset() /datum/dmm_suite/preloader/proc/reset()
GLOB.use_preloader = FALSE GLOB.use_preloader = FALSE
attributes = list() attributes = list()
target_path = null target_path = null
@@ -470,12 +465,12 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new())
// so that one can have separate "unpowered" areas for ruins or whatever, // so that one can have separate "unpowered" areas for ruins or whatever,
// yet have a single area type for use of mapping, instead of creating // yet have a single area type for use of mapping, instead of creating
// a new area type for each new ruin // a new area type for each new ruin
/dmm_suite/loaded_map /datum/dmm_suite/loaded_map
parent_type = /datum parent_type = /datum
var/list/area_list = list() var/list/area_list = list()
var/index = 1 // To store the state of the regex var/index = 1 // To store the state of the regex
/dmm_suite/loaded_map/proc/area_path_to_real_area(area/A) /datum/dmm_suite/loaded_map/proc/area_path_to_real_area(area/A)
if(!ispath(A, /area)) if(!ispath(A, /area))
throw EXCEPTION("Wrong argument to `area_path_to_real_area`") throw EXCEPTION("Wrong argument to `area_path_to_real_area`")

View File

@@ -5,9 +5,8 @@
#define DMM_IGNORE_PLAYERS 16 #define DMM_IGNORE_PLAYERS 16
#define DMM_IGNORE_MOBS 24 #define DMM_IGNORE_MOBS 24
#define DMM_USE_JSON 32 #define DMM_USE_JSON 32
/dmm_suite /datum/dmm_suite
var/quote = "\"" var/static/list/letter_digits = list(
var/list/letter_digits = list(
"a", "b", "c", "d", "e", "a", "b", "c", "d", "e",
"f", "g", "h", "i", "j", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "k", "l", "m", "n", "o",
@@ -22,7 +21,7 @@
"Z" "Z"
) )
/dmm_suite/save_map(var/turf/t1 as turf, var/turf/t2 as turf, var/map_name as text, var/flags as num) /datum/dmm_suite/proc/save_map(turf/t1, turf/t2, map_name = "", flags = 0)
// Check for illegal characters in file name... in a cheap way. // Check for illegal characters in file name... in a cheap way.
if(!((ckeyEx(map_name) == map_name) && ckeyEx(map_name))) if(!((ckeyEx(map_name) == map_name) && ckeyEx(map_name)))
CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.") CRASH("Invalid text supplied to proc save_map, invalid characters or empty string.")
@@ -39,7 +38,7 @@
saved_map << map_text saved_map << map_text
return saved_map return saved_map
/dmm_suite/write_map(var/turf/t1 as turf, var/turf/t2 as turf, var/flags as num) /datum/dmm_suite/proc/write_map(turf/t1, turf/t2, flags = 0)
// Check for valid turfs. // Check for valid turfs.
if(!isturf(t1) || !isturf(t2)) if(!isturf(t1) || !isturf(t2))
CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.") CRASH("Invalid arguments supplied to proc write_map, arguments were not turfs.")
@@ -54,6 +53,7 @@
var/total_timer = start_watch() var/total_timer = start_watch()
var/timer = start_watch() var/timer = start_watch()
log_debug("Reading turfs...") log_debug("Reading turfs...")
// Read the contents of all the turfs we were given // Read the contents of all the turfs we were given
for(var/pos_z in sw.z to ne.z) for(var/pos_z in sw.z to ne.z)
for(var/pos_y in ne.y to sw.y step -1) // We're reversing this because the map format is silly for(var/pos_y in ne.y to sw.y step -1) // We're reversing this because the map format is silly
@@ -66,17 +66,18 @@
template_number = templates.len template_number = templates.len
template_buffer += "[template_number]," template_buffer += "[template_number],"
CHECK_TICK CHECK_TICK
template_buffer += ";" template_buffer += ";"
template_buffer += "." template_buffer += "."
template_buffer_text = jointext(template_buffer, "") template_buffer_text = jointext(template_buffer, "")
log_debug("Reading turfs took [stop_watch(timer)]s.") log_debug("Reading turfs took [stop_watch(timer)]s.")
if(templates.len == 0) if(templates.len == 0)
CRASH("No templates found!") CRASH("No templates found!")
var/key_length = round/*floor*/(log(letter_digits.len, templates.len - 1) + 1) var/key_length = round/*floor*/(log(letter_digits.len, templates.len - 1) + 1)
var/list/keys[templates.len] var/list/keys[templates.len]
// Write the list of key/model pairs to the file // Write the list of key/model pairs to the file
timer = start_watch() timer = start_watch()
log_debug("Writing out key/model pairs to file header...") log_debug("Writing out key/model pairs to file header...")
@@ -85,6 +86,7 @@
keys[key_pos] = get_model_key(key_pos, key_length) keys[key_pos] = get_model_key(key_pos, key_length)
key_models += "\"[keys[key_pos]]\" = ([templates[key_pos]])\n" key_models += "\"[keys[key_pos]]\" = ([templates[key_pos]])\n"
CHECK_TICK CHECK_TICK
dmm_text += jointext(key_models,"") dmm_text += jointext(key_models,"")
log_debug("Writing key/model pairs complete, took [stop_watch(timer)]s.") log_debug("Writing key/model pairs complete, took [stop_watch(timer)]s.")
@@ -92,18 +94,27 @@
// Loop over all z in our zone // Loop over all z in our zone
timer = start_watch() timer = start_watch()
log_debug("Writing out key map...") log_debug("Writing out key map...")
var/list/key_map = list() var/list/key_map = list()
for(var/z_pos = 1; TRUE; z_pos = findtext(template_buffer_text, ".", z_pos) + 1) for(var/z_pos = 1; TRUE; z_pos = findtext(template_buffer_text, ".", z_pos) + 1)
if(z_pos>=length(template_buffer_text)) break if(z_pos >= length(template_buffer_text))
if(z_level) key_map += "\n" break
if(z_level)
key_map += "\n"
key_map += "\n(1, 1,[++z_level]) = {\"\n" key_map += "\n(1, 1,[++z_level]) = {\"\n"
var/z_block = copytext(template_buffer_text, z_pos, findtext(template_buffer_text, ".", z_pos)) var/z_block = copytext(template_buffer_text, z_pos, findtext(template_buffer_text, ".", z_pos))
for(var/y_pos = 1; TRUE; y_pos = findtext(z_block, ";", y_pos) + 1) for(var/y_pos = 1; TRUE; y_pos = findtext(z_block, ";", y_pos) + 1)
if(y_pos>=length(z_block)) break if(y_pos >= length(z_block))
break
var/y_block = copytext(z_block, y_pos, findtext(z_block, ";", y_pos)) var/y_block = copytext(z_block, y_pos, findtext(z_block, ";", y_pos))
// A row of keys // A row of keys
for(var/x_pos = 1; TRUE; x_pos = findtext(y_block, ",", x_pos) + 1) for(var/x_pos = 1; TRUE; x_pos = findtext(y_block, ",", x_pos) + 1)
if(x_pos>=length(y_block)) break if(x_pos >= length(y_block))
break
var/x_block = copytext(y_block, x_pos, findtext(y_block, ",", x_pos)) var/x_block = copytext(y_block, x_pos, findtext(y_block, ",", x_pos))
var/key_number = text2num(x_block) var/key_number = text2num(x_block)
var/temp_key = keys[key_number] var/temp_key = keys[key_number]
@@ -111,39 +122,41 @@
CHECK_TICK CHECK_TICK
key_map += "\n" key_map += "\n"
key_map += "\"}" key_map += "\"}"
dmm_text += jointext(key_map, "") dmm_text += jointext(key_map, "")
log_debug("Writing key map complete, took [stop_watch(timer)]s.") log_debug("Writing key map complete, took [stop_watch(timer)]s.")
log_debug("TOTAL TIME: [stop_watch(total_timer)]s.") log_debug("TOTAL TIME: [stop_watch(total_timer)]s.")
return dmm_text return dmm_text
/dmm_suite/proc/make_template(var/turf/model as turf, var/flags as num) /datum/dmm_suite/proc/make_template(turf/model, flags = 0)
var/use_json = 0 var/use_json = flags & DMM_USE_JSON
if(flags & DMM_USE_JSON)
use_json = 1
var/template = "" var/template = ""
var/turf_template = "" var/turf_template = ""
var/list/obj_template = list() var/list/obj_template = list()
var/list/mob_template = list() var/list/mob_template = list()
var/area_template = "" var/area_template = ""
// Turf // Turf
if(!(flags & DMM_IGNORE_TURFS)) if(!(flags & DMM_IGNORE_TURFS))
turf_template = "[model.type][check_attributes(model,use_json=use_json)]," turf_template = "[model.type][check_attributes(model,use_json=use_json)],"
else turf_template = "[world.turf]," else
turf_template = "[world.turf],"
// Objects loop // Objects loop
if(!(flags & DMM_IGNORE_OBJS)) if(!(flags & DMM_IGNORE_OBJS))
for(var/obj/O in model.contents) for(var/obj/O in model.contents)
if(O.dont_save || QDELETED(O)) if(O.dont_save || QDELETED(O))
continue continue
obj_template += "[O.type][check_attributes(O,use_json=use_json)]," obj_template += "[O.type][check_attributes(O,use_json=use_json)],"
// Mobs Loop // Mobs Loop
for(var/mob/M in model.contents) for(var/mob/M in model.contents)
if(M.dont_save || QDELETED(M)) if(M.dont_save || QDELETED(M))
continue continue
if(M.client) if(M.client)
if(!(flags & DMM_IGNORE_PLAYERS)) if(!(flags & DMM_IGNORE_PLAYERS))
mob_template += "[M.type][check_attributes(M,use_json=use_json)]," mob_template += "[M.type][check_attributes(M,use_json=use_json)],"
@@ -155,36 +168,39 @@
if(!(flags & DMM_IGNORE_AREAS)) if(!(flags & DMM_IGNORE_AREAS))
var/area/m_area = model.loc var/area/m_area = model.loc
area_template = "[m_area.type][check_attributes(m_area,use_json=use_json)]" area_template = "[m_area.type][check_attributes(m_area,use_json=use_json)]"
else area_template = "[world.area]" else
area_template = "[world.area]"
template = "[jointext(obj_template,"")][jointext(mob_template,"")][turf_template][area_template]" template = "[jointext(obj_template,"")][jointext(mob_template,"")][turf_template][area_template]"
return template return template
/dmm_suite/proc/check_attributes(var/atom/A,use_json=0) /datum/dmm_suite/proc/check_attributes(atom/A, use_json = FALSE)
var/attributes_text = "{" var/attributes_text = "{"
var/list/attributes = list() var/list/attributes = list()
if(!use_json) if(!use_json)
for(var/V in A.vars) for(var/V in A.vars)
CHECK_TICK CHECK_TICK
if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))) continue if((!issaved(A.vars[V])) || (A.vars[V] == initial(A.vars[V])))
continue
attributes += var_to_dmm(A.vars[V], V) attributes += var_to_dmm(A.vars[V], V)
else else
var/list/yeah = A.serialize() var/list/to_encode = A.serialize()
// We'll want to write out vars that are important to the editor // We'll want to write out vars that are important to the editor
// So that the map is legible as before // So that the map is legible as before
for(var/thing in A.map_important_vars()) for(var/T in A.map_important_vars())
// Save vars that are important for the map editor, so that // Save vars that are important for the map editor, so that
// json-encoded maps are legible for standard editors // json-encoded maps are legible for standard editors
if(A.vars[thing] != initial(A.vars[thing])) if(A.vars[T] != initial(A.vars[T]))
yeah -= thing to_encode -= T
attributes += var_to_dmm(A.vars[thing],thing) attributes += var_to_dmm(A.vars[T], T)
// Remove useless info // Remove useless info
yeah -= "type" to_encode -= "type"
if(yeah.len) if(to_encode.len)
var/json_stuff = json_encode(yeah) var/json_stuff = json_encode(to_encode)
attributes += var_to_dmm(json_stuff, "map_json_data") attributes += var_to_dmm(json_stuff, "map_json_data")
if(attributes.len == 0) if(attributes.len == 0)
return return
@@ -192,21 +208,21 @@
// so the last one will be trailing. // so the last one will be trailing.
if(copytext(attributes_text, length(attributes_text) - 1, 0) == "; ") if(copytext(attributes_text, length(attributes_text) - 1, 0) == "; ")
attributes_text = copytext(attributes_text, 1, length(attributes_text) - 1) attributes_text = copytext(attributes_text, 1, length(attributes_text) - 1)
attributes_text = "{[jointext(attributes,"; ")]}" attributes_text = "{[jointext(attributes,"; ")]}"
return attributes_text return attributes_text
/datum/dmm_suite/proc/get_model_key(which = 0, key_length = 0)
/dmm_suite/proc/get_model_key(var/which as num, var/key_length as num)
var/list/key = list() var/list/key = list()
var/working_digit = which - 1 var/working_digit = which - 1
for(var/digit_pos in key_length to 1 step -1) for(var/digit_pos in key_length to 1 step -1)
var/place_value = round/*floor*/(working_digit / (letter_digits.len ** (digit_pos - 1))) var/place_value = round/*floor*/(working_digit / (letter_digits.len ** (digit_pos - 1)))
working_digit -= place_value * (letter_digits.len ** (digit_pos - 1)) working_digit -= place_value * (letter_digits.len ** (digit_pos - 1))
key += letter_digits[place_value + 1] key += letter_digits[place_value + 1]
return jointext(key,"") return jointext(key,"")
/datum/dmm_suite/proc/var_to_dmm(attr, name)
/dmm_suite/proc/var_to_dmm(attr, name)
if(istext(attr)) if(istext(attr))
// dmm_encode will strip out characters that would be capable of disrupting // dmm_encode will strip out characters that would be capable of disrupting
// parsing - namely, quotes and curly braces // parsing - namely, quotes and curly braces