multiblock fixtures can now emit/consume multiple wiring types

This commit is contained in:
minjaesong
2021-08-10 16:56:22 +09:00
parent 43ae93e982
commit f1cece1064
3 changed files with 49 additions and 16 deletions

View File

@@ -11,10 +11,12 @@ import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitem.ItemID import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.BlockBoxIndex
import net.torvald.terrarum.modulebasegame.gameactors.Electric
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
import net.torvald.terrarum.worlddrawer.BlocksDrawer
import net.torvald.terrarum.worlddrawer.WorldCamera
import org.khelekore.prtree.* import org.khelekore.prtree.*
import java.util.*
import kotlin.collections.ArrayList
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** /**
@@ -453,16 +455,34 @@ object WorldSimulator {
private val wiresimOverscan = 60 private val wiresimOverscan = 60
/**
* @return List of FixtureBases, safe to cast into Electric
*/
private fun wiresimGetSourceBlocks(): List<FixtureBase> = private fun wiresimGetSourceBlocks(): List<FixtureBase> =
Terrarum.ingame!!.actorContainerActive.filter { Terrarum.ingame!!.actorContainerActive.filter {
it is FixtureBase && it.inUpdateRange(world) && it.wireEmitterType.isNotBlank() it is FixtureBase && it is Electric && it.inUpdateRange(world) && it.wireEmitterTypes.isNotEmpty()
} as List<FixtureBase> } as List<FixtureBase>
private fun simulateWires(delta: Float) { private fun simulateWires(delta: Float) {
wiresimGetSourceBlocks().let { sources -> wiresimGetSourceBlocks().let { sources ->
// signal-emitting fixtures must set emitState of its own tiles via update() // signal-emitting fixtures must set emitState of its own tiles via update()
sources.forEach { sources.forEach {
// TODO (it as Electric).wireEmitterTypes.forEach { wireType, bbi ->
traverseWireGraph(world, it, wireType, bbi)
}
}
}
}
private fun traverseWireGraph(world: GameWorld, fixture: FixtureBase, wireType: String, bbi: BlockBoxIndex) {
fixture.worldBlockPos?.let {
val branchesVisited = ArrayList<Point2i>()
val branchingStack = Stack<Point2i>()
val startPoint = it + fixture.blockBoxIndexToPoint2i(bbi)
branchingStack.push(startPoint)
while (branchingStack.isNotEmpty()) {
} }
} }
} }
@@ -487,7 +507,7 @@ object WorldSimulator {
WireConStatus.BRANCH // 1111 WireConStatus.BRANCH // 1111
) )
data class wireGraphBranch( data class WireGraphBranch(
val x: Int, val x: Int,
val y: Int, val y: Int,
val con: Byte val con: Byte

View File

@@ -14,6 +14,14 @@ import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
typealias BlockBoxIndex = Int
interface Electric {
val wireEmitterTypes: HashMap<String, BlockBoxIndex>
val wireEmission: HashMap<BlockBoxIndex, Vector2>
val wireConsumption: HashMap<BlockBoxIndex, Vector2>
}
/** /**
* Created by minjaesong on 2016-06-17. * Created by minjaesong on 2016-06-17.
*/ */
@@ -29,15 +37,15 @@ open class FixtureBase(
var blockBox: BlockBox = blockBox0 var blockBox: BlockBox = blockBox0
protected set // something like TapestryObject will want to redefine this protected set // something like TapestryObject will want to redefine this
fun blockBoxIndexToPoint2i(it: BlockBoxIndex): Point2i = this.blockBox.width.let { w -> Point2i(it % w, it / w) }
open val wireEmitterType = ""
open val wireEmission = Vector2()
open val wireConsumption = Vector2()
/** /**
* Block-wise position of this fixture when it's placed on the world. Null if it's not on the world * Tile-wise position of this fixture when it's placed on the world, top-left origin. Null if it's not on the world
*/ */
protected var worldBlockPos: Point2i? = null var worldBlockPos: Point2i? = null
private set
init { init {
if (mainUI != null) if (mainUI != null)

View File

@@ -7,10 +7,12 @@ import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.dyn4j.geometry.Vector2 import org.dyn4j.geometry.Vector2
class FixtureLogicSignalEmitter(nameFun: () -> String) : FixtureBase(BlockBox(BlockBox.NO_COLLISION, 1, 1), nameFun = nameFun) { class FixtureLogicSignalEmitter(nameFun: () -> String)
: FixtureBase(BlockBox(BlockBox.NO_COLLISION, 1, 1), nameFun = nameFun), Electric {
override val wireEmitterType = "digital_bit" override val wireEmitterTypes: HashMap<String, BlockBoxIndex> = HashMap()
override val wireEmission = Vector2(1.0, 0.0) override val wireEmission: HashMap<BlockBoxIndex, Vector2> = HashMap()
override val wireConsumption: HashMap<BlockBoxIndex, Vector2> = HashMap()
init { init {
density = 1400.0 density = 1400.0
@@ -20,6 +22,9 @@ class FixtureLogicSignalEmitter(nameFun: () -> String) : FixtureBase(BlockBox(Bl
sprite!!.setRowsAndFrames(1, 1) sprite!!.setRowsAndFrames(1, 1)
actorValue[AVKey.BASEMASS] = MASS actorValue[AVKey.BASEMASS] = MASS
wireEmitterTypes["digital_bit"] = 0
wireEmission[0] = Vector2(1.0, 0.0)
} }
override fun dispose() { } override fun dispose() { }
@@ -31,8 +36,8 @@ class FixtureLogicSignalEmitter(nameFun: () -> String) : FixtureBase(BlockBox(Bl
override fun update(delta: Float) { override fun update(delta: Float) {
// set emit // set emit
worldBlockPos?.let { (x, y) -> worldBlockPos?.let { (x, y) ->
WireCodex.getAll().filter { it.renderClass == "signal" }.forEach { prop -> WireCodex.getAll().filter { it.accepts == "digital_bit" }.forEach { prop ->
world?.setWireEmitStateOf(x, y, prop.id, wireEmission) world?.setWireEmitStateOf(x, y, prop.id, wireEmission[0]!!)
} }
} }
} }