Blame | Last modification | View Log | Download
import java.io.Fileimport java.util.*import kotlin.collections.ArrayList// gradlew desktop:dist for jar create in path ..../ desktop / build / libs// автор тайледа 100% редактор делал изначально не для геймдэва - он не логичен пиздец !!!// есть выделение части слоя, но его нельзя двигать блять !!! Нужно удалять выделение и вставлять куда требуется !!!!// ятаворотибалconst val LEVEL_WIDTH = 16const val LEVEL_HEIGHT = 12@ExperimentalUnsignedTypesclass TiledConversion(val map: File, val dstSpriteStorage: String, val dstLevelsStorage: String) {val mapString = map.readText(Charsets.ISO_8859_1)val mapProperties = "(<map)\\s.+(>)?".toRegex().find(mapString)?.value ?: error("Wrong map properties.")val mapWidth ="(?<= width=\")\\d+(?=\")?".toRegex().find(mapProperties)?.value?.toInt() ?: error("Wrong map WIDTH:")val mapHeight ="(?<= height=\")\\d+(?=\")?".toRegex().find(mapProperties)?.value?.toInt() ?: error("Wrong map HEIGHT:")val columns = mapWidth / LEVEL_WIDTHval rows = mapHeight / LEVEL_HEIGHTval mapLine = columns * LEVEL_WIDTHval tilesId ="(?<=tile id=\")\\d+(?!\")?".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(mapString).toList().map { it.value.toInt() }val tileset ="(?<=source=\")[a-zA-Z0-9_./]+(?!\")?".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(mapString).toList().map { it.value }val mapData ="(?<=<data encoding=\"csv\">)[0-9,\\s]+(?=</data>)?".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(mapString).toList().map { it.value.split(",").map { d -> d.trim().toInt() } }val wallsLayer = mapData[0]// val objectsLayer = MutableList(mapData[1].size) { mapData[1][it] }val objectsLayer = mapData[1].toMutableList().map { it - 1 }val levelAsmData = StringBuilder()var levelAddressesOffset = 0val levelAddresses = StringBuilder("LEVELS_MAP:\tdw ")fun exec() {val spritesAsmData = StringBuilder()val spritesAddressesOffset = ArrayList<Int>()println("Tiles ID`s:")val indices = getIndices()indices.forEachIndexed { newId, arrayInt ->arrayInt.forEach { oldId ->Collections.replaceAll(objectsLayer, oldId, newId)}}prtLine()val names ="(?:../)\\S+(?=\"/>)".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(mapString).map { it.value }.toList()val labels = names.map {val r = it.split("/")r.last().toUpperCase().replace(".", "_")}var imgId = 0var offset = 0indices.forEachIndexed { id, arrayInt ->spritesAddressesOffset.add(offset)spritesAsmData.append("${labels[imgId]}_ID:\tequ $id\n")arrayInt.forEach { _ ->// val file = File(names[imgId]).readLines(Charsets.ISO_8859_1)val file = File(names[imgId]).readText(Charsets.ISO_8859_1).split("\n")// println(f.size)val width = file[1].toInt()val height = file[2].toInt()offset += (width / 8) * heightval data = file[3].toByteArray(Charsets.ISO_8859_1).map { it.toUByte().inv() }.toString().replace("[\\[\\] ]+".toRegex(), "")spritesAsmData.append("${labels[imgId]}:\tdb $data\n")imgId++}}val spritesResult = StringBuilder()spritesResult.append("SPRITE_MAP:\tdw ${spritesAddressesOffset.toString().replace("[\\[\\] ]+".toRegex(), "")}\n").append(spritesAsmData)println(spritesResult)prtLine()val layers = ArrayList<Pair<List<Int>, List<Int>>>()repeat(rows) { r ->repeat(columns) { c ->// val startLevelAddress = r * (mapWidth * LEVEL_HEIGHT) + c * LEVEL_WIDTH// val levelId = r * rows + clayers.add(Pair(cut(wallsLayer, mapWidth, c, r),cut(objectsLayer, mapWidth, c, r)))}}// отбрасываем пустые уровниlayers.filter { it.second.any { int -> int != -1 } }.forEach {levelAsmData.append(tiledConvertToASMFile(it.first, it.second))}val levelsResult = StringBuilder()levelsResult.append(levelAddresses.dropLast(1)).append("\nLEVELS_BEGIN:").append(levelAsmData)println(levelsResult)saveFile(dstSpriteStorage, spritesResult)saveFile(dstLevelsStorage, levelsResult)}//-----------------------------------------------------------private fun tiledConvertToASMFile(walls: List<Int>, objects: List<Int>): String {val wallsString = StringBuilder("\n\tdb ")val objectsString = StringBuilder("\n\tdb ")levelAddresses.append("$levelAddressesOffset,")repeat(24) { line ->var byte = 0var value = 32768repeat(8) { b ->val id = b + (line * 8)byte = if (walls[id] == 0) byte else byte or valuevalue = value shr 1if (objects[id] != -1) {objectsString.append("$id,${objects[id]},") // -1 !?!levelAddressesOffset += 2}}wallsString.append("${byte shr 8 and 255},")}objectsString.append("255")levelAddressesOffset += 24 + 1 // +1 =255 завершающий байтreturn "${wallsString.dropLast(1)}${objectsString}"}private fun getIndices(): ArrayList<ArrayList<Int>> {val indices = ArrayList<ArrayList<Int>>()val tileset = "(?<=<tileset).+(?=</tileset>)".toRegex(RegexOption.DOT_MATCHES_ALL).find(mapString)?.value?: error("Tileset is empty !!!")// индексы из тайлсета, они отличаются от индексов карты - на карте эти индексы +1 (захуярить афтора Tiled map editor)val tileIds ="(?<=<tile id=\")\\d+(?=\">)".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(tileset).map { it.value.trim() }.toList()val tileNames ="(?<=source=\")\\S+(?=\")".toRegex(RegexOption.DOT_MATCHES_ALL).findAll(tileset).map { it.value.trim() }.toList()var preName: String? = null// var count = 0tileNames.forEachIndexed { id, name ->val n = "\\S+(?=_\\d+)".toRegex().find(name)?.value ?: nameif (n != preName) {indices.add(arrayListOf())preName = n// println(count++)// println("$preName, $n")}indices.last().add(tileIds[id].trimIndent().toInt())}indices.forEachIndexed { id, i ->println("$id: ${i.toString()}")}return indices}// вырезает (чанк) уровень 16х12 из картыprivate fun cut(src: List<Int>, srcWidth: Int, x: Int, y: Int): List<Int> {val a = ArrayList<Int>()val id = y * (srcWidth * LEVEL_HEIGHT) + x * LEVEL_WIDTHrepeat(LEVEL_HEIGHT) { h ->repeat(LEVEL_WIDTH) { w ->a.add(src[id + h * srcWidth + w])}}return a}private fun prtLine() {println("----------------------------------------------------------------------------------------------")}private fun saveFile(fileName: String, data: StringBuilder) = File(fileName).writeText(data.toString())}