mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 03:54:06 +09:00
fluid multiplies themselves ?!
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user