mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-17 18:12:21 +01:00
249 lines
9.4 KiB
Plaintext
249 lines
9.4 KiB
Plaintext
|
|
|
|
//-- Reader for loading DMM files at runtime -----------------------------------
|
|
/datum/loadedProperties
|
|
var/info = ""
|
|
var/sourceX = 0
|
|
var/sourceY = 0
|
|
var/sourceZ = 0
|
|
var/maxX = 0
|
|
var/maxY = 0
|
|
var/maxZ = 0
|
|
|
|
dmm_suite
|
|
|
|
/*-- read_map ------------------------------------
|
|
Generates map instances based on provided DMM formatted text. If coordinates
|
|
are provided, the map will start loading at those coordinates. Otherwise, any
|
|
coordinates saved with the map will be used. Otherwise, coordinates will
|
|
default to (1, 1, world.maxz+1)
|
|
*/
|
|
read_map(dmm_text as text, coordX as num, coordY as num, coordZ as num, tag as text)
|
|
var/datum/loadedProperties/props = new()
|
|
props.sourceX = coordX
|
|
props.sourceY = coordY
|
|
props.sourceZ = coordZ
|
|
props.info = tag
|
|
// Split Key/Model list into lines
|
|
var key_len = length(
|
|
copytext(
|
|
dmm_text, 2, findtext(dmm_text, quote, 2, 0)
|
|
)
|
|
)
|
|
var /list/grid_models[0]
|
|
var startGridPos = findtext(dmm_text, "\n\n(1,1,") // Safe because \n not allowed in strings in dmm
|
|
var linesText = copytext(dmm_text, 1, startGridPos)
|
|
var /list/modelLines = text2list(linesText, "\n")
|
|
for(var/modelLine in modelLines) // "aa" = (/path{key = value; key = value},/path,/path)\n
|
|
var modelKey = copytext(modelLine, 2, findtext(modelLine, quote, 2, 0))
|
|
var modelsStart = findtextEx(modelLine, "=")+3 // Skip key and first three characters: "aa" = (
|
|
var modelContents = copytext(modelLine, modelsStart, length(modelLine)) // Skip last character: )
|
|
grid_models[modelKey] = modelContents
|
|
sleep(-1)
|
|
// Retrieve Comments, Determine map position (if not specified)
|
|
var commentModel = modelLines[1] // The comment key will always be first.
|
|
var bracketPos = findtextEx(commentModel, "}")
|
|
commentModel = copytext(commentModel, findtextEx(commentModel, "=")+3, bracketPos) // Skip opening bracket
|
|
var commentPathText = "[/obj/dmm_suite/comment]"
|
|
if(copytext(commentModel, 1, length(commentPathText)+1) == commentPathText)
|
|
var attributesText = copytext(commentModel, length(commentPathText)+2, -1) // Skip closing bracket
|
|
var /list/paddedAttributes = text2list(attributesText, "; ") // "Key = Value"
|
|
for(var/paddedAttribute in paddedAttributes)
|
|
var equalPos = findtextEx(paddedAttribute, "=")
|
|
var attributeKey = copytext(paddedAttribute, 1, equalPos-1)
|
|
var attributeValue = copytext(paddedAttribute, equalPos+3, -1) // Skip quotes
|
|
switch(attributeKey)
|
|
if("coordinates")
|
|
var /list/coords = text2list(attributeValue, ",")
|
|
if(!coordX) coordX = text2num(coords[1])
|
|
if(!coordY) coordY = text2num(coords[2])
|
|
if(!coordZ) coordZ = text2num(coords[3])
|
|
if(!coordX) coordX = 1
|
|
if(!coordY) coordY = 1
|
|
if(!coordZ) coordZ = world.maxz+1
|
|
// Store quoted portions of text in text_strings, and replaces them with an index to that list.
|
|
var gridText = copytext(dmm_text, startGridPos)
|
|
var /list/gridLevels = list()
|
|
var /regex/grid = regex(@(##)\{"\n((?:\l*\n)*)"\}##, "g")
|
|
while(grid.Find(gridText))
|
|
gridLevels.Add(copytext(grid.group[1], 1, -1)) // Strip last \n
|
|
// Create all Atoms at map location, from model key
|
|
world.maxz = max(world.maxz, coordZ+gridLevels.len-1)
|
|
for(var/posZ = 1 to gridLevels.len)
|
|
var zGrid = gridLevels[posZ]
|
|
// Reverse Y coordinate
|
|
var /list/yReversed = text2list(zGrid, "\n")
|
|
var /list/yLines = list()
|
|
for(var/posY = yReversed.len to 1 step -1)
|
|
yLines.Add(yReversed[posY])
|
|
//
|
|
var yMax = yLines.len+(coordY-1)
|
|
if(world.maxy < yMax)
|
|
world.maxy = yMax
|
|
logTheThing( "debug", null, null, "[tag] caused map resize (Y) during prefab placement" )
|
|
var exampleLine = pick(yLines)
|
|
var xMax = length(exampleLine)+(coordX-1)
|
|
if(world.maxx < xMax)
|
|
world.maxx = xMax
|
|
logTheThing( "debug", null, null, "[tag] caused map resize (X) during prefab placement" )
|
|
|
|
props.maxX = xMax
|
|
props.maxY = yMax
|
|
props.maxZ = world.maxz
|
|
|
|
for(var/posY = 1 to yLines.len)
|
|
var yLine = yLines[posY]
|
|
for(var/posX = 1 to length(yLine)/key_len)
|
|
var keyPos = ((posX-1)*key_len)+1
|
|
var modelKey = copytext(yLine, keyPos, keyPos+key_len)
|
|
parse_grid(
|
|
grid_models[modelKey], posX+(coordX-1), posY+(coordY-1), posZ+(coordZ-1)
|
|
)
|
|
sleep(-1)
|
|
sleep(-1)
|
|
//
|
|
return props
|
|
|
|
/*-- load_map ------------------------------------
|
|
Deprecated. Use read_map instead.
|
|
*/
|
|
load_map(dmm_file as file, z_offset as num)
|
|
if(!z_offset) z_offset = world.maxz+1
|
|
var dmmText = file2text(dmm_file)
|
|
return read_map(dmmText, 1, 1, z_offset)
|
|
|
|
|
|
//-- Supplemental Methods ------------------------------------------------------
|
|
|
|
var
|
|
quote = "\""
|
|
|
|
proc
|
|
parse_grid(models as text, xcrd, ycrd, zcrd)
|
|
/* Method parse_grid() - 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.*/
|
|
// Store quoted portions of text in text_strings, and replace them with an index to that list.
|
|
var /list/originalStrings = list()
|
|
var /regex/noStrings = regex(@(##)(["])(?:(?=(\\?))\2(.|\n))*?\1##)
|
|
var stringIndex = 1
|
|
var found
|
|
do
|
|
found = noStrings.Find(models, noStrings.next)
|
|
if(found)
|
|
var indexText = {""[stringIndex]""}
|
|
stringIndex++
|
|
var match = copytext(noStrings.match, 2, -1) // Strip quotes
|
|
models = noStrings.Replace(models, indexText, found)
|
|
originalStrings[indexText] = (match)
|
|
while(found)
|
|
// Identify each object's data, instantiate it, & reconstitues its fields.
|
|
var /list/turfStackTypes = list()
|
|
var /list/turfStackAttributes = list()
|
|
for(var/atomModel in text2list(models, ","))
|
|
var bracketPos = findtext(atomModel, "{")
|
|
var atomPath = text2path(copytext(atomModel, 1, bracketPos))
|
|
var /list/attributes
|
|
if(bracketPos)
|
|
attributes = new()
|
|
var attributesText = copytext(atomModel, bracketPos+1, -1)
|
|
var /list/paddedAttributes = text2list(attributesText, "; ") // "Key = Value"
|
|
for(var/paddedAttribute in paddedAttributes)
|
|
var equalPos = findtextEx(paddedAttribute, "=")
|
|
var attributeKey = copytext(paddedAttribute, 1, equalPos-1)
|
|
var attributeValue = copytext(paddedAttribute, equalPos+2)
|
|
attributes[attributeKey] = attributeValue
|
|
if(!ispath(atomPath, /turf))
|
|
loadModel(atomPath, attributes, originalStrings, xcrd, ycrd, zcrd)
|
|
else
|
|
turfStackTypes.Insert(1, atomPath)
|
|
turfStackAttributes.Insert(1, null)
|
|
turfStackAttributes[1] = attributes
|
|
// Layer all turf appearances into final turf
|
|
if(!turfStackTypes.len) return
|
|
var /turf/topTurf = loadModel(turfStackTypes[1], turfStackAttributes[1], originalStrings, xcrd, ycrd, zcrd)
|
|
for(var/turfIndex = 2 to turfStackTypes.len)
|
|
var /mutable_appearance/underlay = new(turfStackTypes[turfIndex])
|
|
loadModel(underlay, turfStackAttributes[turfIndex], originalStrings, xcrd, ycrd, zcrd)
|
|
topTurf.underlays.Add(underlay)
|
|
|
|
loadModel(atomPath, list/attributes, list/strings, xcrd, ycrd, zcrd)
|
|
// Cancel if atomPath is a placeholder (DMM_IGNORE flags used to write file)
|
|
if(ispath(atomPath, /turf/dmm_suite/clear_turf) || ispath(atomPath, /area/dmm_suite/clear_area))
|
|
return
|
|
if(ispath(atomPath, /turf/space)) return //Dont load space
|
|
// Parse all attributes and create preloader
|
|
var /list/attributesMirror = list()
|
|
var /turf/location = locate(xcrd, ycrd, zcrd)
|
|
for(var/attributeName in attributes)
|
|
attributesMirror[attributeName] = loadAttribute(attributes[attributeName], strings)
|
|
var /dmm_suite/preloader/preloader = new(location, attributesMirror)
|
|
// Begin Instanciation
|
|
// Handle Areas (not created every time)
|
|
var /atom/instance
|
|
if(ispath(atomPath, /area))
|
|
//instance = locate(atomPath)
|
|
//instance.contents.Add(locate(xcrd, ycrd, zcrd))
|
|
new atomPath(locate(xcrd, ycrd, zcrd))
|
|
location.dmm_preloader = null
|
|
// Handle Underlay Turfs
|
|
else if(istype(atomPath, /mutable_appearance))
|
|
instance = atomPath // Skip to preloader manual loading.
|
|
preloader.load(instance)
|
|
// Handle Turfs & Movable Atoms
|
|
else
|
|
if(ispath(atomPath, /turf))
|
|
//instance = new atomPath(location)
|
|
instance = location.ReplaceWith(atomPath, handle_air = 0, handle_dir = 0)
|
|
else
|
|
instance = new atomPath(location)
|
|
// Handle cases where Atom/New was redifined without calling Super()
|
|
if(preloader && instance) // Atom could delete itself in New()
|
|
preloader.load(instance)
|
|
//
|
|
return instance
|
|
|
|
loadAttribute(value, list/strings)
|
|
//Check for string
|
|
if(copytext(value, 1, 2) == "\"")
|
|
return strings[value]
|
|
//Check for number
|
|
var num = text2num(value)
|
|
if(isnum(num))
|
|
return num
|
|
//Check for file
|
|
else if(copytext(value,1,2) == "'")
|
|
return file(copytext(value,2,length(value)))
|
|
// Check for lists
|
|
// To Do
|
|
|
|
|
|
//-- Preloading ----------------------------------------------------------------
|
|
|
|
turf
|
|
var
|
|
dmm_suite/preloader/dmm_preloader
|
|
|
|
atom/New(turf/newLoc)
|
|
if(isturf(newLoc))
|
|
var /dmm_suite/preloader/preloader = newLoc.dmm_preloader
|
|
if(preloader)
|
|
newLoc.dmm_preloader = null
|
|
preloader.load(src)
|
|
. = ..()
|
|
|
|
dmm_suite
|
|
preloader
|
|
parent_type = /datum
|
|
var
|
|
list/attributes
|
|
New(turf/loadLocation, list/_attributes)
|
|
loadLocation.dmm_preloader = src
|
|
attributes = _attributes
|
|
. = ..()
|
|
proc
|
|
load(atom/newAtom)
|
|
var /list/attributesMirror = attributes // apparently this is faster
|
|
for(var/attributeName in attributesMirror)
|
|
newAtom.vars[attributeName] = attributesMirror[attributeName]
|