signal adder

This commit is contained in:
minjaesong
2024-03-10 19:44:16 +09:00
parent a298d6663b
commit 2943f4119c
14 changed files with 207 additions and 11 deletions

View File

@@ -0,0 +1,152 @@
package net.torvald.terrarum.modulebasegame.gameactors
import net.torvald.spriteanimation.SheetSpriteAnimation
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.gameworld.fmod
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.modulebasegame.gameitems.FixtureItemBase
import net.torvald.terrarum.toInt
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import org.dyn4j.geometry.Vector2
/**
* Created by minjaesong on 2024-03-10.
*/
class FixtureLogicSignalAdder : Electric, Reorientable {
@Transient override val spawnNeedsWall = false
@Transient override val spawnNeedsFloor = false
constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 2, 2),
nameFun = { Lang["ITEM_LOGIC_SIGNAL_ADDER"] }
)
override var orientation = 0 // 0 1 2 3
private fun setEmitterAndSink() {
clearStatus()
when (orientation) {
0 -> {
setWireSinkAt(0, 0, "digital_bit")
setWireSinkAt(0, 1, "digital_bit")
setWireEmitterAt(1, 0, "digital_bit")
setWireEmitterAt(1, 1, "digital_bit")
}
1 -> {
setWireSinkAt(1, 0, "digital_bit")
setWireSinkAt(0, 0, "digital_bit")
setWireEmitterAt(1, 1, "digital_bit")
setWireEmitterAt(0, 1, "digital_bit")
}
2 -> {
setWireSinkAt(1, 1, "digital_bit")
setWireSinkAt(1, 0, "digital_bit")
setWireEmitterAt(0, 1, "digital_bit")
setWireEmitterAt(0, 0, "digital_bit")
}
3 -> {
setWireSinkAt(0, 1, "digital_bit")
setWireSinkAt(1, 1, "digital_bit")
setWireEmitterAt(0, 0, "digital_bit")
setWireEmitterAt(1, 0, "digital_bit")
}
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
}
private fun reorient() {
(sprite as SheetSpriteAnimation).currentFrame = orientation
(spriteEmissive as SheetSpriteAnimation).currentFrame = orientation
}
override fun orientClockwise() {
orientation = (orientation + 1) fmod 4
reorient(); setEmitterAndSink(); updateK()
}
override fun orientAnticlockwise() {
orientation = (orientation - 1) fmod 4
reorient(); setEmitterAndSink(); updateK()
}
init {
val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_adder.tga")
val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_adder_emsv.tga")
density = 1400.0
setHitboxDimension(2*TILE_SIZE, 2*TILE_SIZE, 0, 1)
makeNewSprite(TextureRegionPack(itemImage.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
it.setRowsAndFrames(16,4)
it.delays = FloatArray(16) { Float.POSITIVE_INFINITY }
}
makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
it.setRowsAndFrames(16,4)
it.delays = FloatArray(16) { Float.POSITIVE_INFINITY }
}
setEmitterAndSink()
}
override fun reload() {
super.reload()
reorient()
setEmitterAndSink()
updateK()
}
private val I: Boolean
get() = when (orientation) {
0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
1 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
3 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
private val J: Boolean
get() = when (orientation) {
0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
1 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
3 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
private fun updateK() {
val (x1, y1) = when (orientation) {
0 -> 1 to 0
1 -> 1 to 1
2 -> 0 to 1
3 -> 0 to 0
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
val (x2, y2) = when (orientation) {
0 -> 1 to 1
1 -> 0 to 1
2 -> 0 to 0
3 -> 1 to 0
else -> throw IllegalStateException("Orientation not in range ($orientation)")
}
val output1 = (I xor J).toInt().toDouble()
val output2 = (I and J).toInt().toDouble()
setWireEmissionAt(x1, y1, Vector2(output1, 0.0))
setWireEmissionAt(x2, y2, Vector2(output2, 0.0))
// update sprite
val one = isSignalHigh(0, 0)
val two = isSignalHigh(1, 0)
val four = isSignalHigh(0, 1)
val eight = isSignalHigh(1, 1)
val state = one.toInt(0) or two.toInt(1) or four.toInt(2) or eight.toInt(3)
(sprite as SheetSpriteAnimation).currentRow = state
(spriteEmissive as SheetSpriteAnimation).currentRow = state
}
override fun updateSignal() {
updateK()
}
}

View File

@@ -87,4 +87,31 @@ class ItemLogicSignalRepeaterHorz(originalID: ItemID) : FixtureItemBase(original
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = ""
}
}
/**
* Created by minjaesong on 2024-03-10.
*/
class ItemLogicSignalAdder(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalAdder") {
override var dynamicID: ItemID = originalID
override var baseMass = FixtureLogicSignalEmitter.MASS
override val canBeDynamic = false
override val materialId = ""
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsItemSheet("basegame.items").get(14, 3)
override var baseToolSize: Double? = baseMass
override var originalName = "ITEM_LOGIC_SIGNAL_ADDER"
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
super.effectWhileEquipped(actor, delta)
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "signal"
}
override fun effectOnUnequip(actor: ActorWithBody) {
super.effectOnUnequip(actor)
(Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = ""
}
}