From ffd47933e5178ed347f9ae379246969e378f76f9 Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Sun, 7 Aug 2016 12:02:43 -0700 Subject: [PATCH] Map writer is now legible in DM, saves 19x faster --- code/__HELPERS/text.dm | 6 +- code/modules/awaymissions/maploader/writer.dm | 64 +++++++++++-------- code/modules/persistence/persistence.dm | 4 +- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 3fe80b245e9..e56ed3a4310 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -395,7 +395,7 @@ proc/checkhtml(var/t) // First, go through and nix out any of our escape sequences so we don't leave ourselves open to some escape sequence attack // Some coder will probably despise me for this, years down the line - var/list/repl_chars = list(""", "{", "}") + var/list/repl_chars = list("#?qt;", "#?lbr;", "#?rbr;") for(var/char in repl_chars) var/index = findtext(text, char) var/keylength = length(char) @@ -407,7 +407,7 @@ proc/checkhtml(var/t) index = findtext(text, char) // Then, replace characters as normal - var/list/repl_chars_2 = list("\"" = """, "{" = "{", "}" = "}") + var/list/repl_chars_2 = list("\"" = "#?qt;", "{" = "#?lbr;", "}" = "#?rbr;") for(var/char in repl_chars_2) var/index = findtext(text, char) var/keylength = length(char) @@ -419,7 +419,7 @@ proc/checkhtml(var/t) /proc/dmm_decode(text) // Replace what we extracted above - var/list/repl_chars = list(""" = "\"", "{" = "{", "}" = "}") + var/list/repl_chars = list("#?qt;" = "\"", "#?lbr;" = "{", "#?rbr;" = "}") for(var/char in repl_chars) var/index = findtext(text, char) var/keylength = length(char) diff --git a/code/modules/awaymissions/maploader/writer.dm b/code/modules/awaymissions/maploader/writer.dm index c5cac261c46..9b7fdf1bedc 100644 --- a/code/modules/awaymissions/maploader/writer.dm +++ b/code/modules/awaymissions/maploader/writer.dm @@ -47,7 +47,8 @@ var/turf/ne = locate(max(t1.x,t2.x),max(t1.y,t2.y),max(t1.z,t2.z)) // Outer corner var/turf/sw = locate(min(t1.x,t2.x),min(t1.y,t2.y),min(t1.z,t2.z)) // Inner corner var/list/templates[0] - var/template_buffer = "" + var/list/template_buffer = list() + var/template_buffer_text var/buffer_line = "" var/dmm_text = "" @@ -56,7 +57,7 @@ log_debug("Reading turfs...") // Read the contents of all the turfs we were given for(var/pos_z in sw.z to ne.z) - for(var/pos_y = ne.y, pos_y >= sw.y, pos_y--) // 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 for(var/pos_x in sw.x to ne.x) var/turf/test_turf = locate(pos_x,pos_y,pos_z) var/test_template = make_template(test_turf, flags) @@ -64,13 +65,13 @@ if(!template_number) templates.Add(test_template) template_number = templates.len - buffer_line += "[template_number]," + template_buffer += "[template_number]," CHECK_TICK template_buffer += "[buffer_line];" - buffer_line = "" template_buffer += "." + template_buffer_text = jointext(template_buffer,"") log_debug("Reading turfs took [stop_watch(timer)]s.") if(templates.len == 0) @@ -80,20 +81,24 @@ // Write the list of key/model pairs to the file timer = start_watch() log_debug("Writing out key/model pairs to file header...") + var/list/key_models = list() for(var/key_pos in 1 to templates.len) keys[key_pos] = get_model_key(key_pos,key_length) - dmm_text += "\"[keys[key_pos]]\" = ([templates[key_pos]])\n" + key_models += "\"[keys[key_pos]]\" = ([templates[key_pos]])\n" + CHECK_TICK + dmm_text += jointext(key_models,"") log_debug("Writing key/model pairs complete, took [stop_watch(timer)]s.") var/z_level = 0 // Loop over all z in our zone timer = start_watch() log_debug("Writing out key map...") - for(var/z_pos=1;TRUE;z_pos=findtext(template_buffer,".",z_pos)+1) - if(z_pos>=length(template_buffer)) break - if(z_level) dmm_text += "\n" - dmm_text += "\n(1,1,[++z_level]) = {\"\n" - var/z_block = copytext(template_buffer,z_pos,findtext(template_buffer,".",z_pos)) + var/list/key_map = list() + 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_level) key_map += "\n" + key_map += "\n(1,1,[++z_level]) = {\"\n" + 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) if(y_pos>=length(z_block)) break var/y_block = copytext(z_block,y_pos,findtext(z_block,";",y_pos)) @@ -103,11 +108,11 @@ var/x_block = copytext(y_block,x_pos,findtext(y_block,",",x_pos)) var/key_number = text2num(x_block) var/temp_key = keys[key_number] - buffer_line += temp_key + key_map += temp_key CHECK_TICK - dmm_text += "[buffer_line]\n" - buffer_line = "" - dmm_text += "\"}" + key_map += "[buffer_line]\n" + key_map += "\"}" + dmm_text += jointext(key_map,"") log_debug("Writing key map complete, took [stop_watch(timer)]s.") log_debug("TOTAL TIME: [stop_watch(total_timer)]s.") return dmm_text @@ -122,6 +127,8 @@ var/mob_template = "" var/area_template = "" + + // Turf if(!(flags & DMM_IGNORE_TURFS)) turf_template = "[model.type][check_attributes(model,use_json=use_json)]," @@ -156,11 +163,13 @@ /dmm_suite/proc/check_attributes(var/atom/A,use_json=0) var/attributes_text = "{" + var/list/attributes = list() if(!use_json) for(var/V in A.vars) - sleep(-1) + CHECK_TICK if((!issaved(A.vars[V])) || (A.vars[V]==initial(A.vars[V]))) continue - attributes_text += var_to_dmm(A.vars[V], V) + + attributes += var_to_dmm(A.vars[V], V) else var/list/yeah = A.serialize() // We'll want to write out vars that are important to the editor @@ -170,42 +179,45 @@ // json-encoded maps are legible for standard editors if(A.vars[thing] != initial(A.vars[thing])) yeah -= thing - attributes_text += var_to_dmm(A.vars[thing],thing) + attributes += var_to_dmm(A.vars[thing],thing) // Remove useless info yeah -= "type" if(yeah.len) var/json_stuff = json_encode(yeah) - attributes_text += var_to_dmm(json_stuff, "map_json_data") - if(attributes_text == "{") + attributes += var_to_dmm(json_stuff, "map_json_data") + if(attributes.len == 0) return // Trim a trailing semicolon - `var_to_dmm` always appends a semicolon, // so the last one will be trailing. if(copytext(attributes_text, length(attributes_text)-1, 0) == "; ") attributes_text = copytext(attributes_text, 1, length(attributes_text)-1) - attributes_text += "}" + attributes_text = "{[jointext(attributes,"; ")]}" return attributes_text /dmm_suite/proc/get_model_key(var/which as num, var/key_length as num) - var/key = "" + var/list/key = list() var/working_digit = which-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))) working_digit-=place_value*(letter_digits.len**(digit_pos-1)) - key = "[key][letter_digits[place_value+1]]" - return key + key += letter_digits[place_value+1] + return jointext(key,"") /dmm_suite/proc/var_to_dmm(attr, name) if(istext(attr)) // dmm_encode will strip out characters that would be capable of disrupting // parsing - namely, quotes and curly braces - return "[name] = \"[dmm_encode(attr)]\"; " + return "[name] = \"[dmm_encode(attr)]\"" else if(isnum(attr)||ispath(attr)) - return "[name] = [attr]; " + return "[name] = [attr]" else if(isicon(attr)||isfile(attr)) - return "[name] = '[attr]'; " + if(length("[attr]") == 0) + // The DM map reader is unable to read files that have a '' file/icon entry + return + return "[name] = '[attr]'" else return "" diff --git a/code/modules/persistence/persistence.dm b/code/modules/persistence/persistence.dm index e6de3f5d138..4c1b40eaa98 100644 --- a/code/modules/persistence/persistence.dm +++ b/code/modules/persistence/persistence.dm @@ -28,11 +28,11 @@ // This is so specific atoms can override these, and ignore certain ones /atom/proc/vars_to_save() - return list("dir","name","color","icon","icon_state", "pixel_x", "pixel_y") + return list("color","dir","icon","icon_state","name","pixel_x","pixel_y") /atom/proc/map_important_vars() // A list of important things to save in the map editor - return list("dir","name","color","icon","icon_state", "pixel_x", "pixel_y") + return list("color","dir","icon","icon_state","layer","name","pixel_x","pixel_y") /area/map_important_vars() // Keep the area default icons, to keep things nice and legible