def writeMap(self, *args): l = len(args) if l==3: map, device, path = args self.d.writeMap(map, device, path) elif l==2: tp = type(args[1]) if tp==QIODevice: map, device, path = args, QString() self.d.writeMap(map, device, path) elif tp in [QString, str]: ## # Writes a TMX map to the given \a fileName. # # Returns False and sets errorString() when reading failed. # \overload ## map, fileName = args file = QSaveFile(fileName) if (not self.d.openFile(file)): return False self.writeMap(map, file, QFileInfo(fileName).absolutePath()) if (file.error() != QFile.NoError): self.d.mError = file.errorString() return False if (not file.commit()): self.d.mError = file.errorString() return False return True
def write(self, tileset, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False converter = MapToVariantConverter() variant = converter.toVariant(tileset, QFileInfo(fileName).dir()) writer = json try: result = writer.dumps(variant, indent=4) except: # This can only happen due to coding error self.mError = self.tr('Unknow error.') return False out = QTextStream(file) out << result out.flush() if (file.error() != QFile.NoError): self.mError = self.tr("Error while writing file:\n%1").arg(file.errorString()) return False if (not file.commit()): self.mError = file.errorString() return False return True
def write(self, map, fileName): # Open up a temporary file for saving the level. file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open temporary file for writing.") return False # Create an output stream for serializing data. out = QDataStream(file) out.setByteOrder(QDataStream.LittleEndian) out.setFloatingPointPrecision(QDataStream.SinglePrecision) # Write out the signature and file header. out.writeInt8(96) # Signature. out.writeInt8(map.layerCount()) ok = False x, ok = Int2(map.property("background_index")) if (not ok): self.mError = self.tr("You must define a background_index property on the map!") return False out.writeInt8(x) # Write out each layer. for i in range(0, map.layerCount()): layer = map.layerAt(i).asTileLayer() if (not layer): self.mError = self.tr("Can't save non-tile layer!") return False if (not self.writeLayer(out, layer)): return False if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): # Get file paths for each layer layerPaths = self.outputFiles(map, fileName) # Traverse all tile layers currentLayer = 0 for layer in map.layers(): if layer.layerType() != Layer.TileLayerType: continue tileLayer = layer file = QSaveFile(layerPaths[currentLayer]) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False # Write out tiles either by ID or their name, if given. -1 is "empty" for y in range(0, tileLayer.height()): for x in range(0, tileLayer.width()): if (x > 0): file.write(",") cell = tileLayer.cellAt(x, y) tile = cell.tile if (tile and tile.hasProperty("name")) : file.write(tile.property("name").encode()) else: if tile: id = tile.id() else: id = -1 file.write(QByteArray.number(id)) file.write("\n") if (file.error() != QFile.NoError) : self.mError = file.errorString() return False if (not file.commit()) : self.mError = file.errorString() return False return True
def write(self, map, fileName): # Get file paths for each layer layerPaths = self.outputFiles(map, fileName) # Traverse all tile layers currentLayer = 0 for layer in map.layers(): if layer.layerType() != Layer.TileLayerType: continue tileLayer = layer file = QSaveFile(layerPaths[currentLayer]) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False # Write out tiles either by ID or their name, if given. -1 is "empty" for y in range(0, tileLayer.height()): for x in range(0, tileLayer.width()): if (x > 0): file.write(",") cell = tileLayer.cellAt(x, y) tile = cell.tile if (tile and tile.hasProperty("name")): file.write(tile.property("name").encode()) else: if tile: id = tile.id() else: id = -1 file.write(QByteArray.number(id)) file.write("\n") if (file.error() != QFile.NoError): self.mError = file.errorString() return False if (not file.commit()): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False converter = MapToVariantConverter() variant = converter.toVariant(map, QFileInfo(fileName).dir()) writer = json try: result = writer.dumps(variant, indent=4) except: # This can only happen due to coding error self.mError = self.tr('Unknow error.') return False out = QTextStream(file) if self.mSubFormat == JsonMapFormat.SubFormat.JavaScript: # Trim and escape name nameWriter = json baseName = QFileInfo(fileName).baseName() baseNameResult = nameWriter.dumps(baseName) out << "(function(name,data){\n if(typeof onTileMapLoaded === 'undefined') {\n" out << " if(typeof TileMaps === 'undefined') TileMaps = {};\n" out << " TileMaps[name] = data;\n" out << " } else {\n" out << " onTileMapLoaded(name,data);\n" out << " }})(" + baseNameResult + ",\n" out << result if self.mSubFormat == JsonMapFormat.SubFormat.JavaScript: out << ");" out.flush() if (file.error() != QFile.NoError) : self.mError = self.tr("Error while writing file:\n%1").arg(file.errorString()) return False if (not file.commit()) : self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False self.mMapDir = QDir(QFileInfo(fileName).path()) writer = LuaTableWriter(file) writer.writeStartDocument() self.writeMap(writer, map) writer.writeEndDocument() if (file.error() != QFile.NoError) : self.mError = file.errorString() return False if (not file.commit()) : self.mError = file.errorString() return False return True
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) new_f = None try: ok = f.open(QIODevice.WriteOnly) if not ok: raise OSError(f.errorString()) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f except: f.cancelWriting() raise finally: if new_f is not None: new_f.flush() commit_ok = f.commit() if not commit_ok: raise OSError(f.errorString())
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) new_f = None try: ok = f.open(QIODevice.WriteOnly) if not ok: # pylint: disable=used-before-assignment raise OSError(f.errorString()) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f except: f.cancelWriting() raise finally: if new_f is not None: new_f.flush() ok = f.commit() if not ok: raise OSError(f.errorString())
def write(self, map, fileName): # Check layer count and type if (map.layerCount() != 1 or not map.layerAt(0).isTileLayer()): self.mError = self.tr( "The map needs to have exactly one tile layer!") return False mapLayer = map.layerAt(0).asTileLayer() # Check layer size if (mapLayer.width() != 48 or mapLayer.height() != 48): self.mError = self.tr( "The layer must have a size of 48 x 48 tiles!") return False # Create QByteArray and compress it uncompressed = QByteArray(48 * 48, b'\x00') width = mapLayer.width() height = mapLayer.height() for y in range(0, height): for x in range(0, width): tile = mapLayer.cellAt(x, y).tile if tile: # 'QByteArray' object does not support item assignment uncompressed.replace(y * width + x, 1, bytes([tile.id() & 0xff])) compressed = compress(uncompressed, CompressionMethod.Gzip) # Write QByteArray file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open file for writing.") return False file.write(compressed) if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): collisionLayer = None for layer in map.layers(): if layer.name().lower() == "collision": tileLayer = layer.asTileLayer() if tileLayer: if (collisionLayer) : self.mError = self.tr("Multiple collision layers found!") return False collisionLayer = tileLayer if (not collisionLayer) : self.mError = self.tr("No collision layer found!") return False file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)) : self.mError = self.tr("Could not open file for writing.") return False width = collisionLayer.width() height = collisionLayer.height() stream = QDataStream(file) stream.setByteOrder(QDataStream.LittleEndian) stream.writeInt16(width&0xffff) stream.writeInt16(height&0xffff) for y in range(0, height): for x in range(0, width): tile = collisionLayer.cellAt(x, y).tile stream.writeInt8(int(tile and tile.id()> 0)&0xff) if not file.commit(): self.mError = file.errorString() return False return True
def savefile_open(filename, binary=False, encoding='utf-8'): """Context manager to easily use a QSaveFile.""" f = QSaveFile(filename) cancelled = False try: ok = f.open(QIODevice.WriteOnly) if not ok: raise OSError(f.errorString()) if binary: new_f = PyQIODevice(f) else: new_f = io.TextIOWrapper(PyQIODevice(f), encoding=encoding) yield new_f except: f.cancelWriting() cancelled = True raise else: new_f.flush() finally: commit_ok = f.commit() if not commit_ok and not cancelled: raise OSError("Commit failed!")
def write(self, map, fileName): # Check layer count and type if (map.layerCount() != 1 or not map.layerAt(0).isTileLayer()) : self.mError = self.tr("The map needs to have exactly one tile layer!") return False mapLayer = map.layerAt(0).asTileLayer() # Check layer size if (mapLayer.width() != 48 or mapLayer.height() != 48) : self.mError = self.tr("The layer must have a size of 48 x 48 tiles!") return False # Create QByteArray and compress it uncompressed = QByteArray(48 * 48, b'\x00') width = mapLayer.width() height = mapLayer.height() for y in range(0, height): for x in range(0, width): tile = mapLayer.cellAt(x, y).tile if tile: # 'QByteArray' object does not support item assignment uncompressed.replace(y * width + x, 1, bytes([tile.id()&0xff])) compressed = compress(uncompressed, CompressionMethod.Gzip) # Write QByteArray file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)) : self.mError = self.tr("Could not open file for writing.") return False file.write(compressed) if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): # Open up a temporary file for saving the level. file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly)): self.mError = self.tr("Could not open temporary file for writing.") return False # Create an output stream for serializing data. out = QDataStream(file) out.setByteOrder(QDataStream.LittleEndian) out.setFloatingPointPrecision(QDataStream.SinglePrecision) # Write out the signature and file header. out.writeInt8(96) # Signature. out.writeInt8(map.layerCount()) ok = False x, ok = Int2(map.property("background_index")) if (not ok): self.mError = self.tr( "You must define a background_index property on the map!") return False out.writeInt8(x) # Write out each layer. for i in range(0, map.layerCount()): layer = map.layerAt(i).asTileLayer() if (not layer): self.mError = self.tr("Can't save non-tile layer!") return False if (not self.writeLayer(out, layer)): return False if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QFile.WriteOnly | QFile.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) out.setCodec("UTF-8") mapWidth = map.width() mapHeight = map.height() # write [header] out << "[header]\n" out << "width=" << str(mapWidth) << "\n" out << "height=" << str(mapHeight) << "\n" out << "tilewidth=" << str(map.tileWidth()) << "\n" out << "tileheight=" << str(map.tileHeight()) << "\n" out << "orientation=" << str(orientationToString(map.orientation())) << "\n" # write all properties for this map for it in map.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" mapDir = QFileInfo(fileName).absoluteDir() out << "[tilesets]\n" for tileset in map.tilesets(): imageSource = tileset.imageSource() source = mapDir.relativeFilePath(imageSource) out << "tileset=" << source \ << "," << str(tileset.tileWidth()) \ << "," << str(tileset.tileHeight()) \ << "," << str(tileset.tileOffset().x()) \ << "," << str(tileset.tileOffset().y()) \ << "\n" out << "\n" gidMapper = GidMapper(map.tilesets()) # write layers for layer in map.layers(): tileLayer = layer.asTileLayer() if tileLayer: out << "[layer]\n" out << "type=" << layer.name() << "\n" out << "data=\n" for y in range(0, mapHeight): for x in range(0, mapWidth): t = tileLayer.cellAt(x, y) id = 0 if (t.tile): id = gidMapper.cellToGid(t) out << id if (x < mapWidth - 1): out << "," if (y < mapHeight - 1): out << "," out << "\n" out << "\n" group = layer.asObjectGroup() if group: for o in group.objects(): if o.type() != '': out << "[" << group.name() << "]\n" # display object name as comment if o.name() != '': out << "# " << o.name() << "\n" out << "type=" << o.type() << "\n" x,y,w,h = 0 if (map.orientation() == Map.Orthogonal): x = o.x()/map.tileWidth() y = o.y()/map.tileHeight() w = o.width()/map.tileWidth() h = o.height()/map.tileHeight() else : x = o.x()/map.tileHeight() y = o.y()/map.tileHeight() w = o.width()/map.tileHeight() h = o.height()/map.tileHeight() out << "location=" << x << "," << y out << "," << w << "," << h << "\n" # write all properties for this object for it in o.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) # Write the header header = map.property("header") for line in header.split("\\n"): out << line << '\n' width = map.width() height = map.height() asciiMap = QList() cachedTiles = QHash() propertyOrder = QList() propertyOrder.append("terrain") propertyOrder.append("object") propertyOrder.append("actor") propertyOrder.append("trap") propertyOrder.append("status") propertyOrder.append("spot") # Ability to handle overflow and strings for display outputLists = False asciiDisplay = ASCII_MIN overflowDisplay = 1 # Add the empty tile numEmptyTiles = 0 emptyTile = Properties() emptyTile["display"] = "?" cachedTiles["?"] = emptyTile # Process the map, collecting used display strings as we go for y in range(0, height): for x in range(0, width): currentTile = cachedTiles["?"] for layer in map.layers(): # If the layer name does not start with one of the tile properties, skip it layerKey = '' for currentProperty in propertyOrder: if (layer.name().lower().startswith( currentProperty.lower())): layerKey = currentProperty break if layerKey == '': continue tileLayer = layer.asTileLayer() objectLayer = layer.asObjectGroup() # Process the Tile Layer if (tileLayer): tile = tileLayer.cellAt(x, y).tile if (tile): currentTile["display"] = tile.property("display") currentTile[layerKey] = tile.property("value") # Process the Object Layer elif (objectLayer): for obj in objectLayer.objects(): if (math.floor(obj.y()) <= y and y <= math.floor(obj.y() + obj.height())): if (math.floor(obj.x()) <= x and x <= math.floor(obj.x() + obj.width())): # Check the Object Layer properties if either display or value was missing if (not obj.property("display").isEmpty()): currentTile["display"] = obj.property( "display") elif (not objectLayer.property( "display").isEmpty()): currentTile[ "display"] = objectLayer.property( "display") if (not obj.property("value").isEmpty()): currentTile[layerKey] = obj.property( "value") elif (not objectLayer.property( "value").isEmpty()): currentTile[ layerKey] = objectLayer.property( "value") # If the currentTile does not exist in the cache, add it if (not cachedTiles.contains(currentTile["display"])): cachedTiles[currentTile["display"]] = currentTile # Otherwise check that it EXACTLY matches the cached one # and if not... elif (currentTile != cachedTiles[currentTile["display"]]): # Search the cached tiles for a match foundInCache = False displayString = QString() for i in cachedTiles.items(): displayString = i[0] currentTile["display"] = displayString if (currentTile == i[1]): foundInCache = True break # If we haven't found a match then find a random display string # and cache it if (not foundInCache): while (True): # First try to use the ASCII characters if (asciiDisplay < ASCII_MAX): displayString = asciiDisplay asciiDisplay += 1 # Then fall back onto integers else: displayString = QString.number(overflowDisplay) overflowDisplay += 1 currentTile["display"] = displayString if (not cachedTiles.contains(displayString)): cachedTiles[displayString] = currentTile break elif (currentTile == cachedTiles[ currentTile["display"]]): break # Check the output type if len(currentTile["display"]) > 1: outputLists = True # Check if we are still the emptyTile if (currentTile == emptyTile): numEmptyTiles += 1 # Finally add the character to the asciiMap asciiMap.append(currentTile["display"]) # Write the definitions to the file out << "-- defineTile section\n" for i in cachedTiles.items(): displayString = i[0] # Only print the emptyTile definition if there were empty tiles if (displayString == "?" and numEmptyTiles == 0): continue # Need to escape " and \ characters displayString.replace('\\', "\\\\") displayString.replace('"', "\\\"") args = self.constructArgs(i[1], propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) out << "defineTile(\"%s\"%s)\n" % (displayString, args) # Check for an ObjectGroup named AddSpot out << "\n-- addSpot section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addspot")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) for y in range(math.floor(obj.y()), math.floor(obj.y() + obj.height())): for y in range(math.floor(obj.x()), math.floor(obj.x() + obj.width())): out << "addSpot({%s, %s}%s)\n" % (x, y, args) # Check for an ObjectGroup named AddZone out << "\n-- addZone section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addzone")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()): args = QString(", %1").arg(args) top_left_x = math.floor(obj.x()) top_left_y = math.floor(obj.y()) bottom_right_x = math.floor(obj.x() + obj.width()) bottom_right_y = math.floor(obj.y() + obj.height()) out << "addZone({%s, %s, %s, %s}%s)" % ( top_left_x, top_left_y, bottom_right_x, bottom_right_y, args) # Write the map returnStart = QString() returnStop = QString() lineStart = QString() lineStop = QString() itemStart = QString() itemStop = QString() seperator = QString() if (outputLists): returnStart = "{" returnStop = "}" lineStart = "{" lineStop = "}," itemStart = "[[" itemStop = "]]" seperator = "," else: returnStart = "[[" returnStop = "]]" lineStart = "" lineStop = "" itemStart = "" itemStop = "" seperator = "" out << "\n-- ASCII map section\n" out << "return " << returnStart << '\n' for y in range(0, height): out << lineStart for x in range(0, width): out << itemStart << asciiMap[x + (y * width)] << itemStop << seperator if (y == height - 1): out << lineStop << returnStop else: out << lineStop << '\n' if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QFile.WriteOnly | QFile.Text)): self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) out.setCodec("UTF-8") mapWidth = map.width() mapHeight = map.height() # write [header] out << "[header]\n" out << "width=" << str(mapWidth) << "\n" out << "height=" << str(mapHeight) << "\n" out << "tilewidth=" << str(map.tileWidth()) << "\n" out << "tileheight=" << str(map.tileHeight()) << "\n" out << "orientation=" << str(orientationToString( map.orientation())) << "\n" # write all properties for this map for it in map.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" mapDir = QFileInfo(fileName).absoluteDir() out << "[tilesets]\n" for tileset in map.tilesets(): imageSource = tileset.imageSource() source = mapDir.relativeFilePath(imageSource) out << "tileset=" << source \ << "," << str(tileset.tileWidth()) \ << "," << str(tileset.tileHeight()) \ << "," << str(tileset.tileOffset().x()) \ << "," << str(tileset.tileOffset().y()) \ << "\n" out << "\n" gidMapper = GidMapper(map.tilesets()) # write layers for layer in map.layers(): tileLayer = layer.asTileLayer() if tileLayer: out << "[layer]\n" out << "type=" << layer.name() << "\n" out << "data=\n" for y in range(0, mapHeight): for x in range(0, mapWidth): t = tileLayer.cellAt(x, y) id = 0 if (t.tile): id = gidMapper.cellToGid(t) out << id if (x < mapWidth - 1): out << "," if (y < mapHeight - 1): out << "," out << "\n" out << "\n" group = layer.asObjectGroup() if group: for o in group.objects(): if o.type() != '': out << "[" << group.name() << "]\n" # display object name as comment if o.name() != '': out << "# " << o.name() << "\n" out << "type=" << o.type() << "\n" x, y, w, h = 0 if (map.orientation() == Map.Orthogonal): x = o.x() / map.tileWidth() y = o.y() / map.tileHeight() w = o.width() / map.tileWidth() h = o.height() / map.tileHeight() else: x = o.x() / map.tileHeight() y = o.y() / map.tileHeight() w = o.width() / map.tileHeight() h = o.height() / map.tileHeight() out << "location=" << x << "," << y out << "," << w << "," << h << "\n" # write all properties for this object for it in o.properties().__iter__(): out << it[0] << "=" << it[1] << "\n" out << "\n" if not file.commit(): self.mError = file.errorString() return False return True
def write(self, map, fileName): file = QSaveFile(fileName) if (not file.open(QIODevice.WriteOnly | QIODevice.Text)) : self.mError = self.tr("Could not open file for writing.") return False out = QTextStream(file) # Write the header header = map.property("header") for line in header.split("\\n"): out << line << '\n' width = map.width() height = map.height() asciiMap = QList() cachedTiles = QHash() propertyOrder = QList() propertyOrder.append("terrain") propertyOrder.append("object") propertyOrder.append("actor") propertyOrder.append("trap") propertyOrder.append("status") propertyOrder.append("spot") # Ability to handle overflow and strings for display outputLists = False asciiDisplay = ASCII_MIN overflowDisplay = 1 # Add the empty tile numEmptyTiles = 0 emptyTile = Properties() emptyTile["display"] = "?" cachedTiles["?"] = emptyTile # Process the map, collecting used display strings as we go for y in range(0, height): for x in range(0, width): currentTile = cachedTiles["?"] for layer in map.layers(): # If the layer name does not start with one of the tile properties, skip it layerKey = '' for currentProperty in propertyOrder: if (layer.name().lower().startswith(currentProperty.lower())) : layerKey = currentProperty break if layerKey == '': continue tileLayer = layer.asTileLayer() objectLayer = layer.asObjectGroup() # Process the Tile Layer if (tileLayer) : tile = tileLayer.cellAt(x, y).tile if (tile) : currentTile["display"] = tile.property("display") currentTile[layerKey] = tile.property("value") # Process the Object Layer elif (objectLayer) : for obj in objectLayer.objects(): if (math.floor(obj.y()) <= y and y <= math.floor(obj.y() + obj.height())) : if (math.floor(obj.x()) <= x and x <= math.floor(obj.x() + obj.width())) : # Check the Object Layer properties if either display or value was missing if (not obj.property("display").isEmpty()) : currentTile["display"] = obj.property("display") elif (not objectLayer.property("display").isEmpty()) : currentTile["display"] = objectLayer.property("display") if (not obj.property("value").isEmpty()) : currentTile[layerKey] = obj.property("value") elif (not objectLayer.property("value").isEmpty()) : currentTile[layerKey] = objectLayer.property("value") # If the currentTile does not exist in the cache, add it if (not cachedTiles.contains(currentTile["display"])) : cachedTiles[currentTile["display"]] = currentTile # Otherwise check that it EXACTLY matches the cached one # and if not... elif (currentTile != cachedTiles[currentTile["display"]]) : # Search the cached tiles for a match foundInCache = False displayString = QString() for i in cachedTiles.items(): displayString = i[0] currentTile["display"] = displayString if (currentTile == i[1]) : foundInCache = True break # If we haven't found a match then find a random display string # and cache it if (not foundInCache) : while (True) : # First try to use the ASCII characters if (asciiDisplay < ASCII_MAX) : displayString = asciiDisplay asciiDisplay += 1 # Then fall back onto integers else : displayString = QString.number(overflowDisplay) overflowDisplay += 1 currentTile["display"] = displayString if (not cachedTiles.contains(displayString)) : cachedTiles[displayString] = currentTile break elif (currentTile == cachedTiles[currentTile["display"]]) : break # Check the output type if len(currentTile["display"]) > 1: outputLists = True # Check if we are still the emptyTile if (currentTile == emptyTile) : numEmptyTiles += 1 # Finally add the character to the asciiMap asciiMap.append(currentTile["display"]) # Write the definitions to the file out << "-- defineTile section\n" for i in cachedTiles.items(): displayString = i[0] # Only print the emptyTile definition if there were empty tiles if (displayString == "?" and numEmptyTiles == 0) : continue # Need to escape " and \ characters displayString.replace('\\', "\\\\") displayString.replace('"', "\\\"") args = self.constructArgs(i[1], propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) out << "defineTile(\"%s\"%s)\n"%(displayString, args) # Check for an ObjectGroup named AddSpot out << "\n-- addSpot section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addspot")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) for y in range(math.floor(obj.y()), math.floor(obj.y() + obj.height())): for y in range(math.floor(obj.x()), math.floor(obj.x() + obj.width())): out << "addSpot({%s, %s}%s)\n"%(x, y, args) # Check for an ObjectGroup named AddZone out << "\n-- addZone section\n" for layer in map.layers(): objectLayer = layer.asObjectGroup() if (objectLayer and objectLayer.name().lower().startsWith("addzone")): for obj in objectLayer.objects(): propertyOrder = QList() propertyOrder.append("type") propertyOrder.append("subtype") propertyOrder.append("additional") args = self.constructArgs(obj.properties(), propertyOrder) if (not args.isEmpty()) : args = QString(", %1").arg(args) top_left_x = math.floor(obj.x()) top_left_y = math.floor(obj.y()) bottom_right_x = math.floor(obj.x() + obj.width()) bottom_right_y = math.floor(obj.y() + obj.height()) out << "addZone({%s, %s, %s, %s}%s)"%(top_left_x, top_left_y, bottom_right_x, bottom_right_y, args) # Write the map returnStart = QString() returnStop = QString() lineStart = QString() lineStop = QString() itemStart = QString() itemStop = QString() seperator = QString() if (outputLists) : returnStart = "{" returnStop = "}" lineStart = "{" lineStop = "}," itemStart = "[[" itemStop = "]]" seperator = "," else : returnStart = "[[" returnStop = "]]" lineStart = "" lineStop = "" itemStart = "" itemStop = "" seperator = "" out << "\n-- ASCII map section\n" out << "return " << returnStart << '\n' for y in range(0, height): out << lineStart for x in range(0, width): out << itemStart << asciiMap[x + (y * width)] << itemStop << seperator if (y == height - 1): out << lineStop << returnStop else : out << lineStop << '\n' if not file.commit(): self.mError = file.errorString() return False return True