From 1f1d6f1eda6bde13e0f42e7b55a8c913ae29f86a Mon Sep 17 00:00:00 2001 From: Minjae Song Date: Wed, 12 Dec 2018 23:29:30 +0900 Subject: [PATCH] preparing fluid updater: debug water bucket --- src/net/torvald/terrarum/ModMgr.kt | 2 + .../torvald/terrarum/UIItemInventoryElem.kt | 4 + .../torvald/terrarum/blockproperties/Fluid.kt | 13 ++ .../torvald/terrarum/gameworld/GameWorld.kt | 22 +- .../terrarum/itemproperties/ItemCodex.kt | 11 +- .../torvald/terrarum/modulebasegame/Ingame.kt | 2 +- .../gameactors/ActorInventory.kt | 3 + .../gameactors/PlayerBuilderSigrid.kt | 1 + .../gameworld/WorldSimulator.kt | 209 ++---------------- 9 files changed, 67 insertions(+), 200 deletions(-) create mode 100644 src/net/torvald/terrarum/blockproperties/Fluid.kt diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index ab9fa276c..1625fb854 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -229,6 +229,8 @@ object ModMgr { val className = it["classname"].toString() val itemID = it["id"].toInt() + printdbg(this, "Reading item #$itemID with className $className") + val loadedClass = Class.forName(className) val loadedClassConstructor = loadedClass.getConstructor(ItemID::class.java) val loadedClassInstance = loadedClassConstructor.newInstance(itemID) diff --git a/src/net/torvald/terrarum/UIItemInventoryElem.kt b/src/net/torvald/terrarum/UIItemInventoryElem.kt index 42efed3df..32202e72e 100644 --- a/src/net/torvald/terrarum/UIItemInventoryElem.kt +++ b/src/net/torvald/terrarum/UIItemInventoryElem.kt @@ -171,6 +171,10 @@ class UIItemInventoryElem( // equip da shit val itemEquipSlot = item!!.equipPosition + if (itemEquipSlot == GameItem.EquipPosition.NULL) { + TODO("Equip position is NULL, does this mean it's single-consume items like a potion?") + } + val player = (Terrarum.ingame!! as Ingame).actorNowPlaying if (player == null) return false diff --git a/src/net/torvald/terrarum/blockproperties/Fluid.kt b/src/net/torvald/terrarum/blockproperties/Fluid.kt new file mode 100644 index 000000000..c3207edf4 --- /dev/null +++ b/src/net/torvald/terrarum/blockproperties/Fluid.kt @@ -0,0 +1,13 @@ +package net.torvald.terrarum.blockproperties + +/** + * Created by minjaesong on 2016-08-06. + */ +object Fluid { + + val NULL = 0 + + val WATER = 1 + val STATIC_WATER = -1 + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 8408b9240..865567a88 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.blockproperties.BlockCodex +import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator import net.torvald.terrarum.serialise.ReadLayerDataLzma import org.dyn4j.geometry.Vector2 @@ -341,9 +342,24 @@ open class GameWorld { fun setFluid(x: Int, y: Int, fluidType: Int, fill: Float) { val addr = LandUtil.getBlockAddr(this, x, y) - fluidTypes[addr] = fluidType - fluidFills[addr] = fill - setTileTerrain(x, y, Block.FLUID_MARKER) + if (fill <= WorldSimulator.FLUID_MIN_MASS) { + fluidTypes.remove(addr) + fluidFills.remove(addr) + setTileTerrain(x, y, 0) + } + else { + fluidTypes[addr] = fluidType + fluidFills[addr] = fill + setTileTerrain(x, y, Block.FLUID_MARKER) + } + } + + fun getFluid(x: Int, y: Int): Pair? { + val addr = LandUtil.getBlockAddr(this, x, y) + val fill = fluidFills[addr] + val type = fluidTypes[addr] + + return if (type == null) null else Pair(type!!, fill!!) } diff --git a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt index 624b755b6..bf87679ee 100644 --- a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt +++ b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.KVHashMap import net.torvald.terrarum.modulebasegame.gameactors.CanBeAnItem import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarum.modulebasegame.Ingame @@ -32,12 +33,14 @@ object ItemCodex { private val itemImagePlaceholder = TextureRegion(Texture("./assets/item_kari_24.tga")) - //private val ingame = Terrarum.ingame!! as Ingame + //private val ingame = Terrarum.ingame!! as Ingame // WARNING you can't put this here, ExceptionInInitializerError // TODO: when generalised, there's no guarantee that blocks will be used as an item. Write customised item prop loader and init it on the Ingame init { + //val ingame = Terrarum.ingame!! as Ingame // WARNING you can't put this here, ExceptionInInitializerError + /*println("[ItemCodex] recording item ID ") @@ -186,8 +189,12 @@ object ItemCodex { override val isDynamic: Boolean = false override val material: Material = Material(1,1,1,1,1,1,1,1,1,1.0) + override val equipPosition: Int = EquipPosition.HAND_GRIP + override fun startSecondaryUse(delta: Float): Boolean { - return super.startSecondaryUse(delta) + val ingame = Terrarum.ingame!! as Ingame // must be in here + ingame.world.setFluid(Terrarum.mouseTileX, Terrarum.mouseTileY, Fluid.WATER, 1f) + return true } } diff --git a/src/net/torvald/terrarum/modulebasegame/Ingame.kt b/src/net/torvald/terrarum/modulebasegame/Ingame.kt index a43f91bb9..9278a93c5 100644 --- a/src/net/torvald/terrarum/modulebasegame/Ingame.kt +++ b/src/net/torvald/terrarum/modulebasegame/Ingame.kt @@ -519,7 +519,7 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { /////////////////////////// BlockPropUtil.dynamicLumFuncTickClock() world.updateWorldTime(delta) - //WorldSimulator(player, delta) + WorldSimulator.invoke(actorNowPlaying, delta) WeatherMixer.update(delta, actorNowPlaying, world) BlockStats.update() diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt index 10f3ed1a4..fc08c1011 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt @@ -177,6 +177,9 @@ class ActorInventory(val actor: Pocketed, var maxCapacity: Int, var capacityMode if (item.stackable && !item.isDynamic) { remove(item, 1) } + else if (item.isUnique) { + return // don't consume a bike! + } else { val newItem: GameItem diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt index d87021da9..4bd1d6b31 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderSigrid.kt @@ -95,6 +95,7 @@ object PlayerBuilderSigrid { blocks.forEach { p.addItem(it, 999) } walls.forEach { p.addItem(it + 4096, 999) } p.inventory.add(ItemCodex.ITEM_STATIC.first) + p.inventory.add(9000) diff --git a/src/net/torvald/terrarum/modulebasegame/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/modulebasegame/gameworld/WorldSimulator.kt index 4f360ac9a..e25bbe4bc 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameworld/WorldSimulator.kt @@ -8,6 +8,7 @@ import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.BlockCodex +import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.gameworld.FluidCodex import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.Ingame @@ -17,6 +18,9 @@ import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid * Created by minjaesong on 2016-08-03. */ object WorldSimulator { + + // FLUID-RELATED STUFFS // + /** * In tiles; * square width/height = field * 2 @@ -24,11 +28,14 @@ object WorldSimulator { const val FLUID_UPDATING_SQUARE_RADIUS = 64 // larger value will have dramatic impact on performance const private val DOUBLE_RADIUS = FLUID_UPDATING_SQUARE_RADIUS * 2 - private val fluidMap = Array(DOUBLE_RADIUS, { ByteArray(DOUBLE_RADIUS) }) - private val fluidTypeMap = Array(DOUBLE_RADIUS, { ByteArray(DOUBLE_RADIUS) }) + private val fluidMap = Array(DOUBLE_RADIUS, { FloatArray(DOUBLE_RADIUS) }) + private val fluidTypeMap = Array(DOUBLE_RADIUS, { IntArray(DOUBLE_RADIUS) }) - const val DISPLACE_CAP = 4 - const val FLUID_MAX = 16 + const val FLUID_MAX_MASS = 1f // The normal, un-pressurized mass of a full water cell + const val FLUID_MAX_COMP = 0.02f // How much excess water a cell can store, compared to the cell above it + const val FLUID_MIN_MASS = 0.0001f //Ignore cells that are almost dry + + // END OF FLUID-RELATED STUFFS var updateXFrom = 0 var updateXTo = 0 @@ -65,67 +72,6 @@ object WorldSimulator { // build fluidmap // //////////////////// purgeFluidMap() - worldToFluidMap(world) - - - ///////////////////////////////////////////////////////////// - // displace fluids. Record displacements into the fluidMap // - ///////////////////////////////////////////////////////////// - for (y in updateYFrom..updateYTo) { - for (x in updateXFrom..updateXTo) { - val tile = world.getTileFromTerrain(x, y) ?: Block.STONE - val tileBottom = world.getTileFromTerrain(x, y + 1) ?: Block.STONE - val tileLeft = world.getTileFromTerrain(x - 1, y) ?: Block.STONE - val tileRight = world.getTileFromTerrain(x + 1, y) ?: Block.STONE - if (tile.isFluid()) { - - // move down if not obstructed - /*if (!tileBottom.isSolid()) { - val drainage = drain(world, x, y, DISPLACE_CAP) - pour(world, x, y + 1, drainage) - } - // left and right both open - else if (!tileLeft.isSolid() && !tileRight.isSolid()) { - // half-breaker - val moreToTheRight = HQRNG().nextBoolean() - val displacement = drain(world, x, y, DISPLACE_CAP) - - if (displacement.isEven()) { - pour(world, x - 1, y, displacement shr 1) - pour(world, x + 1, y, displacement shr 1) - } - else { - pour(world, x - 1, y, (displacement shr 1) + if (moreToTheRight) 0 else 1) - pour(world, x + 1, y, (displacement shr 1) + if (moreToTheRight) 1 else 0) - } - } - // left open - else if (!tileLeft.isSolid()) { - val displacement = drain(world, x, y, DISPLACE_CAP) - pour(world, x - 1, y, displacement) - } - // right open - else if (!tileRight.isSolid()) { - val displacement = drain(world, x, y, DISPLACE_CAP) - pour(world, x + 1, y, displacement) - } - // nowhere open; do default (fill top) - else { - pour(world, x, y - 1, DISPLACE_CAP) - }*/ - if (!tileBottom.isSolid()) { - pour(x, y + 1, drain(x, y, FLUID_MAX)) - } - - } - } - } - - - ///////////////////////////////////////////////////// - // replace fluids in the map according to fluidMap // - ///////////////////////////////////////////////////// - fluidMapToWorld(world) } @@ -134,7 +80,7 @@ object WorldSimulator { * falling, each tiles are displaced by ONLY ONE TILE below. */ fun displaceFallables(delta: Float) { - for (y in updateYFrom..updateYTo) { + /*for (y in updateYFrom..updateYTo) { for (x in updateXFrom..updateXTo) { val tile = world.getTileFromTerrain(x, y) ?: Block.STONE val tileBelow = world.getTileFromTerrain(x, y + 1) ?: Block.STONE @@ -155,7 +101,7 @@ object WorldSimulator { } } } - } + }*/ } @@ -163,143 +109,18 @@ object WorldSimulator { } - - fun drawFluidMapDebug(batch: SpriteBatch) { - batch.color = colourWater - - for (y in 0..fluidMap.size - 1) { - for (x in 0..fluidMap[0].size - 1) { - val data = fluidMap[y][x] - if (BlocksDrawer.tileInCamera(x + updateXFrom, y + updateYFrom)) { - if (data == 0.toByte()) - batch.color = colourNone - else - batch.color = colourWater - - Terrarum.fontSmallNumbers.draw(batch, - data.toString(), - updateXFrom.plus(x).times(FeaturesDrawer.TILE_SIZE).toFloat() - + if (data < 10) 4f else 0f, - updateYFrom.plus(y).times(FeaturesDrawer.TILE_SIZE) + 4f - ) - } - - - //if (data > 0) println(data) - } - } - } - private fun purgeFluidMap() { for (y in 1..DOUBLE_RADIUS) { for (x in 1..DOUBLE_RADIUS) { - fluidMap[y - 1][x - 1] = 0 - fluidTypeMap[y - 1][x - 1] = 0 + fluidMap[y - 1][x - 1] = 0f + fluidTypeMap[y - 1][x - 1] = Fluid.NULL } } } - private fun worldToFluidMap(world: GameWorld) { - for (y in updateYFrom..updateYTo) { - for (x in updateXFrom..updateXTo) { - val tile = world.getTileFromTerrain(x, y) ?: Block.STONE - if (tile.isFluid()) { - fluidMap[y - updateYFrom][x - updateXFrom] = tile.fluidLevel().toByte() - fluidTypeMap[y - updateYFrom][x - updateXFrom] = tile.fluidType().toByte() - } - } - } - } - private fun fluidMapToWorld(world: GameWorld) { - for (y in 0..fluidMap.size - 1) { - for (x in 0..fluidMap[0].size - 1) { - placeFluid(world, updateXFrom + x, updateYFrom + y - , FluidCodex.FLUID_WATER, fluidMap[y][x] - 1 - ) - // FIXME test code: deals with water only! - } - } - } - - fun Int.isFluid() = BlockCodex[this].isFluid - fun Int.isSolid() = this.fluidLevel() == FLUID_MAX || BlockCodex[this].isSolid - //fun Int.viscosity() = BlockCodex[this]. - fun Int.fluidLevel() = if (!this.isFluid()) 0 else (this % FLUID_MAX).plus(1) - fun Int.fluidType() = (this / 16) // 0 - 255, 255 being water, 254 being lava - fun Int.isEven() = (this and 0x01) == 0 fun Int.isFallable() = BlockCodex[this].isFallable - private fun placeFluid(world: GameWorld, x: Int, y: Int, fluidType: Byte, amount: Int) { - if (world.layerTerrain.isInBound(x, y)) { - if (amount > 0 && !world.getTileFromTerrain(x, y)!!.isSolid()) { - world.setTileTerrain(x, y, fluidType, amount - 1) - } - else if (amount == 0 && world.getTileFromTerrain(x, y)!!.isFluid()) { - world.setTileTerrain(x, y, Block.AIR) - } - } - } - /** - * @param x and y: world tile coord - * @return amount of fluid actually drained. - * (intended drainage - this) will give you how much fluid is not yet drained. - * TODO add fluidType support - */ - private fun drain(x: Int, y: Int, amount: Int): Int { - val displacement = Math.min(fluidMap[y - updateYFrom][x - updateXFrom].toInt(), amount) - fluidMap[y - updateYFrom][x - updateXFrom] = - (fluidMap[y - updateYFrom][x - updateXFrom] - displacement).toByte() - - return displacement - } - - /** - * @param x and y: world tile coord - * TODO add fluidType support - */ - private fun pour(x: Int, y: Int, amount: Int) { - /** - * @param x and y: world tile coord - * @return spillage - * TODO add fluidType support - */ - fun pourInternal(worldXpos: Int, worldYPos: Int, volume: Int): Int { - var spil = 0 - - val addrX = worldXpos - updateXFrom - val addrY = worldYPos - updateYFrom - - if (addrX >= 0 && addrY >= 0 && addrX < DOUBLE_RADIUS && addrY < DOUBLE_RADIUS) { - fluidMap[addrY][addrX] = (fluidMap[addrY][addrX] + volume).toByte() - if (fluidMap[addrY][addrX] > FLUID_MAX) { - spil = fluidMap[addrY][addrX] - FLUID_MAX - fluidMap[addrY][addrX] = FLUID_MAX.toByte() - } - } - - return spil - } - - // pour the fluid - var spillage = pourInternal(x, y, amount) - - if (spillage <= 0) return - - // deal with the spillage - - val tileUp = world.getTileFromTerrain(x - updateXFrom, y - updateYFrom - 1) - val tileDown = world.getTileFromTerrain(x - updateXFrom, y - updateYFrom + 1) - - // try to fill downward - if (tileDown != null && !tileDown.isSolid()) { - spillage = pourInternal(x, y + 1, spillage) - } - // else, try to fill upward. if there is no space, just discard - if (spillage >= 0 && tileUp != null && !tileUp.isSolid()) { - pourInternal(x, y - 1, spillage) - } - } } \ No newline at end of file