More stuff.

This commit is contained in:
2023-03-05 17:33:54 -08:00
parent c973a1a3c6
commit 3d4862adc0
25 changed files with 345 additions and 69 deletions

View File

@ -0,0 +1,19 @@
package gay.pizza.foundation.heimdall.load
import gay.pizza.foundation.heimdall.export.ExportedBlock
class ExportedBlockTable {
private val internalBlocks = mutableListOf<ExportedBlock>()
val blocks: List<ExportedBlock>
get() = internalBlocks
fun index(block: ExportedBlock): Int {
val existing = internalBlocks.indexOf(block)
if (existing >= 0) {
return existing
}
internalBlocks.add(block)
return internalBlocks.size - 1
}
}

View File

@ -0,0 +1,69 @@
package gay.pizza.foundation.heimdall.load
import kotlinx.serialization.Serializable
import kotlin.math.absoluteValue
@Serializable
data class OffsetList<L: List<T>, T>(
val offset: Int,
val data: L
) {
fun <K> toMap(toKey: (Int) -> K): Map<K, T> {
val map = mutableMapOf<K, T>()
for ((index, value) in data.withIndex()) {
val real = index + offset
val key = toKey(real)
map[key] = value
}
return map
}
fun <R> map(value: (T) -> R): ImmutableOffsetList<R> =
ImmutableOffsetList(offset, MutableList(data.size) { index -> value(data[index]) })
fun eachRealIndex(block: (Int, T) -> Unit) {
for ((fakeIndex, value) in data.withIndex()) {
val realIndex = fakeIndex + offset
block(realIndex, value)
}
}
companion object {
fun <K, T, V> transform(
map: Map<K, T>,
minAndTotal: (Map<K, T>) -> Pair<Int, Int>,
keyToInt: (K) -> Int,
valueTransform: (T) -> V
): ImmutableOffsetList<V?> {
val (min, total) = minAndTotal(map)
val offset = if (min < 0) min.absoluteValue else 0
val list = MutableList<V?>(total) { null }
for ((key, value) in map) {
val pkey = keyToInt(key)
val rkey = pkey + offset
list[rkey] = valueTransform(value)
}
return OffsetList(if (min < 0) min else 0, list)
}
}
}
typealias ImmutableOffsetList<T> = OffsetList<List<T>, T>
@Serializable
class WorldLoadCompactWorld(
override val name: String,
val data: ImmutableOffsetList<ImmutableOffsetList<ImmutableOffsetList<Int?>?>?>
) : WorldLoadWorld() {
override fun crawl(block: (Long, Long, Long, Int) -> Unit) {
data.eachRealIndex { x, zList ->
zList?.eachRealIndex { z, yList ->
yList?.eachRealIndex { y, index ->
if (index != null) {
block(x.toLong(), z.toLong(), y.toLong(), index)
}
}
}
}
}
}

View File

@ -1,8 +1,10 @@
package gay.pizza.foundation.heimdall.load
import gay.pizza.foundation.heimdall.export.ExportedBlock
import kotlinx.serialization.Serializable
@Serializable
class WorldLoadFormat(
val blockLookupTable: List<ExportedBlock>,
val worlds: Map<String, WorldLoadWorld>
)

View File

@ -0,0 +1,64 @@
package gay.pizza.foundation.heimdall.load
import kotlinx.serialization.Serializable
import kotlin.math.absoluteValue
@Serializable
class WorldLoadSimpleWorld(
override val name: String,
val blocks: Map<Long, Map<Long, Map<Long, Int>>>
) : WorldLoadWorld() {
fun compact(): WorldLoadCompactWorld {
val list = OffsetList.transform(
blocks,
minAndTotal = ::minAndTotal,
keyToInt = Long::toInt,
valueTransform = { zValue ->
OffsetList.transform(
zValue,
minAndTotal = ::minAndTotal,
keyToInt = Long::toInt,
valueTransform = { yValue ->
OffsetList.transform(
yValue,
minAndTotal = ::minAndTotal,
keyToInt = Long::toInt,
valueTransform = { it }
)
}
)
})
return WorldLoadCompactWorld(name, list)
}
private fun <T> minAndTotal(map: Map<Long, T>): Pair<Int, Int> {
val keys = map.keys
if (keys.isEmpty()) {
return 0 to 0
}
val min = keys.min()
val max = keys.max()
var total = 1L
if (max > 0) {
total += max
}
if (min < 0) {
total += min.absoluteValue
}
return min.toInt() to total.toInt()
}
override fun crawl(block: (Long, Long, Long, Int) -> Unit) {
for ((x, zBlocks) in blocks) {
for ((z, yBlocks) in zBlocks) {
for ((y, index) in yBlocks) {
block(x, z, y, index)
}
}
}
}
}

View File

@ -1,10 +1,10 @@
package gay.pizza.foundation.heimdall.load
import gay.pizza.foundation.heimdall.export.ExportedBlock
import kotlinx.serialization.Serializable
@Serializable
class WorldLoadWorld(
val name: String,
val blocks: Map<Long, Map<Long, Map<Long, ExportedBlock>>>
)
sealed class WorldLoadWorld {
abstract val name: String
abstract fun crawl(block: (Long, Long, Long, Int) -> Unit)
}