mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 03:24:06 +09:00
the-flattening wip
This commit is contained in:
@@ -9,10 +9,12 @@ import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.gameitem.ItemID
|
||||
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
|
||||
import net.torvald.terrarum.printStackTrace
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.serialise.ReadLayerDataZip
|
||||
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
|
||||
import net.torvald.util.SortedArrayList
|
||||
import org.dyn4j.geometry.Vector2
|
||||
import kotlin.math.absoluteValue
|
||||
@@ -79,7 +81,7 @@ open class GameWorld : Disposable {
|
||||
/**
|
||||
* Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised.
|
||||
*/
|
||||
private val wiringBlocks: HashMap<BlockAddress, Int>
|
||||
private val wiringBlocks: HashMap<BlockAddress, ItemID>
|
||||
|
||||
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
|
||||
//physics
|
||||
@@ -100,6 +102,11 @@ open class GameWorld : Disposable {
|
||||
open var TIME_T: Long = 0L
|
||||
open var dayLength: Int = 86400
|
||||
|
||||
@TEMzPayload("TMaP", TEMzPayload.EXTERNAL_JSON)
|
||||
val tileNumberToNameMap: HashMap<Int, ItemID>
|
||||
// does not go to the savefile
|
||||
val tileNameToNumberMap: HashMap<ItemID, Int>
|
||||
|
||||
|
||||
constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) {
|
||||
if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)")
|
||||
@@ -133,6 +140,14 @@ open class GameWorld : Disposable {
|
||||
creationTime = creationTIME_T
|
||||
lastPlayTime = lastPlayTIME_T
|
||||
this.totalPlayTime = totalPlayTime
|
||||
|
||||
|
||||
tileNumberToNameMap = HashMap<Int, ItemID>()
|
||||
tileNameToNumberMap = HashMap<ItemID, Int>()
|
||||
CreateTileAtlas.tags.forEach {
|
||||
tileNumberToNameMap[it.value.tileNumber] = it.key
|
||||
tileNameToNumberMap[it.key] = it.value.tileNumber
|
||||
}
|
||||
}
|
||||
|
||||
internal constructor(worldIndex: Int, layerData: ReadLayerDataZip.LayerData, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) {
|
||||
@@ -160,6 +175,17 @@ open class GameWorld : Disposable {
|
||||
creationTime = creationTIME_T
|
||||
lastPlayTime = lastPlayTIME_T
|
||||
this.totalPlayTime = totalPlayTime
|
||||
|
||||
tileNumberToNameMap = layerData.tileNumberToNameMap
|
||||
|
||||
// TODO perform renaming of tile layers
|
||||
|
||||
// after the renaming, update the name maps
|
||||
tileNameToNumberMap = HashMap<ItemID, Int>()
|
||||
CreateTileAtlas.tags.forEach {
|
||||
tileNumberToNameMap[it.value.tileNumber] = it.key
|
||||
tileNameToNumberMap[it.key] = it.value.tileNumber
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,12 +198,34 @@ open class GameWorld : Disposable {
|
||||
|
||||
fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1))
|
||||
|
||||
fun getTileFromWall(rawX: Int, rawY: Int): Int {
|
||||
/**
|
||||
* @return ItemID
|
||||
*/
|
||||
fun getTileFromWall(rawX: Int, rawY: Int): ItemID {
|
||||
val (x, y) = coerceXY(rawX, rawY)
|
||||
return tileNumberToNameMap[layerWall.unsafeGetTile(x, y)]!!
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ItemID
|
||||
*/
|
||||
fun getTileFromTerrain(rawX: Int, rawY: Int): ItemID {
|
||||
val (x, y) = coerceXY(rawX, rawY)
|
||||
return tileNumberToNameMap[layerTerrain.unsafeGetTile(x, y)]!!
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Int
|
||||
*/
|
||||
fun getTileNumFromWall(rawX: Int, rawY: Int): Int {
|
||||
val (x, y) = coerceXY(rawX, rawY)
|
||||
return layerWall.unsafeGetTile(x, y)
|
||||
}
|
||||
|
||||
fun getTileFromTerrain(rawX: Int, rawY: Int): Int {
|
||||
/**
|
||||
* @return Int
|
||||
*/
|
||||
fun getTileNumFromTerrain(rawX: Int, rawY: Int): Int {
|
||||
val (x, y) = coerceXY(rawX, rawY)
|
||||
return layerTerrain.unsafeGetTile(x, y)
|
||||
}
|
||||
@@ -191,17 +239,17 @@ open class GameWorld : Disposable {
|
||||
* *
|
||||
* @param y
|
||||
* *
|
||||
* @param tilenum Item id of the wall block. Less-than-4096-value is permitted.
|
||||
* @param itemID Tile as in ItemID
|
||||
*/
|
||||
fun setTileWall(x: Int, y: Int, tilenum: Int) {
|
||||
fun setTileWall(x: Int, y: Int, itemID: ItemID) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val tilenum = tilenum % TILES_SUPPORTED // does work without this, but to be safe...
|
||||
val tilenum = tileNameToNumberMap[itemID]!!
|
||||
|
||||
val oldWall = getTileFromWall(x, y)
|
||||
layerWall.unsafeSetTile(x, y, tilenum)
|
||||
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
||||
|
||||
Terrarum.ingame?.queueWallChangedEvent(oldWall, tilenum, LandUtil.getBlockAddr(this, x, y))
|
||||
Terrarum.ingame?.queueWallChangedEvent(oldWall, itemID, LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,23 +261,24 @@ open class GameWorld : Disposable {
|
||||
* *
|
||||
* @param y
|
||||
* *
|
||||
* @param tilenum Item id of the terrain block, <4096
|
||||
* @param itemID Tile as in ItemID
|
||||
*/
|
||||
fun setTileTerrain(x: Int, y: Int, tilenum: Int) {
|
||||
fun setTileTerrain(x: Int, y: Int, itemID: ItemID) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val tilenum = tileNameToNumberMap[itemID]!!
|
||||
|
||||
val oldTerrain = getTileFromTerrain(x, y)
|
||||
layerTerrain.unsafeSetTile(x, y, tilenum)
|
||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
terrainDamages.remove(blockAddr)
|
||||
|
||||
if (BlockCodex[tilenum].isSolid) {
|
||||
if (BlockCodex[itemID].isSolid) {
|
||||
fluidFills.remove(blockAddr)
|
||||
fluidTypes.remove(blockAddr)
|
||||
}
|
||||
// fluid tiles-item should be modified so that they will also place fluid onto their respective map
|
||||
|
||||
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, tilenum, LandUtil.getBlockAddr(this, x, y))
|
||||
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, itemID, LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
/*fun setTileWire(x: Int, y: Int, tile: Byte) {
|
||||
@@ -241,8 +290,9 @@ open class GameWorld : Disposable {
|
||||
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
||||
}*/
|
||||
|
||||
fun getWiringBlocks(x: Int, y: Int): Int {
|
||||
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
|
||||
fun getWiringBlocks(x: Int, y: Int): ItemID {
|
||||
return Block.AIR // TODO
|
||||
//return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), Block.AIR)
|
||||
}
|
||||
|
||||
fun getAllConduitsFrom(x: Int, y: Int): SortedArrayList<WiringNode>? {
|
||||
@@ -258,7 +308,9 @@ open class GameWorld : Disposable {
|
||||
}
|
||||
|
||||
fun addNewConduitTo(x: Int, y: Int, node: WiringNode) {
|
||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
// TODO needs new conduit storage scheme
|
||||
|
||||
/*val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
|
||||
// check for existing type of conduit
|
||||
// if there's no duplicate...
|
||||
@@ -270,10 +322,10 @@ open class GameWorld : Disposable {
|
||||
}
|
||||
else {
|
||||
TODO("need overwriting policy for existing conduit node")
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
|
||||
fun getTileFrom(mode: Int, x: Int, y: Int): ItemID {
|
||||
if (mode == TERRAIN) {
|
||||
return getTileFromTerrain(x, y)
|
||||
}
|
||||
@@ -287,8 +339,8 @@ open class GameWorld : Disposable {
|
||||
throw IllegalArgumentException("illegal mode input: " + mode.toString())
|
||||
}
|
||||
|
||||
fun terrainIterator(): Iterator<Int> {
|
||||
return object : Iterator<Int> {
|
||||
fun terrainIterator(): Iterator<ItemID> {
|
||||
return object : Iterator<ItemID> {
|
||||
|
||||
private var iteratorCount = 0
|
||||
|
||||
@@ -296,7 +348,7 @@ open class GameWorld : Disposable {
|
||||
return iteratorCount < width * height
|
||||
}
|
||||
|
||||
override fun next(): Int {
|
||||
override fun next(): ItemID {
|
||||
val y = iteratorCount / width
|
||||
val x = iteratorCount % width
|
||||
// advance counter
|
||||
@@ -308,15 +360,15 @@ open class GameWorld : Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
fun wallIterator(): Iterator<Int> {
|
||||
return object : Iterator<Int> {
|
||||
fun wallIterator(): Iterator<ItemID> {
|
||||
return object : Iterator<ItemID> {
|
||||
|
||||
private var iteratorCount = 0
|
||||
|
||||
override fun hasNext(): Boolean =
|
||||
iteratorCount < width * height
|
||||
|
||||
override fun next(): Int {
|
||||
override fun next(): ItemID {
|
||||
val y = iteratorCount / width
|
||||
val x = iteratorCount % width
|
||||
// advance counter
|
||||
@@ -351,7 +403,7 @@ open class GameWorld : Disposable {
|
||||
|
||||
// remove tile from the world
|
||||
if (terrainDamages[addr] ?: 0f >= BlockCodex[getTileFromTerrain(x, y)].strength) {
|
||||
setTileTerrain(x, y, 0)
|
||||
setTileTerrain(x, y, Block.AIR)
|
||||
terrainDamages.remove(addr)
|
||||
return true
|
||||
}
|
||||
@@ -380,7 +432,7 @@ open class GameWorld : Disposable {
|
||||
|
||||
// remove tile from the world
|
||||
if (wallDamages[addr]!! >= BlockCodex[getTileFromWall(x, y)].strength) {
|
||||
setTileWall(x, y, 0)
|
||||
setTileWall(x, y, Block.AIR)
|
||||
wallDamages.remove(addr)
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user