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