electric: rising/falling edge and level detection

This commit is contained in:
minjaesong
2023-06-19 18:42:08 +09:00
parent 528b975350
commit 7a42066392
7 changed files with 132 additions and 72 deletions

View File

@@ -389,14 +389,14 @@ open class GameWorld(
return wiringGraph[blockAddr]?.get(itemID)?.emt
}
fun getWireRecvStateOf(x: Int, y: Int, itemID: ItemID): ArrayList<WireRecvState>? {
fun getWireReceptionStateOf(x: Int, y: Int, itemID: ItemID): ArrayList<WireReceptionState>? {
val (x, y) = coerceXY(x, y)
val blockAddr = LandUtil.getBlockAddr(this, x, y)
return getWireRecvStateUnsafe(blockAddr, itemID)
return getWireReceptionStateUnsafe(blockAddr, itemID)
}
fun getWireRecvStateUnsafe(blockAddr: BlockAddress, itemID: ItemID): ArrayList<WireRecvState>? {
return wiringGraph[blockAddr]?.get(itemID)?.rcv
fun getWireReceptionStateUnsafe(blockAddr: BlockAddress, itemID: ItemID): ArrayList<WireReceptionState>? {
return wiringGraph[blockAddr]?.get(itemID)?.rcp
}
fun setWireGraphOf(x: Int, y: Int, itemID: ItemID, cnx: Int) {
@@ -429,7 +429,7 @@ open class GameWorld(
wiringGraph[blockAddr]!![itemID]!!.emt.set(vector)
}
fun addWireRecvStateOf(x: Int, y: Int, itemID: ItemID, state: WireRecvState) {
fun addWireRecvStateOf(x: Int, y: Int, itemID: ItemID, state: WireReceptionState) {
val (x, y) = coerceXY(x, y)
val blockAddr = LandUtil.getBlockAddr(this, x, y)
return addWireRecvStateOfUnsafe(blockAddr, itemID, state)
@@ -441,13 +441,13 @@ open class GameWorld(
return clearAllWireRecvStateUnsafe(blockAddr)
}
fun addWireRecvStateOfUnsafe(blockAddr: BlockAddress, itemID: ItemID, state: WireRecvState) {
fun addWireRecvStateOfUnsafe(blockAddr: BlockAddress, itemID: ItemID, state: WireReceptionState) {
if (wiringGraph[blockAddr] == null)
wiringGraph[blockAddr] = WiringGraphMap()
if (wiringGraph[blockAddr]!![itemID] == null)
wiringGraph[blockAddr]!![itemID] = WiringSimCell(0)
wiringGraph[blockAddr]!![itemID]!!.rcv.add(state)
wiringGraph[blockAddr]!![itemID]!!.rcp.add(state)
}
fun getAllWiringGraph(x: Int, y: Int): HashMap<ItemID, WiringSimCell>? {
@@ -462,7 +462,7 @@ open class GameWorld(
fun clearAllWireRecvStateUnsafe(blockAddr: BlockAddress) {
wiringGraph[blockAddr]?.forEach {
it.value.rcv.clear()
it.value.rcp.clear()
}
}
@@ -654,7 +654,7 @@ open class GameWorld(
val ws: SortedArrayList<ItemID> = SortedArrayList<ItemID>() // what could possibly go wrong bloating up the RAM footprint when it's practically infinite these days?
)
data class WireRecvState(
data class WireReceptionState(
var dist: Int = -1, // how many tiles it took to traverse
var src: Point2i = Point2i(0,0) // xy position
// to get the state, use the src to get the state of the source emitter directly, then use dist to apply attenuation
@@ -666,7 +666,7 @@ open class GameWorld(
data class WiringSimCell(
var cnx: Int = 0, // connections. [1, 2, 4, 8] = [RIGHT, DOWN, LEFT, UP]
val emt: Vector2 = Vector2(0.0, 0.0), // i'm emitting this much power
val rcv: ArrayList<WireRecvState> = ArrayList() // how far away are the power sources
val rcp: ArrayList<WireReceptionState> = ArrayList() // how far away are the power sources
)
fun getTemperature(worldTileX: Int, worldTileY: Int): Float? {

View File

@@ -469,15 +469,15 @@ object WorldSimulator {
/**
* @return List of FixtureBases, safe to cast into Electric
*/
private fun wiresimGetSourceBlocks(): List<FixtureBase> =
INGAME.actorContainerActive.filterIsInstance<FixtureBase>().filter {
it is Electric && it.inUpdateRange(world) && it.wireEmitterTypes.isNotEmpty()
private fun wiresimGetSourceBlocks(): List<Electric> =
INGAME.actorContainerActive.filterIsInstance<Electric>().filter {
it.inUpdateRange(world) && it.wireEmitterTypes.isNotEmpty()
}
private val wireSimMarked = HashSet<Long>()
private val wireSimPoints = Queue<WireGraphCursor>()
private val oldTraversedNodes = ArrayList<WireGraphCursor>()
private val fixtureCache = HashMap<Point2i, Pair<FixtureBase, WireEmissionType>>() // also instance of Electric
private val fixtureCache = HashMap<Point2i, Pair<Electric, WireEmissionType>>() // also instance of Electric
private fun simulateWires(delta: Float) {
// unset old wires before we begin
@@ -491,10 +491,10 @@ object WorldSimulator {
wiresimGetSourceBlocks().let { sources ->
// signal-emitting fixtures must set emitState of its own tiles via update()
sources.forEach {
(it as Electric).wireEmitterTypes.forEach { bbi, wireType ->
it.wireEmitterTypes.forEach { bbi, wireType ->
val startingPoint = it.worldBlockPos!! + it.blockBoxIndexToPoint2i(bbi)
val signal = (it as Electric).wireEmission[bbi] ?: Vector2(0.0, 0.0)
val signal = it.wireEmission[bbi] ?: Vector2(0.0, 0.0)
world.getAllWiringGraph(startingPoint.x, startingPoint.y)?.keys?.filter { WireCodex[it].accepts == wireType }?.forEach { wire ->
val simStartingPoint = WireGraphCursor(startingPoint, wire)
@@ -553,20 +553,19 @@ object WorldSimulator {
if (fixture == null) {
INGAME.getActorsAt(point.x * TILE_SIZED, point.y * TILE_SIZED).filterIsInstance<Electric>().firstOrNull().let { found ->
if (found != null) {
val foundFixture = (found as FixtureBase)
// get offset from the fixture's origin
tileOffsetFromFixture = foundFixture.intTilewiseHitbox.let { Point2i(it.startX.toInt(), it.startY.toInt()) } - tilePoint
tileOffsetFromFixture = found.intTilewiseHitbox.let { Point2i(it.startX.toInt(), it.startY.toInt()) } - tilePoint
// println("$tilePoint; ${found.javaClass.canonicalName}, $tileOffsetFromFixture, ${found.getWireSinkAt(tileOffsetFromFixture!!)}")
if (found.getWireSinkAt(tileOffsetFromFixture!!) == emissionType) {
fixtureCache[tilePoint] = foundFixture to emissionType
fixture = foundFixture to emissionType
fixtureCache[tilePoint] = found to emissionType
fixture = found to emissionType
}
}
}
}
(fixture?.first as? Electric)?.updateOnWireGraphTraversal(tileOffsetFromFixture!!.x, tileOffsetFromFixture!!.y, fixture!!.second)
fixture?.first?.updateOnWireGraphTraversal(tileOffsetFromFixture!!.x, tileOffsetFromFixture!!.y, fixture!!.second)
}
}