mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
#12 event for world block change -- mainly meant for fixture updating itself
This commit is contained in:
@@ -2,9 +2,11 @@ package net.torvald.terrarum
|
||||
|
||||
import com.badlogic.gdx.Screen
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import com.badlogic.gdx.utils.Queue
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.ui.ConsoleWindow
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.Lock
|
||||
@@ -45,6 +47,10 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
||||
val actorContainer = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
||||
val actorContainerInactive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
|
||||
|
||||
protected val terrainChangeQueue = Queue<BlockChangeQueueItem>()
|
||||
protected val wallChangeQueue = Queue<BlockChangeQueueItem>()
|
||||
protected val wireChangeQueue = Queue<BlockChangeQueueItem>()
|
||||
|
||||
override fun hide() {
|
||||
}
|
||||
|
||||
@@ -96,6 +102,33 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
||||
open fun worldSecondaryClickEnd(delta: Float) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Event for triggering fixture update when something is placed/removed on the world.
|
||||
* Normally only called by GameWorld.setTileTerrain
|
||||
*
|
||||
* Queueing schema is used to make sure things are synchronised.
|
||||
*/
|
||||
open fun queueTerrainChangedEvent(old: Int, new: Int, position: Long) {
|
||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||
terrainChangeQueue.addFirst(BlockChangeQueueItem(old, new, x, y))
|
||||
}
|
||||
|
||||
/**
|
||||
* Wall version of terrainChanged() event
|
||||
*/
|
||||
open fun queueWallChangedEvent(old: Int, new: Int, position: Long) {
|
||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||
wallChangeQueue.addFirst(BlockChangeQueueItem(old, new, x, y))
|
||||
}
|
||||
|
||||
/**
|
||||
* Wire version of terrainChanged() event
|
||||
*/
|
||||
open fun queueWireChangedEvent(old: Int, new: Int, position: Long) {
|
||||
val (x, y) = LandUtil.resolveBlockAddr(world, position)
|
||||
wireChangeQueue.addFirst(BlockChangeQueueItem(old, new, x, y))
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////
|
||||
@@ -215,6 +248,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class BlockChangeQueueItem(val old: Int, val new: Int, val posX: Int, val posY: Int)
|
||||
}
|
||||
|
||||
inline fun Lock.lock(body: () -> Unit) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package net.torvald.terrarum.gameworld
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import net.torvald.terrarum.Terrarum
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.blockproperties.BlockCodex
|
||||
import net.torvald.terrarum.blockproperties.Fluid
|
||||
@@ -220,9 +221,13 @@ open class GameWorld {
|
||||
|
||||
fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val oldWall = getTileFromWall(x, y)
|
||||
layerWall.setTile(x, y, tile)
|
||||
layerWallLowBits.setData(x, y, damage)
|
||||
wallDamages.remove(LandUtil.getBlockAddr(this, x, y))
|
||||
|
||||
if (oldWall != null)
|
||||
Terrarum.ingame?.queueWallChangedEvent(oldWall, tile.toUint() * PairedMapLayer.RANGE + damage, LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +235,7 @@ open class GameWorld {
|
||||
*/
|
||||
fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val oldTerrain = getTileFromTerrain(x, y)
|
||||
layerTerrain.setTile(x, y, tile)
|
||||
layerTerrainLowBits.setData(x, y, damage)
|
||||
val blockAddr = LandUtil.getBlockAddr(this, x, y)
|
||||
@@ -240,11 +246,18 @@ open class GameWorld {
|
||||
fluidTypes.remove(blockAddr)
|
||||
}
|
||||
// fluid tiles-item should be modified so that they will also place fluid onto their respective map
|
||||
|
||||
if (oldTerrain != null)
|
||||
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, tile.toUint() * PairedMapLayer.RANGE + damage, LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
fun setTileWire(x: Int, y: Int, tile: Byte) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val oldWire = getTileFromWire(x, y)
|
||||
layerWire.setTile(x, y, tile)
|
||||
|
||||
if (oldWire != null)
|
||||
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
|
||||
}
|
||||
|
||||
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
|
||||
|
||||
@@ -405,6 +405,8 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
itemOnGrip?.endSecondaryUse(delta)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private var firstTimeRun = true
|
||||
|
||||
///////////////
|
||||
@@ -505,6 +507,12 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
CollisionSolver.process()
|
||||
|
||||
WorldCamera.update(gameworld, actorNowPlaying)
|
||||
|
||||
|
||||
// completely consume block change queues because why not
|
||||
terrainChangeQueue.clear()
|
||||
wallChangeQueue.clear()
|
||||
wireChangeQueue.clear()
|
||||
}
|
||||
|
||||
|
||||
@@ -665,6 +673,12 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (it is CuedByTerrainChange) {
|
||||
terrainChangeQueue.forEach { cue ->
|
||||
it.updateForWorldChange(cue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
actorNowPlaying?.update(delta)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.IngameInstance
|
||||
import net.torvald.terrarum.Point2d
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||
@@ -7,9 +8,9 @@ import net.torvald.terrarum.gameactors.ActorWBMovable
|
||||
/**
|
||||
* Created by minjaesong on 2016-06-17.
|
||||
*/
|
||||
open class FixtureBase(val blockBox: BlockBox) :
|
||||
open class FixtureBase(val blockBox: BlockBox, val blockBoxProps: BlockBoxProps = BlockBoxProps(0)) :
|
||||
// disabling physics (not allowing the fixture to move) WILL make things easier
|
||||
ActorWBMovable(RenderOrder.BEHIND, immobileBody = true, usePhysics = false) {
|
||||
ActorWBMovable(RenderOrder.BEHIND, immobileBody = true, usePhysics = false), CuedByTerrainChange {
|
||||
|
||||
/**
|
||||
* Block-wise position of this fixture when it's placed on the world. Null if it's not on the world
|
||||
@@ -32,6 +33,10 @@ open class FixtureBase(val blockBox: BlockBox) :
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
open fun updateSelf() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,6 +47,33 @@ open class FixtureBase(val blockBox: BlockBox) :
|
||||
}
|
||||
}
|
||||
|
||||
interface CuedByTerrainChange {
|
||||
/**
|
||||
* Fired by world's BlockChanged event (fired when blocks are placed/removed).
|
||||
* The flooding check must run on every frame. use updateSelf() for that.
|
||||
*
|
||||
* E.g. if a fixture block that is inside of BlockBox is missing, destroy and drop self.
|
||||
*/
|
||||
fun updateForWorldChange(cue: IngameInstance.BlockChangeQueueItem) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard 32-bit binary flags.
|
||||
*
|
||||
* (LSB)
|
||||
* - 0: fluid resist - when FALSE, the fixture will break itself to item/nothing. For example, crops has this flag FALSE.
|
||||
* - 1: don't drop item when broken - when TRUE, the fixture will simply disappear instead of dropping itself. For example, crop has this flag TRUE.
|
||||
*
|
||||
* (MSB)
|
||||
*
|
||||
* In the savegame's JSON, this flag set should be stored as signed integer.
|
||||
*/
|
||||
inline class BlockBoxProps(val flags: Int) {
|
||||
|
||||
}
|
||||
|
||||
data class BlockBox(var collisionType: Int, var width: Int, var height: Int) {
|
||||
|
||||
fun redefine(collisionType: Int, width: Int, height: Int) {
|
||||
|
||||
Reference in New Issue
Block a user