KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/defs/dungeon/TiledTileSets.kt

74 lines
2.3 KiB
Kotlin

package ru.dbotthepony.kstarbound.defs.dungeon
import com.google.gson.JsonObject
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import ru.dbotthepony.kstarbound.json.builder.JsonFactory
import ru.dbotthepony.kstarbound.util.AssetPathStack
class TiledTileSets(entries: List<Entry>) {
@JsonFactory
data class Entry(
val firstgid: Int,
// not asset path because of funky names which can't be properly
// untangled by AssetPath's adapter code
val source: String,
)
private var front: Int2ObjectOpenHashMap<Pair<DungeonTile, JsonObject>>
private var back: Int2ObjectOpenHashMap<Pair<DungeonTile, JsonObject>>
init {
val mapped = entries.map { (firstgid, source) ->
// Tiled stores tileset paths relative to the map file, which can go below
// the assets root if it's referencing a tileset in another asset package.
// The solution chosen here is to ignore everything in the path up until a
// known path segment, e.g.:
// "source" : "..\/..\/..\/..\/packed\/tilesets\/packed\/materials.json"
// We ignore everything up until the 'tilesets' path segment, and the asset
// we actually load is located at:
// /tilesets/packed/materials.json
val actualSource: String
val split = source.lowercase().lastIndexOf("/tilesets/")
if (split != -1) {
actualSource = source.substring(split)
} else {
actualSource = AssetPathStack.remap(source)
}
firstgid to TiledTileSet.load(actualSource)
}
front = Int2ObjectOpenHashMap<Pair<DungeonTile, JsonObject>>(mapped.sumOf { it.second.size })
back = Int2ObjectOpenHashMap<Pair<DungeonTile, JsonObject>>(mapped.sumOf { it.second.size })
for ((firstgid, set) in mapped) {
for (i in 0 until set.size) {
front.put(firstgid + i, set.front[i] ?: throw NullPointerException("aeiou"))
back.put(firstgid + i, set.back[i] ?: throw NullPointerException("aeiou"))
}
}
}
fun getFront(gid: Int): DungeonTile {
return front[gid]?.first ?: DungeonTile.EMPTY
}
fun getBack(gid: Int): DungeonTile {
return back[gid]?.first ?: DungeonTile.CLEAR
}
fun getFrontData(gid: Int): JsonObject {
return front[gid]?.second ?: JsonObject()
}
fun getBackData(gid: Int): JsonObject {
return back[gid]?.second ?: JsonObject()
}
fun free() {
front = Int2ObjectOpenHashMap()
back = Int2ObjectOpenHashMap()
}
}