From 03d38bf895a5a0932dffd75a22700fd08957ad2b Mon Sep 17 00:00:00 2001 From: YotaXP Date: Thu, 31 Mar 2016 13:44:04 -0400 Subject: [PATCH] Adds a 'measureOnly' mode to the maploader code for templates. --- code/datums/helper_datums/map_template.dm | 19 ++---- .../admin/verbs/map_template_loadverb.dm | 15 +++-- .../awaymissions/maploader/dmm_suite.dm | 3 +- code/modules/awaymissions/maploader/reader.dm | 64 +++++++++++++------ 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/code/datums/helper_datums/map_template.dm b/code/datums/helper_datums/map_template.dm index 860ce32d94e..156f896e187 100644 --- a/code/datums/helper_datums/map_template.dm +++ b/code/datums/helper_datums/map_template.dm @@ -16,16 +16,10 @@ name = rename /datum/map_template/proc/preload_size(path) - var/quote = ascii2text(34) - var/map_file = file2text(path) - var/key_len = length(copytext(map_file,2,findtext(map_file,quote,2,0))) - //assuming one map per file since more makes no sense for templates anyway - var/mapstart = findtext(map_file,"\n(1,1,") //todo replace with something saner - var/content = copytext(map_file,findtext(map_file,quote+"\n",mapstart,0)+2,findtext(map_file,"\n"+quote,mapstart,0)+1) - var/line_len = length(copytext(content,1,findtext(content,"\n",2,0))) - - width = line_len/key_len - height = length(content)/(line_len+1) + var/bounds = maploader.load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE) + . = bounds[1] != 0 // 0 if the map failed to be measured + width = bounds[4] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1 + height = bounds[5] /datum/map_template/proc/load(turf/T, centered = FALSE) if(centered) @@ -37,14 +31,14 @@ if(T.y+height > world.maxy) return - maploader.load_map(get_file(), T.x-1, T.y-1, T.z) + var/list/bounds = maploader.load_map(get_file(), T.x, T.y, T.z, cropMap=TRUE) //initialize things that are normally initialized after map load var/list/obj/machinery/atmospherics/atmos_machines = list() var/list/obj/structure/cable/cables = list() var/list/atom/atoms = list() - for(var/L in block(T,locate(T.x+width-1, T.y+height-1, T.z))) + for(var/L in block(locate(bounds[1], bounds[2], bounds[3]), locate(bounds[4], bounds[5], bounds[6]))) var/turf/B = L for(var/A in B) atoms += A @@ -60,6 +54,7 @@ SSair.setup_template_machinery(atmos_machines) log_game("[name] loaded at at [T.x],[T.y],[T.z]") + return 1 /datum/map_template/proc/get_file() if(mapfile) diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index 781ab735832..b1a524986dc 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -18,8 +18,10 @@ preview += image('icons/turf/overlays.dmi',S,"greenOverlay") usr.client.images += preview if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes") - template.load(T, centered = TRUE) - message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at (JMP)") + if(template.load(T, centered = TRUE)) + message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at (JMP)") + else + usr << "Failed to place map" usr.client.images -= preview /client/proc/map_template_upload() @@ -34,6 +36,9 @@ return var/datum/map_template/M = new(map=map, rename="[map]") - M.preload_size(map) - map_templates[M.name] = M - message_admins("[key_name_admin(usr)] has uploaded a map template ([map])") + if(M.preload_size(map)) + usr << "Map template '[map]' ready to place ([M.width]x[M.height])" + map_templates[M.name] = M + message_admins("[key_name_admin(usr)] has uploaded a map template ([map])") + else + usr << "Map template '[map]' failed to load properly" diff --git a/code/modules/awaymissions/maploader/dmm_suite.dm b/code/modules/awaymissions/maploader/dmm_suite.dm index ba4664fa4aa..01f7a08a1c9 100644 --- a/code/modules/awaymissions/maploader/dmm_suite.dm +++ b/code/modules/awaymissions/maploader/dmm_suite.dm @@ -53,10 +53,11 @@ 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, var/cropMap as num){ + verb/load_map(var/dmm_file as file, var/x_offset as num, var/y_offset as num, var/z_offset as num, var/cropMap as num, var/measureOnly as num){ // dmm_file: A .dmm file to load (Required). // z_offset: A number representing the z-level on which to start loading the map (Optional). // cropMap: When true, the map will be cropped to fit the existing world dimensions (Optional). + // measureOnly: When true, no changes will be made to the world (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). diff --git a/code/modules/awaymissions/maploader/reader.dm b/code/modules/awaymissions/maploader/reader.dm index e153ad961d0..f765cda07e0 100644 --- a/code/modules/awaymissions/maploader/reader.dm +++ b/code/modules/awaymissions/maploader/reader.dm @@ -25,7 +25,7 @@ var/global/dmm_suite/preloader/_preloader = new * 2) Read the map line by line, parsing the result (using parse_grid) * */ -/dmm_suite/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num) +/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) var/tfile = dmm_file//the map file we're creating if(isfile(tfile)) tfile = file2text(tfile) @@ -37,6 +37,7 @@ var/global/dmm_suite/preloader/_preloader = new if(!z_offset) z_offset = world.maxz + 1 + var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF) var/list/grid_models = list() var/key_len = 0 @@ -53,7 +54,8 @@ var/global/dmm_suite/preloader/_preloader = new key_len = length(key) else throw EXCEPTION("Inconsistant key length in DMM") - grid_models[key] = dmmRegex.group[2] + if(!measureOnly) + grid_models[key] = dmmRegex.group[2] // (1,1,1) = {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} else if(dmmRegex.group[3]) // Coords @@ -72,6 +74,10 @@ var/global/dmm_suite/preloader/_preloader = new else world.maxz = zcrd //create a new z_level if needed + bounds[1] = min(bounds[1], xcrdStart) // Update the min-x + bounds[3] = min(bounds[3], zcrd) // Update the min-z + bounds[6] = max(bounds[6], zcrd) // Update the max-z + var/list/gridLines = splittext(dmmRegex.group[6], "\n") var/leadingBlanks = 0 @@ -85,34 +91,50 @@ var/global/dmm_suite/preloader/_preloader = new if(gridLines.len && gridLines[gridLines.len] == "") gridLines.Cut(gridLines.len) // Remove only one blank line at the end. + bounds[2] = min(bounds[2], ycrd) // Update the min-y ycrd += gridLines.len - 1 // Start at the top and work down if(!cropMap && ycrd > world.maxy) - world.maxy = ycrd // Expand Y here. X is expanded in the loop below + if(!measureOnly) + world.maxy = ycrd // Expand Y here. X is expanded in the loop below + bounds[5] = max(bounds[5], ycrd) // Update the max-y + else + bounds[5] = max(bounds[5], min(ycrd, world.maxy)) // Update the max-y - for(var/line in gridLines) - if(ycrd <= world.maxy && ycrd >= 1) - xcrd = xcrdStart - for(var/tpos = 1 to length(line) - key_len + 1 step key_len) - if(xcrd > world.maxx) - if(cropMap) - break - else - world.maxx = xcrd + var/maxx = xcrdStart + if(measureOnly) + for(var/line in gridLines) + maxx = max(maxx, xcrdStart + length(line) / key_len - 1) + else + for(var/line in gridLines) + if(ycrd <= world.maxy && ycrd >= 1) + xcrd = xcrdStart + for(var/tpos = 1 to length(line) - key_len + 1 step key_len) + if(xcrd > world.maxx) + if(cropMap) + break + else + world.maxx = xcrd - if(xcrd >= 1) - var/model_key = copytext(line, tpos, tpos + key_len) - if(!grid_models[model_key]) - throw EXCEPTION("Undefined model key in DMM.") - parse_grid(grid_models[model_key], xcrd, ycrd, zcrd) - sleep(-1) + if(xcrd >= 1) + var/model_key = copytext(line, tpos, tpos + key_len) + if(!grid_models[model_key]) + throw EXCEPTION("Undefined model key in DMM.") + parse_grid(grid_models[model_key], xcrd, ycrd, zcrd) + CHECK_TICK - ++xcrd - --ycrd + maxx = max(maxx, xcrd) + ++xcrd + --ycrd + + bounds[4] = max(bounds[4], cropMap ? min(maxx, world.maxx) : maxx) // Update the max-x CHECK_TICK - return 1 + if(bounds[1] == 1.#INF) + return list(0, 0, 0, 0, 0, 0) + else + return bounds /** * Fill a given tile with its area/turf/objects/mobs