block functions now share one centralised core function

This commit is contained in:
minjaesong
2019-05-04 03:29:59 +09:00
parent 65e01b1eb0
commit e064d6b8f1
8 changed files with 133 additions and 67 deletions

View File

@@ -210,10 +210,6 @@ open class GameWorld {
terrain * PairedMapLayer.RANGE + terrainDamage
}
fun getWiringBlocks(x: Int, y: Int): Int {
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
}
fun getWallLowBits(x: Int, y: Int): Int? {
val (x, y) = coerceXY(x, y)
return layerWallLowBits.getData(x, y)
@@ -230,10 +226,11 @@ open class GameWorld {
* *
* @param y
* *
* @param combinedTilenum (tilenum * 16) + damage
* @param combinedTilenum Item id of the wall block. Less-than-4096-value is permitted.
*/
fun setTileWall(x: Int, y: Int, combinedTilenum: Int) {
val (x, y) = coerceXY(x, y)
val combinedTilenum = combinedTilenum % GameWorld.TILES_SUPPORTED // does work without this, but to be safe...
setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE)
}
@@ -243,7 +240,7 @@ open class GameWorld {
* *
* @param y
* *
* @param combinedTilenum (tilenum * 16) + damage
* @param combinedTilenum Item id of the terrain block, <4096
*/
fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) {
val (x, y) = coerceXY(x, y)
@@ -291,6 +288,10 @@ open class GameWorld {
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
}*/
fun getWiringBlocks(x: Int, y: Int): Int {
return wiringBlocks.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
}
fun getAllConduitsFrom(x: Int, y: Int): SortedArrayList<WiringNode>? {
return wirings.get(LandUtil.getBlockAddr(this, x, y))
}
@@ -488,12 +489,17 @@ open class GameWorld {
override fun toString() = "Fluid type: ${type.value}, amount: $amount"
}
/**
* Connection rules: connect to all nearby, except:
*
* If the wire allows 3- or 4-way connection, make such connection.
* If the wire does not allow them (e.g. wire bridge, thicknet), connect top-bottom and left-right nodes.
*/
data class WiringNode(
val position: BlockAddress,
/** One defined in WireCodex, always power of two */
val typeBitMask: Int,
var fills: Float = 0f,
var connectedNodes: ArrayList<WiringNode>
var fills: Float = 0f
) : Comparable<WiringNode> {
override fun compareTo(other: WiringNode): Int {
return (this.position - other.position).sign

View File

@@ -1,14 +1,16 @@
package net.torvald.terrarum.modulebasegame
import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.AppLoader.IS_DEVELOPMENT_BUILD
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.ModuleEntryPoint
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.gameactors.ActorWBMovable
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.itemproperties.MaterialCodex
import net.torvald.terrarum.modulebasegame.imagefont.WatchFont
import net.torvald.terrarum.modulebasegame.items.BlockBase
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
@@ -74,48 +76,11 @@ class EntryPoint : ModuleEntryPoint() {
}
override fun startPrimaryUse(delta: Float): Boolean {
val ingame = Terrarum.ingame!! as Ingame
return BlockBase.blockStartPrimaryUse(this, i, delta)
}
val mousePoint = Point2d(Terrarum.mouseTileX.toDouble(), Terrarum.mouseTileY.toDouble())
// check for collision with actors (BLOCK only)
if (this.inventoryCategory == Category.BLOCK) {
var ret1 = true
ingame.actorContainerActive.forEach {
if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint))
ret1 = false // return is not allowed here
}
if (!ret1) return ret1
}
// return false if the tile is already there
if (this.inventoryCategory == Category.BLOCK &&
this.dynamicID == ingame.world.getTileFromTerrain(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
this.inventoryCategory == Category.WALL &&
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
this.inventoryCategory == Category.WIRE &&
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWiringBlocks(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
)
return false
// filter passed, do the job
// FIXME this is only useful for Player
if (i in ItemCodex.ITEM_TILES) {
ingame.world.setTileTerrain(
Terrarum.mouseTileX,
Terrarum.mouseTileY,
i
)
}
else {
ingame.world.setTileWall(
Terrarum.mouseTileX,
Terrarum.mouseTileY,
i
)
}
return true
override fun effectWhenEquipped(delta: Float) {
BlockBase.blockEffectWhenEquipped(delta)
}
}
}

View File

@@ -94,7 +94,7 @@ object IngameRenderer {
LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay)
prepLightmapRGBA()
BlocksDrawer.renderData(selectedWireBitToDraw)
BlocksDrawer.renderData()
drawToRGB(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer)
drawOverlayActors(actorsRenderOverlay)
@@ -214,9 +214,6 @@ object IngameRenderer {
// works but some UI elements have wrong transparency -> should be fixed with Terrarum.gdxCleanAndSetBlend -- Torvald 2019-01-12
blendNormal(batch)
batch.color = Color.WHITE
selectedWireBitToDraw = 0
}

View File

@@ -85,7 +85,7 @@ object PlayerBuilderSigrid {
inventory.add(8448) // copper pick
inventory.add(8449) // iron pick
inventory.add(8450) // steel pick
inventory.add(8466) // wire piece
inventory.add(8466, 9995) // wire piece
inventory.add(9000) // TEST water bucket
inventory.add(9001) // TEST lava bucket
}

View File

@@ -0,0 +1,97 @@
package net.torvald.terrarum.modulebasegame.items
import net.torvald.terrarum.Point2d
import net.torvald.terrarum.Point2i
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWBMovable
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulebasegame.Ingame
import net.torvald.terrarum.modulebasegame.IngameRenderer
import net.torvald.terrarum.realestate.LandUtil
/**
* Created by minjaesong on 2019-05-02.
*/
object BlockBase {
/**
* @param dontEncaseActors when set to true, blocks won't be placed where Actors are. You will want to set it false
* for wire items, otherwise you want it to be true.
*/
fun blockStartPrimaryUse(gameItem: GameItem, itemID: Int, delta: Float): Boolean {
val ingame = Terrarum.ingame!! as Ingame
val mousePoint = Point2d(Terrarum.mouseTileX.toDouble(), Terrarum.mouseTileY.toDouble())
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
// check for collision with actors (BLOCK only)
if (gameItem.inventoryCategory == GameItem.Category.BLOCK) {
var ret1 = true
ingame.actorContainerActive.forEach {
if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint))
ret1 = false // return is not allowed here
}
if (!ret1) return ret1
}
// return false if the tile is already there
if (gameItem.inventoryCategory == GameItem.Category.BLOCK &&
gameItem.dynamicID == ingame.world.getTileFromTerrain(mouseTile.x, mouseTile.y) ||
gameItem.inventoryCategory == GameItem.Category.WALL &&
gameItem.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(mouseTile.x, mouseTile.y)
)
return false
// filter passed, do the job
// FIXME this is only useful for Player
if (itemID in ItemCodex.ITEM_TILES) {
ingame.world.setTileTerrain(
mouseTile.x,
mouseTile.y,
itemID
)
}
else {
ingame.world.setTileWall(
mouseTile.x,
mouseTile.y,
itemID
)
}
return true
}
fun blockEffectWhenEquipped(delta: Float) {
IngameRenderer.selectedWireBitToDraw = 0
}
fun wireStartPrimaryUse(gameItem: GameItem, wireTypeBit: Int, delta: Float): Boolean {
val ingame = Terrarum.ingame!! as Ingame
val mouseTile = Point2i(Terrarum.mouseTileX, Terrarum.mouseTileY)
// return false if the tile is already there
if (ingame.world.getWiringBlocks(mouseTile.x, mouseTile.y) and wireTypeBit != 0)
return false
// filter passed, do the job
// FIXME this is only useful for Player
ingame.world.addNewConduitTo(
mouseTile.x,
mouseTile.y,
GameWorld.WiringNode(
LandUtil.getBlockAddr(ingame.world, mouseTile.x, mouseTile.y),
wireTypeBit,
0f
)
)
return true
}
fun wireEffectWhenEquipped(typebit: Int, delta: Float) {
IngameRenderer.selectedWireBitToDraw = typebit
}
}

View File

@@ -6,7 +6,6 @@ import net.torvald.terrarum.blockproperties.Wire
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemID
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.modulebasegame.IngameRenderer
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
@@ -32,12 +31,10 @@ class WirePieceSignalWire(override val originalID: ItemID) : GameItem() {
}
override fun startPrimaryUse(delta: Float): Boolean {
println("Wire!")
return true
return BlockBase.wireStartPrimaryUse(this, Wire.BIT_SIGNAL_RED, delta)
}
override fun effectWhenEquipped(delta: Float) {
IngameRenderer.selectedWireBitToDraw = Wire.BIT_SIGNAL_RED
BlockBase.wireEffectWhenEquipped(Wire.BIT_SIGNAL_RED, delta)
}
}

View File

@@ -150,11 +150,13 @@ class BasicDebugInfoWindow : UICanvas() {
printLine(batch, 8, "light@cursor $ccG$lightVal")
if (ingame != null) {
val wallNum = ingame!!.world.getTileFromWall(mouseTileX, mouseTileY) ?: -1
val tileNum = ingame!!.world.getTileFromTerrain(mouseTileX, mouseTileY) ?: -1
val wireNum = ingame!!.world.getWiringBlocks(mouseTileX, mouseTileY)
val fluid = ingame!!.world.getFluid(mouseTileX, mouseTileY)
printLine(batch, 9, "tile@cursor $ccG$tileNum ($mtX, $mtY)")
printLine(batch, 10, "fluid@cursor ${ccY}Type $ccM${fluid.type.value} ${ccY}Fill $ccG${fluid.amount}f")
printLine(batch, 9, "tile@cursor ${ccO}W$ccG$wallNum ${ccO}T$ccG$tileNum ${ccO}C$ccG${wireNum.toString(2)} $ccY($mtX, $mtY)")
printLine(batch, 10, "fluid@cursor ${ccO}Type $ccG${fluid.type.value} ${ccO}Fill $ccG${fluid.amount}f")
}

View File

@@ -27,6 +27,8 @@ import kotlin.math.roundToInt
* in the shader (tiling.frag). This will not be a problem in the base game, but if you are modifying
* this engine for your project, you must edit the shader program accordingly.
*
* To render and draw images, modify the ```selectedWireBitToDraw``` (bitset) property from the IngameRenderer.
*
* Created by minjaesong on 2016-01-19.
*/
internal object BlocksDrawer {
@@ -185,7 +187,7 @@ internal object BlocksDrawer {
// NO draw lightmap using colour filter, actors must also be hidden behind the darkness
///////////////////////////////////////////
internal fun renderData(wireBit: Int) {
internal fun renderData() {
try {
drawTIME_T = (world as GameWorldExtension).time.TIME_T - (WorldTime.DAY_LENGTH * 15) // offset by -15 days
@@ -198,7 +200,7 @@ internal object BlocksDrawer {
drawTiles(WALL)
drawTiles(TERRAIN) // regular tiles
drawTiles(WIRE, wireBit)
drawTiles(WIRE)
drawTiles(FLUID)
}
@@ -281,7 +283,7 @@ internal object BlocksDrawer {
* @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID.
* @param wire coduitTypes bit that is selected to be drawn. Must be the power of two.
*/
private fun drawTiles(mode: Int, wireBit: Int = 0) {
private fun drawTiles(mode: Int) {
// can't be "WorldCamera.y / TILE_SIZE":
// ( 3 / 16) == 0
// (-3 / 16) == -1 <-- We want it to be '-1', not zero
@@ -310,7 +312,7 @@ internal object BlocksDrawer {
val thisTile = when (mode) {
WALL -> world.getTileFromWall(x, y)
TERRAIN -> world.getTileFromTerrain(x, y)
WIRE -> world.getWiringBlocks(x, y).and(wireBit).toBitOrd()
WIRE -> world.getWiringBlocks(x, y).and(drawWires).toBitOrd()
FLUID -> world.getFluid(x, y).type.abs()
else -> throw IllegalArgumentException()
}