mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
fluid wip and hopefully fixed F3 dangling ptr
This commit is contained in:
@@ -158,3 +158,5 @@ id;classname;tags
|
||||
# ...
|
||||
# 10FF00h..10FFFFh : Fluid type 255 (???) x container type 0..255
|
||||
|
||||
# reserved for debug items
|
||||
16777216;net.torvald.terrarum.modulebasegame.gameitems.ItemBottomlessWaterBucket;DEBUG,TOOL
|
||||
|
||||
|
@@ -8,10 +8,7 @@ import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.terrarum.App.*
|
||||
import net.torvald.terrarum.App.setToGameConfig
|
||||
import net.torvald.terrarum.audio.AudioCodex
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.BlockProp
|
||||
import net.torvald.terrarum.blockproperties.OreCodex
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.blockproperties.*
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gamecontroller.IME
|
||||
import net.torvald.terrarum.gameitems.FixtureInteractionBlocked
|
||||
@@ -765,6 +762,18 @@ object ModMgr {
|
||||
}
|
||||
}
|
||||
|
||||
object GameFluidLoader {
|
||||
const val fluidPath = "fluids/"
|
||||
|
||||
init {
|
||||
Terrarum.fluidCodex = FluidCodex()
|
||||
}
|
||||
|
||||
@JvmStatic operator fun invoke(module: String) {
|
||||
Terrarum.fluidCodex.fromModule(module, fluidPath + "fluids.csv")
|
||||
}
|
||||
}
|
||||
|
||||
object GameAudioLoader {
|
||||
val audioPath = listOf(
|
||||
"audio/music",
|
||||
|
||||
@@ -42,7 +42,7 @@ object TerrarumPostProcessor : Disposable {
|
||||
private val safeAreaCol2 = Color(0xffffff44.toInt())
|
||||
private val currentResCol = Color(0xfff066_88.toInt())
|
||||
|
||||
private val debugUI = BasicDebugInfoWindow()
|
||||
internal val debugUI = BasicDebugInfoWindow()
|
||||
|
||||
private val functionRowHelper = Texture(Gdx.files.internal("assets/graphics/function_row_help.png"))
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package net.torvald.terrarum.blockproperties
|
||||
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.utils.CSVFetcher
|
||||
import org.apache.commons.csv.CSVRecord
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2023-10-09.
|
||||
*/
|
||||
class FluidCodex {
|
||||
|
||||
@Transient val blockProps = HashMap<ItemID, FluidProp>()
|
||||
@Transient val fluidProps = HashMap<ItemID, FluidProp>()
|
||||
|
||||
@Transient private val nullProp = FluidProp()
|
||||
|
||||
@@ -20,22 +24,105 @@ class FluidCodex {
|
||||
|
||||
try {
|
||||
return if (fluidID.startsWith("fluid@"))
|
||||
blockProps[fluidID.substring(6)]!!
|
||||
fluidProps[fluidID]!!
|
||||
else
|
||||
blockProps[fluidID]!!
|
||||
throw NullPointerException("Missing prefix 'fluid@' for the ID '$fluidID'")
|
||||
}
|
||||
catch (e: NullPointerException) {
|
||||
throw NullPointerException("Fluidprop with id $fluidID does not exist.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Later entry (possible from other modules) will replace older ones
|
||||
*/
|
||||
fun fromModule(module: String, path: String, registerHook: (FluidProp) -> Unit = {}) {
|
||||
printdbg(this, "Building fluid properties table")
|
||||
try {
|
||||
register(module, CSVFetcher.readFromModule(module, path), registerHook)
|
||||
}
|
||||
catch (e: IOException) { e.printStackTrace() }
|
||||
}
|
||||
|
||||
private fun register(module: String, records: List<CSVRecord>, registerHook: (FluidProp) -> Unit) {
|
||||
records.forEach {
|
||||
setProp(module, it.intVal("id"), it)
|
||||
val tileId = "fluid@$module:${it.intVal("id")}"
|
||||
fluidProps[tileId]?.let(registerHook)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setProp(module: String, key: Int, record: CSVRecord) {
|
||||
val prop = FluidProp()
|
||||
prop.nameKey = record.get("name")
|
||||
prop.tags = record.get("tags").split(',').map { it.trim().toUpperCase() }.toHashSet()
|
||||
|
||||
prop.id = "fluid@$module:$key"
|
||||
prop.numericID = key
|
||||
|
||||
prop.shadeColR = record.floatVal("shdr")
|
||||
prop.shadeColG = record.floatVal("shdg")
|
||||
prop.shadeColB = record.floatVal("shdb")
|
||||
prop.shadeColA = record.floatVal("shduv")
|
||||
prop.opacity = Cvec(prop.shadeColR, prop.shadeColG, prop.shadeColB, prop.shadeColA)
|
||||
|
||||
prop.strength = record.intVal("str")
|
||||
prop.density = record.intVal("dsty")
|
||||
|
||||
prop.lumColR = record.floatVal("lumr")
|
||||
prop.lumColG = record.floatVal("lumg")
|
||||
prop.lumColB = record.floatVal("lumb")
|
||||
prop.lumColA = record.floatVal("lumuv")
|
||||
prop.lumCol.set(prop.lumColR, prop.lumColG, prop.lumColB, prop.lumColA)
|
||||
|
||||
prop.viscosity = record.intVal("vscs")
|
||||
prop.colour = record.str16ToInt("colour")
|
||||
|
||||
prop.reflectance = record.floatVal("refl")
|
||||
|
||||
prop.material = record.get("mate")
|
||||
|
||||
fluidProps[prop.id] = prop
|
||||
|
||||
printdbg(this, "Setting fluid prop ${prop.id} ->>\t${prop.nameKey}")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class FluidProp {
|
||||
val opacity: Cvec = Cvec()
|
||||
val lumCol: Cvec = Cvec()
|
||||
var id: ItemID = ""
|
||||
var numericID: Int = -1
|
||||
var nameKey: String = ""
|
||||
|
||||
/** 1.0f for 1023, 0.25f for 255 */
|
||||
var shadeColR = 0f
|
||||
var shadeColG = 0f
|
||||
var shadeColB = 0f
|
||||
var shadeColA = 0f
|
||||
var opacity = Cvec()
|
||||
|
||||
var strength: Int = 0
|
||||
var density: Int = 0
|
||||
|
||||
var material: String = ""
|
||||
|
||||
/** 1.0f for 1023, 0.25f for 255 */
|
||||
var lumColR = 0f
|
||||
var lumColG = 0f
|
||||
var lumColB = 0f
|
||||
var lumColA = 0f
|
||||
var lumCol = Cvec()
|
||||
|
||||
/** Fluid colour */
|
||||
var colour: Int = 0
|
||||
|
||||
var viscosity: Int = 0
|
||||
|
||||
var reflectance = 0f // the exact colour of the reflected light depends on the texture
|
||||
|
||||
@Transient var tags = HashSet<String>()
|
||||
|
||||
}
|
||||
@@ -248,6 +248,12 @@ open class GameWorld(
|
||||
tileNameToNumberMap[it.key] = it.value.tileNumber
|
||||
}
|
||||
}
|
||||
Terrarum.fluidCodex.fluidProps.entries.forEach {
|
||||
if (!forcedFluidNumberToTiles.contains(it.key)) {
|
||||
fluidNumberToNameMap[it.value.numericID.toLong()] = it.key
|
||||
fluidNameToNumberMap[it.key] = it.value.numericID
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,6 +276,10 @@ open class GameWorld(
|
||||
tileNumberToNameMap[it.value.tileNumber.toLong()] = it.key
|
||||
tileNameToNumberMap[it.key] = it.value.tileNumber
|
||||
}
|
||||
Terrarum.fluidCodex.fluidProps.entries.forEach {
|
||||
fluidNumberToNameMap[it.value.numericID.toLong()] = it.key
|
||||
fluidNameToNumberMap[it.key] = it.value.numericID
|
||||
}
|
||||
|
||||
// force this rule to the old saves
|
||||
tileNumberToNameMap[0] = Block.AIR
|
||||
@@ -749,11 +759,11 @@ open class GameWorld(
|
||||
|
||||
|
||||
if (fluidType == Fluid.NULL && fill != 0f) {
|
||||
throw Error("Illegal fluid at ($x,$y): ${FluidInfo(fluidType, fill)}")
|
||||
throw Error("Illegal fluid fill at ($x,$y): ${FluidInfo(fluidType, fill)}")
|
||||
}
|
||||
|
||||
|
||||
val addr = LandUtil.getBlockAddr(this, x, y)
|
||||
// val addr = LandUtil.getBlockAddr(this, x, y)
|
||||
|
||||
val fluidNumber = fluidNameToNumberMap[fluidType]!!
|
||||
|
||||
@@ -778,7 +788,7 @@ open class GameWorld(
|
||||
val (type, fill) = layerFluids.unsafeGetTile1(x, y)
|
||||
val fluidID = fluidNumberToNameMap[type.toLong()] ?: throw NullPointerException("No such fluid: $type")
|
||||
|
||||
return FluidInfo(fluidID, fill)
|
||||
return FluidInfo(fluidID, fill.let { if (it.isNaN()) 0f else it }) // hex FFFFFFFF (magic number for ungenerated tiles) is interpreted as Float.NaN
|
||||
}
|
||||
|
||||
/*private fun fluidTypeToBlock(type: FluidType) = when (type.abs()) {
|
||||
|
||||
@@ -35,6 +35,7 @@ class EntryPoint : ModuleEntryPoint() {
|
||||
ModMgr.GameItemLoader.invoke(moduleName)
|
||||
ModMgr.GameBlockLoader.invoke(moduleName)
|
||||
ModMgr.GameOreLoader.invoke(moduleName)
|
||||
ModMgr.GameFluidLoader.invoke(moduleName)
|
||||
ModMgr.GameLanguageLoader.invoke(moduleName)
|
||||
ModMgr.GameCraftingRecipeLoader.invoke(moduleName)
|
||||
ModMgr.GameAudioLoader.invoke(moduleName)
|
||||
|
||||
@@ -196,6 +196,8 @@ object IngameRenderer : Disposable {
|
||||
// printdbg(this, "Set new RenderedWorld (UUID=${world.worldIndex}) at time ${System.currentTimeMillis()} (disposed: ${world.disposed}), called by:")
|
||||
// printStackTrace(this)
|
||||
|
||||
var successful = false
|
||||
|
||||
try {
|
||||
|
||||
// change worlds from internal methods
|
||||
@@ -210,11 +212,19 @@ object IngameRenderer : Disposable {
|
||||
// "new world: ${world.hashCode()}")
|
||||
newWorldLoadedLatch = true
|
||||
}
|
||||
|
||||
successful = true
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
// new init, do nothing
|
||||
}
|
||||
finally {
|
||||
if (successful)
|
||||
TerrarumPostProcessor.debugUI.world = world
|
||||
else
|
||||
TerrarumPostProcessor.debugUI.world = null
|
||||
}
|
||||
}
|
||||
|
||||
private var oldCamX = 0
|
||||
|
||||
@@ -88,7 +88,7 @@ object WorldSimulator {
|
||||
|
||||
if (ingame.terrainChangeQueue.isNotEmpty()) { App.measureDebugTime("WorldSimulator.degrass") { buryGrassImmediately() } }
|
||||
App.measureDebugTime("WorldSimulator.growGrass") { growOrKillGrass() }
|
||||
App.measureDebugTime("WorldSimulator.fluids") { /*moveFluids(delta)*/ }
|
||||
App.measureDebugTime("WorldSimulator.fluids") { moveFluids(delta) }
|
||||
App.measureDebugTime("WorldSimulator.fallables") { displaceFallables(delta) }
|
||||
App.measureDebugTime("WorldSimulator.wires") { simulateWires(delta) }
|
||||
App.measureDebugTime("WorldSimulator.collisionDroppedItem") { collideDroppedItems() }
|
||||
|
||||
@@ -163,7 +163,7 @@ class ActorGlowOrb(throwPitch: Float) : ActorLobbed(throwPitch) {
|
||||
spriteEmissive = SingleImageSprite(this, itemImage)
|
||||
|
||||
avBaseMass = 1.0
|
||||
density = 1400.0
|
||||
density = 580.0
|
||||
}
|
||||
|
||||
@Transient private val lifePower = 10000L // charge reaches 0 on timeDelta = 9 * lifePower
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameitems
|
||||
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.INGAME
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.GameItem.EquipPosition.HAND_GRIP
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-07-14.
|
||||
*/
|
||||
class ItemBottomlessWaterBucket(originalID: ItemID) : GameItem(originalID) {
|
||||
|
||||
override var baseToolSize: Double? = PickaxeCore.BASE_MASS_AND_SIZE
|
||||
override var inventoryCategory = Category.TOOL
|
||||
override val canBeDynamic = false
|
||||
override val materialId = "CUPR"
|
||||
override var baseMass = 2.0
|
||||
override var equipPosition = HAND_GRIP
|
||||
override var originalName = "ITEM_BOTTOMLESS_WATER_BUCKET"
|
||||
|
||||
init {
|
||||
stackable = false
|
||||
isUnique = true
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long {
|
||||
val mx = Terrarum.mouseTileX; val my =Terrarum.mouseTileY
|
||||
INGAME.world.setFluid(mx, my, Fluid.WATER, 1f)
|
||||
printdbg(this, "Pouring water at ($mx, $my)")
|
||||
return 0L
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
private var ydelta = 0.0
|
||||
|
||||
private var ingame: IngameInstance? = null
|
||||
private var world: GameWorld? = null
|
||||
internal var world: GameWorld? = null // is set by IngameRenderer.setRenderedWorld(GameWorld)
|
||||
|
||||
private val icons = TextureRegionPack(Gdx.files.internal("assets/graphics/gui/debug_window_symbols.tga"), 21, 26)
|
||||
private val back = Texture(Gdx.files.internal("assets/graphics/gui/debug_window_background.tga"))
|
||||
@@ -86,12 +86,9 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
private var showAudioMixer2 = false
|
||||
private var showChunks = false
|
||||
|
||||
override fun show() {
|
||||
ingame = Terrarum.ingame
|
||||
world = ingame?.world
|
||||
}
|
||||
|
||||
override fun updateImpl(delta: Float) {
|
||||
ingame = Terrarum.ingame
|
||||
|
||||
val player = ingame?.actorNowPlaying
|
||||
val hitbox = player?.hitbox
|
||||
|
||||
@@ -382,24 +379,24 @@ class BasicDebugInfoWindow : UICanvas() {
|
||||
*/
|
||||
|
||||
if (ingame != null) {
|
||||
App.fontSmallNumbers.draw(batch, "${ccY}Actors total $ccG${ingame!!.actorContainerActive.size + ingame!!.actorContainerInactive.size}",
|
||||
TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 2f)
|
||||
App.fontSmallNumbers.draw(batch, "${ccY}Active $ccG${ingame!!.actorContainerActive.size}",
|
||||
TinyAlphNum.W * 2f + (17 * 8), App.scr.height - TinyAlphNum.H * 2f)
|
||||
App.fontSmallNumbers.draw(batch, "${ccY}Dormant $ccG${ingame!!.actorContainerInactive.size}",
|
||||
TinyAlphNum.W * 2f + (28 * 8), App.scr.height - TinyAlphNum.H * 2f)
|
||||
// App.fontSmallNumbers.draw(batch, "${ccY}Actors total $ccG${ingame!!.actorContainerActive.size + ingame!!.actorContainerInactive.size}",
|
||||
// TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 2f)
|
||||
// App.fontSmallNumbers.draw(batch, "${ccY}Active $ccG${ingame!!.actorContainerActive.size}",
|
||||
// TinyAlphNum.W * 2f + (17 * 8), App.scr.height - TinyAlphNum.H * 2f)
|
||||
// App.fontSmallNumbers.draw(batch, "${ccY}Dormant $ccG${ingame!!.actorContainerInactive.size}",
|
||||
// TinyAlphNum.W * 2f + (28 * 8), App.scr.height - TinyAlphNum.H * 2f)
|
||||
if (ingame is TerrarumIngame) {
|
||||
App.fontSmallNumbers.draw(batch, "${ccM}Particles $ccG${(ingame as TerrarumIngame).particlesActive}$ccY/$ccG${(ingame as TerrarumIngame).PARTICLES_MAX}",
|
||||
TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 4f)
|
||||
TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 3f)
|
||||
}
|
||||
App.fontSmallNumbers.draw(batch, "${ccM}Clouds $ccG${WeatherMixer.cloudsSpawned}$ccY/$ccG${WeatherMixer.cloudSpawnMax}",
|
||||
TinyAlphNum.W * 2f + (18 * 8), App.scr.height - TinyAlphNum.H * 4f)
|
||||
TinyAlphNum.W * 2f + (18 * 8), App.scr.height - TinyAlphNum.H * 3f)
|
||||
}
|
||||
|
||||
App.fontSmallNumbers.draw(batch, "${ccY}Actors rendering $ccG${IngameRenderer.renderingActorsCount}",
|
||||
TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 3f)
|
||||
TinyAlphNum.W * 2f, App.scr.height - TinyAlphNum.H * 2f)
|
||||
App.fontSmallNumbers.draw(batch, "${ccY}UIs rendering $ccG${IngameRenderer.renderingUIsCount}",
|
||||
TinyAlphNum.W * 2f + (21 * 8), App.scr.height - TinyAlphNum.H * 3f)
|
||||
TinyAlphNum.W * 2f + (21 * 8), App.scr.height - TinyAlphNum.H * 2f)
|
||||
|
||||
/**
|
||||
* Bottom right
|
||||
|
||||
Reference in New Issue
Block a user