water flow works

turns out, var.coerceIn() returns value and does not modify the var
This commit is contained in:
Minjae Song
2018-12-18 01:48:38 +09:00
parent 62319ba4d2
commit 23d557b6b2
2 changed files with 24 additions and 72 deletions

View File

@@ -365,24 +365,20 @@ open class GameWorld {
val addr = LandUtil.getBlockAddr(this, x, y) val addr = LandUtil.getBlockAddr(this, x, y)
// fluid completely drained
if (fill <= WorldSimulator.FLUID_MIN_MASS) {
/**********/ fluidTypes.remove(addr)
val oldMap = fluidFills.remove(addr)
// oldMap not being null means there actually was a fluid there, so we can put AIR onto it if (fill > WorldSimulator.FLUID_MIN_MASS) {
// otherwise, it means it was some solid and therefore we DON'T want to put AIR onto it setTileTerrain(x, y, fluidTypeToBlock(fluidType))
if (oldMap != null) {
setTileTerrain(x, y, 0)
}
}
// update the fluid amount
else {
//printdbg(this, "> Setting nonzero ($fill) on ($x,$y)")
setTileTerrain(x, y, fluidTypeToBlock(fluidType)) // this function alters fluid list, must be called first // TODO fluidType aware
fluidTypes[addr] = fluidType
fluidFills[addr] = fill fluidFills[addr] = fill
fluidTypes[addr] = fluidType
}
else {
fluidFills.remove(addr)
fluidTypes.remove(addr)
// if old tile was fluid
if (BlockCodex[getTileFromTerrain(x, y) ?: Block.STONE].isFluid) {
setTileTerrain(x, y, Block.AIR)
}
} }
@@ -397,7 +393,6 @@ open class GameWorld {
val addr = LandUtil.getBlockAddr(this, x, y) val addr = LandUtil.getBlockAddr(this, x, y)
val fill = fluidFills[addr] val fill = fluidFills[addr]
val type = fluidTypes[addr] val type = fluidTypes[addr]
return if (type == null) FluidInfo(Fluid.NULL, 0f) else FluidInfo(type, fill!!) return if (type == null) FluidInfo(Fluid.NULL, 0f) else FluidInfo(type, fill!!)
} }

View File

@@ -1,13 +1,16 @@
package net.torvald.terrarum.modulebasegame.gameworld package net.torvald.terrarum.modulebasegame.gameworld
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import net.torvald.terrarum.AppLoader import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.roundInt import net.torvald.terrarum.roundInt
import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.worlddrawer.FeaturesDrawer
import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameworld.FluidType import net.torvald.terrarum.gameworld.FluidType
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
@@ -79,7 +82,6 @@ object WorldSimulator {
makeFluidMapFromWorld() makeFluidMapFromWorld()
simCompression() simCompression()
//myFluidSim()
if (AppLoader.IS_DEVELOPMENT_BUILD) { if (AppLoader.IS_DEVELOPMENT_BUILD) {
monitorIllegalFluidSetup() // non-air non-zero fluid is kinda inevitable monitorIllegalFluidSetup() // non-air non-zero fluid is kinda inevitable
@@ -96,51 +98,6 @@ object WorldSimulator {
return ((fluid.type sameAs type || fluid.type sameAs Fluid.NULL) && !BlockCodex[tile].isSolid) return ((fluid.type sameAs type || fluid.type sameAs Fluid.NULL) && !BlockCodex[tile].isSolid)
} }
fun isSolid(worldX: Int, worldY: Int): Boolean {
val tile = world.getTileFromTerrain(worldX, worldY)
val fluid = world.getFluid(worldX, worldY)
return (tile != Block.WATER && tile != Block.AIR && fluid.amount == 0f)
}
private fun myFluidSim() {
for (y in 1 until fluidMap.size - 1) {
for (x in 1 until fluidMap[0].size - 1) {
val worldX = x + updateXFrom
val worldY = y + updateYFrom
val remainingType = fluidTypeMap[y][x]
if (!isFlowable(remainingType, worldX, worldY)) continue
var remainingMass = fluidMap[y][x]
var flow = 0f
if (remainingMass != 0f && remainingType == Fluid.NULL) throw InternalError("wtf? (Type: $remainingType, fill: $remainingMass)")
if (remainingMass == 0f) continue
// move down
if (isFlowable(remainingType, worldX, worldY + 1)) {
//fluidNewMap[y][x] -= remainingMass
//fluidNewMap[y + 1][x] += remainingMass
//fluidNewTypeMap[y + 1][x] = remainingType
flow = getStableStateB(remainingMass + fluidMap[y + 1][x]) - fluidMap[y + 1][x]
if (flow > minFlow) {
flow *= 0.5f // leads to smoother flow
}
flow.coerceIn(0f, minOf(maxSpeed, remainingMass))
fluidNewMap[y][x] -= flow
fluidNewMap[y + 1][x] += flow
fluidNewTypeMap[y + 1][x] = remainingType
remainingMass -= flow
}
if (remainingMass <= 0) continue
}
}
}
/* /*
Explanation of get_stable_state_b (well, kind-of) : Explanation of get_stable_state_b (well, kind-of) :
@@ -210,12 +167,12 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// The block below this one // The block below this one
if (isFlowable(remainingType, worldX, worldY + 1)) { // TODO use isFlowable if (isFlowable(remainingType, worldX, worldY + 1)) {
flow = getStableStateB(remainingMass + fluidMap[y + 1][x]) - fluidMap[y + 1][x] flow = getStableStateB(remainingMass + fluidMap[y + 1][x]) - fluidMap[y + 1][x]
if (flow > minFlow) { if (flow > minFlow) {
flow *= 0.5f // leads to smoother flow flow *= 0.5f // leads to smoother flow
} }
flow.coerceIn(0f, minOf(maxSpeed, remainingMass)) flow = flow.coerceIn(0f, minOf(maxSpeed, remainingMass))
fluidNewMap[y][x] -= flow fluidNewMap[y][x] -= flow
fluidNewMap[y + 1][x] += flow fluidNewMap[y + 1][x] += flow
@@ -226,13 +183,13 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Left // Left
if (isFlowable(remainingType, worldX - 1, worldY)) { // TODO use isFlowable if (isFlowable(remainingType, worldX - 1, worldY)) {
// Equalise the amount fo water in this block and its neighbour // Equalise the amount fo water in this block and its neighbour
flow = (fluidMap[y][x] - fluidMap[y][x - 1]) / 4f flow = (fluidMap[y][x] - fluidMap[y][x - 1]) / 4f
if (flow > minFlow) { if (flow > minFlow) {
flow *= 0.5f flow *= 0.5f
} }
flow.coerceIn(0f, remainingMass) flow = flow.coerceIn(0f, remainingMass)
fluidNewMap[y][x] -= flow fluidNewMap[y][x] -= flow
fluidNewMap[y][x - 1] += flow fluidNewMap[y][x - 1] += flow
@@ -243,13 +200,13 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Right // Right
if (isFlowable(remainingType, worldX + 1, worldY)) { // TODO use isFlowable if (isFlowable(remainingType, worldX + 1, worldY)) {
// Equalise the amount fo water in this block and its neighbour // Equalise the amount fo water in this block and its neighbour
flow = (fluidMap[y][x] - fluidMap[y][x + 1]) / 4f flow = (fluidMap[y][x] - fluidMap[y][x + 1]) / 4f
if (flow > minFlow) { if (flow > minFlow) {
flow *= 0.5f flow *= 0.5f
} }
flow.coerceIn(0f, remainingMass) flow = flow.coerceIn(0f, remainingMass)
fluidNewMap[y][x] -= flow fluidNewMap[y][x] -= flow
fluidNewMap[y][x + 1] += flow fluidNewMap[y][x + 1] += flow
@@ -260,18 +217,18 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Up; only compressed water flows upwards // Up; only compressed water flows upwards
/*if (isFlowable(remainingType, worldX, worldY - 1)) { // TODO use isFlowable if (isFlowable(remainingType, worldX, worldY - 1)) {
flow = remainingMass - getStableStateB(remainingMass + fluidMap[y - 1][x]) flow = remainingMass - getStableStateB(remainingMass + fluidMap[y - 1][x])
if (flow > minFlow) { if (flow > minFlow) {
flow *= 0.5f flow *= 0.5f
} }
flow.coerceIn(0f, minOf(maxSpeed, remainingMass)) flow = flow.coerceIn(0f, minOf(maxSpeed, remainingMass))
fluidNewMap[y][x] -= flow fluidNewMap[y][x] -= flow
fluidNewMap[y - 1][x] += flow fluidNewMap[y - 1][x] += flow
fluidNewTypeMap[y - 1][x] = remainingType fluidNewTypeMap[y - 1][x] = remainingType
remainingMass -= flow remainingMass -= flow
}*/ }
} }