fluid multiplies themselves ?!

This commit is contained in:
Minjae Song
2018-12-17 22:39:19 +09:00
parent 8db2405232
commit 62319ba4d2
4 changed files with 73 additions and 58 deletions

View File

@@ -13,8 +13,13 @@ object Fluid {
val WATER = FluidType(1) val WATER = FluidType(1)
val STATIC_WATER = FluidType(-1) val STATIC_WATER = FluidType(-1)
val LAVA = FluidType(2)
val STATIC_LAVA = FluidType(-2)
val fluidTilesRange = 4094..4095 // MANUAL UPDATE
val fluidRange = 1..2 // MANUAL UPDATE
fun getFluidTileFrom(type: FluidType) = GameWorld.TILES_SUPPORTED - type.abs() fun getFluidTileFrom(type: FluidType) = GameWorld.TILES_SUPPORTED - type.abs()
private val fluidTilesRange = 4094..4095
fun isThisTileFluid(tileid: Int) = tileid in fluidTilesRange fun isThisTileFluid(tileid: Int) = tileid in fluidTilesRange
} }

View File

@@ -380,7 +380,7 @@ open class GameWorld {
else { else {
//printdbg(this, "> Setting nonzero ($fill) on ($x,$y)") //printdbg(this, "> Setting nonzero ($fill) on ($x,$y)")
setTileTerrain(x, y, Block.WATER) // this function alters fluid list, must be called first // TODO fluidType aware setTileTerrain(x, y, fluidTypeToBlock(fluidType)) // this function alters fluid list, must be called first // TODO fluidType aware
fluidTypes[addr] = fluidType fluidTypes[addr] = fluidType
fluidFills[addr] = fill fluidFills[addr] = fill
} }
@@ -401,6 +401,12 @@ open class GameWorld {
return if (type == null) FluidInfo(Fluid.NULL, 0f) else FluidInfo(type, fill!!) return if (type == null) FluidInfo(Fluid.NULL, 0f) else FluidInfo(type, fill!!)
} }
private fun fluidTypeToBlock(type: FluidType) = when (type.abs()) {
Fluid.NULL.value -> Block.AIR
in Fluid.fluidRange -> GameWorld.TILES_SUPPORTED - type.abs()
else -> throw IllegalArgumentException("Unsupported fluid type: $type")
}
data class FluidInfo(val type: FluidType, val amount: Float) { data class FluidInfo(val type: FluidType, val amount: Float) {
override fun toString() = "Fluid type: ${type.value}, amount: $amount" override fun toString() = "Fluid type: ${type.value}, amount: $amount"
} }

View File

@@ -2,7 +2,6 @@ package net.torvald.terrarum.modulebasegame.gameworld
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
@@ -80,34 +79,7 @@ object WorldSimulator {
makeFluidMapFromWorld() makeFluidMapFromWorld()
simCompression() simCompression()
/*for (y in 1 until fluidMap.size - 1) { //myFluidSim()
for (x in 1 until fluidMap[0].size - 1) {
val worldX = x + updateXFrom
val worldY = y + updateYFrom
/*if (worldX == 60 && worldY == 256) {
printdbg(this, "tile: ${world.getTileFromTerrain(worldX, worldY)}, isSolid = ${isSolid(worldX, worldY)}")
}*/
if (isSolid(worldX, worldY)) continue
val remainingMass = fluidMap[y][x]
val remainingType = fluidTypeMap[y][x]
if (remainingMass != 0f && remainingType == Fluid.NULL) throw InternalError("wtf? (Type: $remainingType, fill: $remainingMass)")
/*if (worldX == 60 && worldY == 256) {
printdbg(this, "remainimgMass: $remainingMass at ($worldX, $worldY)")
}*/
if (remainingMass == 0f) continue
if (!isSolid(worldX, worldY + 1)) {
fluidNewMap[y][x] -= remainingMass
fluidNewMap[y + 1][x] += remainingMass
fluidNewTypeMap[y + 1][x] = remainingType
}
}
}*/
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
@@ -117,23 +89,55 @@ object WorldSimulator {
} }
fun isFlowable(type: FluidType, worldX: Int, worldY: Int): Boolean { fun isFlowable(type: FluidType, worldX: Int, worldY: Int): Boolean {
val targetFluid = world.getFluid(worldX, worldY) val fluid = world.getFluid(worldX, worldY)
val tile = world.getTileFromTerrain(worldX, worldY)
// true if target's type is the same as mine, or it's NULL (air) // true if target's type is the same as mine, or it's NULL (air)
return (targetFluid.type sameAs type || targetFluid.type sameAs Fluid.NULL) return ((fluid.type sameAs type || fluid.type sameAs Fluid.NULL) && !BlockCodex[tile].isSolid)
} }
fun isSolid(worldX: Int, worldY: Int): Boolean { fun isSolid(worldX: Int, worldY: Int): Boolean {
val tile = world.getTileFromTerrain(worldX, worldY) val tile = world.getTileFromTerrain(worldX, worldY)
if (tile != Block.WATER) { val fluid = world.getFluid(worldX, worldY)
// check for block properties isSolid return (tile != Block.WATER && tile != Block.AIR && fluid.amount == 0f)
return BlockCodex[tile].isSolid }
}
else {
// check for fluid
// no STATIC is implement yet, just return false private fun myFluidSim() {
return false 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
}
} }
} }
@@ -183,32 +187,31 @@ object WorldSimulator {
private fun simCompression() { private fun simCompression() {
// before data: fluidMap/fluidTypeMap // before data: fluidMap/fluidTypeMap
// after data: fluidNewMap/fluidNewTypeMap // after data: fluidNewMap/fluidNewTypeMap
var flow = 0f
var remainingMass = 0f
var remainingType = Fluid.NULL
// FIXME water doesn't disappear when they should // FIXME water doesn't disappear when they should
// FIXME >as it turns out, fluid FUCKING MULTIPLIES themselves (wut D:)
for (y in 1 until fluidMap.size - 1) { for (y in 1 until fluidMap.size - 1) {
for (x in 1 until fluidMap[0].size - 1) { for (x in 1 until fluidMap[0].size - 1) {
val worldX = x + updateXFrom val worldX = x + updateXFrom
val worldY = y + updateYFrom val worldY = y + updateYFrom
val remainingType = fluidTypeMap[y][x]
// check solidity // check solidity
if (isSolid(worldX, worldY)) continue if (!isFlowable(remainingType, worldX, worldY)) continue
// check if the fluid is a same kind // check if the fluid is a same kind
//if (!isFlowable(type, worldX, worldY))) continue //if (!isFlowable(type, worldX, worldY))) continue
// Custom push-only flow // Custom push-only flow
flow = 0f var flow = 0f
remainingMass = fluidNewMap[y][x] var remainingMass = fluidMap[y][x]
remainingType = fluidNewTypeMap[y][x] //val remainingType = fluidTypeMap[y][x]
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// The block below this one // The block below this one
if (!isSolid(worldX, worldY + 1)) { // TODO use isFlowable if (isFlowable(remainingType, worldX, worldY + 1)) { // TODO use isFlowable
flow = getStableStateB(remainingMass + fluidNewMap[y + 1][x]) - fluidNewMap[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
} }
@@ -223,9 +226,9 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Left // Left
if (!isSolid(worldX - 1, worldY)) { // TODO use isFlowable if (isFlowable(remainingType, worldX - 1, worldY)) { // TODO use isFlowable
// Equalise the amount fo water in this block and its neighbour // Equalise the amount fo water in this block and its neighbour
flow = (fluidNewMap[y][x] - fluidNewMap[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
} }
@@ -240,9 +243,9 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Right // Right
if (!isSolid(worldX + 1, worldY)) { // TODO use isFlowable if (isFlowable(remainingType, worldX + 1, worldY)) { // TODO use isFlowable
// Equalise the amount fo water in this block and its neighbour // Equalise the amount fo water in this block and its neighbour
flow = (fluidNewMap[y][x] - fluidNewMap[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
} }
@@ -257,8 +260,8 @@ object WorldSimulator {
if (remainingMass <= 0) continue if (remainingMass <= 0) continue
// Up; only compressed water flows upwards // Up; only compressed water flows upwards
if (!isSolid(worldX, worldY - 1)) { // TODO use isFlowable /*if (isFlowable(remainingType, worldX, worldY - 1)) { // TODO use isFlowable
flow = remainingMass - getStableStateB(remainingMass + fluidNewMap[y - 1][x]) flow = remainingMass - getStableStateB(remainingMass + fluidMap[y - 1][x])
if (flow > minFlow) { if (flow > minFlow) {
flow *= 0.5f flow *= 0.5f
} }
@@ -268,11 +271,12 @@ object WorldSimulator {
fluidNewMap[y - 1][x] += flow fluidNewMap[y - 1][x] += flow
fluidNewTypeMap[y - 1][x] = remainingType fluidNewTypeMap[y - 1][x] = remainingType
remainingMass -= flow remainingMass -= flow
} }*/
} }
} }
} }
/** /**