mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 20:14:05 +09:00
building wire graph PER TILE
This commit is contained in:
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user