building wire graph PER TILE

This commit is contained in:
minjaesong
2021-08-03 16:27:36 +09:00
parent 1ae3e34392
commit 6891d6b840
3 changed files with 61 additions and 13 deletions

View File

@@ -16,10 +16,10 @@ import net.torvald.terrarum.gameworld.GameWorld
class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.IMMOBILE) { class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.IMMOBILE) {
companion object { companion object {
private val nearbyArr = arrayOf( val WIRE_NEARBY = arrayOf(
(-1 to 0), // tileL
(0 to +1), // tileB
(+1 to 0), // tileR (+1 to 0), // tileR
(0 to +1), // tileB
(-1 to 0), // tileL
(0 to -1) // tileT (0 to -1) // tileT
) )
} }
@@ -60,9 +60,9 @@ class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.I
val nearbyTiles = getNearbyTilesPos(worldX, worldY).map { world.getAllWiresFrom(it.x, it.y) } val nearbyTiles = getNearbyTilesPos(worldX, worldY).map { world.getAllWiresFrom(it.x, it.y) }
var ret = 0 var ret = 0
for (i in nearbyTiles.indices) { for (i in 0..3) {
if (nearbyTiles[i]?.contains(itemID) == true) { if (nearbyTiles[i]?.contains(itemID) == true) {
ret += (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3 ret = ret or (1 shl i) // add 1, 2, 4, 8 for i = 0, 1, 2, 3
} }
} }
sprite!!.currentFrame = ret sprite!!.currentFrame = ret
@@ -73,7 +73,7 @@ class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.I
Point2i(x + 1, y), Point2i(x + 1, y),
Point2i(x, y - 1), Point2i(x, y - 1),
Point2i(x - 1, y), Point2i(x - 1, y),
Point2i(x, y + 1) Point2i(x, y + 1) // don't know why but it doesn't work if I don't flip Y
) )
} }

View File

@@ -3,21 +3,21 @@ package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable import com.badlogic.gdx.utils.Disposable
import net.torvald.gdx.graphics.Cvec import net.torvald.gdx.graphics.Cvec
import net.torvald.terrarum.AppLoader import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.ReferencingRanges
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameactors.WireActor
import net.torvald.terrarum.gameitem.ItemID import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator
import net.torvald.terrarum.printStackTrace
import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.serialise.ReadLayerDataZip import net.torvald.terrarum.serialise.ReadLayerDataZip
import net.torvald.terrarum.worlddrawer.CreateTileAtlas import net.torvald.terrarum.worlddrawer.CreateTileAtlas
import net.torvald.util.SortedArrayList import net.torvald.util.SortedArrayList
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
import kotlin.experimental.and
import kotlin.experimental.or
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.sign import kotlin.math.sign
@@ -79,6 +79,9 @@ open class GameWorld : Disposable {
@TEMzPayload("WiNt", TEMzPayload.EXTERNAL_JSON) @TEMzPayload("WiNt", TEMzPayload.EXTERNAL_JSON)
private val wirings: HashMap<BlockAddress, WiringNode> private val wirings: HashMap<BlockAddress, WiringNode>
private val wiringGraph = HashMap<BlockAddress, HashMap<ItemID, Byte>>()
private val WIRE_POS_MAP = byteArrayOf(1,2,4,8)
/** /**
* Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised. * Used by the renderer. When wirings are updated, `wirings` and this properties must be synchronised.
*/ */
@@ -325,11 +328,54 @@ open class GameWorld : Disposable {
if (!bypassEvent) if (!bypassEvent)
Terrarum.ingame?.queueWireChangedEvent(tile, false, LandUtil.getBlockAddr(this, x, y)) Terrarum.ingame?.queueWireChangedEvent(tile, false, LandUtil.getBlockAddr(this, x, y))
// figure out wiring graphs
val matchingNeighbours = WireActor.WIRE_NEARBY.mapIndexed { index, (tx, ty) ->
(getAllWiresFrom(x + tx, y + ty)?.contains(tile) == true).toInt() shl index
}.sum().toByte()
// setup graph of mine
setWireGraphOfUnsafe(blockAddr, tile, matchingNeighbours)
// setup graph for neighbours
for (i in 0.toByte() .. 3.toByte()) {
if (matchingNeighbours and WIRE_POS_MAP[i] > 0) {
val (tx, ty) = WireActor.WIRE_NEARBY[i]
val old = getWireGraphOf(x + tx, y + ty, tile) ?: 0
setWireGraphOf(x + tx, y + ty, tile, old or WIRE_POS_MAP[i])
}
}
}
fun getWireGraphOf(x: Int, y: Int, itemID: ItemID): Byte? {
val (x, y) = coerceXY(x, y)
val blockAddr = LandUtil.getBlockAddr(this, x, y)
return getWireGraphUnsafe(blockAddr, itemID)
}
fun getWireGraphUnsafe(blockAddr: BlockAddress, itemID: ItemID): Byte? {
return wiringGraph[blockAddr]?.get(itemID)
}
fun setWireGraphOf(x: Int, y: Int, itemID: ItemID, byte: Byte) {
val (x, y) = coerceXY(x, y)
val blockAddr = LandUtil.getBlockAddr(this, x, y)
return setWireGraphOfUnsafe(blockAddr, itemID, byte)
}
fun setWireGraphOfUnsafe(blockAddr: BlockAddress, itemID: ItemID, byte: Byte) {
if (wiringGraph[blockAddr] == null)
wiringGraph[blockAddr] = HashMap()
wiringGraph[blockAddr]!![itemID] = byte
} }
fun getAllWiresFrom(x: Int, y: Int): SortedArrayList<ItemID>? { fun getAllWiresFrom(x: Int, y: Int): SortedArrayList<ItemID>? {
val (x, y) = coerceXY(x, y) val (x, y) = coerceXY(x, y)
val blockAddr = LandUtil.getBlockAddr(this, x, y) val blockAddr = LandUtil.getBlockAddr(this, x, y)
return getAllWiresFrom(blockAddr)
}
fun getAllWiresFrom(blockAddr: BlockAddress): SortedArrayList<ItemID>? {
return wirings[blockAddr]?.wires return wirings[blockAddr]?.wires
} }

View File

@@ -910,7 +910,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic
throw RuntimeException("Attempted to remove player.") throw RuntimeException("Attempted to remove player.")
val indexToDelete = actorContainerActive.searchForIndex(actor.referenceID) { it.referenceID!! } val indexToDelete = actorContainerActive.searchForIndex(actor.referenceID) { it.referenceID }
if (indexToDelete != null) { if (indexToDelete != null) {
printdbg(this, "Removing actor $actor") printdbg(this, "Removing actor $actor")
printStackTrace(this) printStackTrace(this)
@@ -978,8 +978,10 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
throw Error("The actor $actor already exists in the game") throw Error("The actor $actor already exists in the game")
} }
else { else {
printdbg(this, "Adding actor $actor") if (actor.referenceID < ReferencingRanges.ACTORS_WIRES.first) {
printStackTrace(this) printdbg(this, "Adding actor $actor")
printStackTrace(this)
}
actorContainerActive.add(actor) actorContainerActive.add(actor)