diff --git a/assets/mods/basegame/items/itemid.csv b/assets/mods/basegame/items/itemid.csv index a647606c7..612593f9e 100644 --- a/assets/mods/basegame/items/itemid.csv +++ b/assets/mods/basegame/items/itemid.csv @@ -43,6 +43,7 @@ id;classname;tags 42;net.torvald.terrarum.modulebasegame.gameitems.ItemTableBirch;FIXTURE,SURFACE 43;net.torvald.terrarum.modulebasegame.gameitems.ItemTableRosewood;FIXTURE,SURFACE 44;net.torvald.terrarum.modulebasegame.gameitems.ItemSignalBlocker;FIXTURE,SIGNAL +45;net.torvald.terrarum.modulebasegame.gameitems.ItemSignalLatch;FIXTURE,SIGNAL # ingots 26;net.torvald.terrarum.modulebasegame.gameitems.IngotSteel;INGOT diff --git a/assets/mods/basegame/items/items.tga b/assets/mods/basegame/items/items.tga index 96da69951..82157046a 100644 --- a/assets/mods/basegame/items/items.tga +++ b/assets/mods/basegame/items/items.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3c0ec3f25da79b846fbd653d417217456f455b8ee6bdc3ec028f5c4b92551021 +oid sha256:657154947d1f36431568a9f8625bb7a0d26ebd41c8f7fa38287c0cb36801c46e size 2408466 diff --git a/assets/mods/basegame/sprites/fixtures/signal_latch.tga b/assets/mods/basegame/sprites/fixtures/signal_latch.tga new file mode 100644 index 000000000..2c7b62c2c --- /dev/null +++ b/assets/mods/basegame/sprites/fixtures/signal_latch.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:808185b5324f5721093daf9833d0a0302eb1ee6ad2d3530f0643ef9e7278ab9e +size 6162 diff --git a/assets/mods/basegame/sprites/fixtures/signal_latch_emsv.tga b/assets/mods/basegame/sprites/fixtures/signal_latch_emsv.tga new file mode 100644 index 000000000..dd60cd863 --- /dev/null +++ b/assets/mods/basegame/sprites/fixtures/signal_latch_emsv.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15f6c66914ec2b6a99657ec3b06e090bd06ca3a92a0831031176b4f18d784150 +size 6162 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt index 4b6b1437f..2ec0294aa 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt @@ -9,6 +9,8 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import org.dyn4j.geometry.Vector2 /** + * Implements a Nimply gate. + * * Created by minjaesong on 2024-03-04. */ interface Reorientable { @@ -21,7 +23,7 @@ interface Reorientable { */ fun orientAnticlockwise() /** - * strictly 0 1 2 3. If your fixture can only be oriented in two ways, use value 0 2. + * strictly 0 1 2 3. If your fixture can only be oriented in two ways, use value 0 1(normal, 90 deg) or 0 2(normal, upside-down/flipped). */ var orientation: Int } @@ -39,7 +41,7 @@ class FixtureSignalBlocker : Electric, Reorientable { nameFun = { Lang["ITEM_LOGIC_SIGNAL_BLOCKER"] } ) - override var orientation = 0 + override var orientation = 0 // 0 1 2 3 private fun setEmitterAndSink() { when (orientation) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalLatch.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalLatch.kt new file mode 100644 index 000000000..eeab99eba --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalLatch.kt @@ -0,0 +1,146 @@ +package net.torvald.terrarum.modulebasegame.gameactors + +import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE +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 + +/** + * Implements a D-Flip Flop with extra Set/Reset pins. + * + * Created by minjaesong on 2024-03-05. + */ +class FixtureSignalLatch : Electric, Reorientable { + + @Transient override val spawnNeedsWall = false + @Transient override val spawnNeedsFloor = false + + constructor() : super( + BlockBox(BlockBox.NO_COLLISION, 2, 3), + nameFun = { Lang["ITEM_LOGIC_SIGNAL_LATCH"] } + ) + + override var orientation = 0 // 0 2, where 2 is a mirror-image rather than rotation + + private fun setEmitterAndSink() { + when (orientation) { + 0 -> { + setWireSinkAt(0, 0, "digital_bit") // D + setWireEmitterAt(1, 0, "digital_bit") // Q + setWireSinkAt(0, 1, "digital_bit") // CLK + setWireSinkAt(0, 2, "digital_bit") // S + setWireSinkAt(1, 2, "digital_bit") // R + } + 2 -> { + setWireSinkAt(1, 0, "digital_bit") // D + setWireEmitterAt(0, 0, "digital_bit") // Q + setWireSinkAt(1, 0, "digital_bit") // CLK + setWireSinkAt(1, 2, "digital_bit") // S + setWireSinkAt(0, 2, "digital_bit") // R + } + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + } + + + override fun orientClockwise() { + orientation = (orientation + 2) % 4 + setEmitterAndSink(); updateQ() + } + override fun orientAnticlockwise() { + orientation = (orientation - 2) % 4 + setEmitterAndSink(); updateQ() + } + + + init { + val itemImage = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_latch.tga") + val itemImage2 = FixtureItemBase.getItemImageFromSingleImage("basegame", "sprites/fixtures/signal_latch_emsv.tga") + + density = 1400.0 + setHitboxDimension(2*TILE_SIZE, 3*TILE_SIZE, 0, 1) + + makeNewSprite(TextureRegionPack(itemImage.texture, 2*TILE_SIZE, 3*TILE_SIZE)).let { + it.setRowsAndFrames(16,4) + it.delays = FloatArray(16) { Float.POSITIVE_INFINITY } + } + makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, 2*TILE_SIZE, 3*TILE_SIZE)).let { + it.setRowsAndFrames(16,4) + it.delays = FloatArray(16) { Float.POSITIVE_INFINITY } + } + + setEmitterAndSink() + } + + override fun reload() { + super.reload() + setEmitterAndSink() + updateQ() + } + + private var internalState = false + + private val D: Boolean + get() = when (orientation) { + 0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + 2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + + private var CLK0old: Boolean = false + + private val CLK0: Boolean + get() = when (orientation) { + 0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + 2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + + private val S: Boolean + get() = when (orientation) { + 0 -> getWireStateAt(0, 2, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + 2 -> getWireStateAt(1, 2, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + + private val R: Boolean + get() = when (orientation) { + 0 -> getWireStateAt(1, 2, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + 2 -> getWireStateAt(0, 2, "digital_bit").x >= ELECTRIC_THRESHOLD_HIGH + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + + private fun updateQ() { + val (x, y) = when (orientation) { + 0 -> 1 to 0 + 2 -> 0 to 0 + else -> throw IllegalStateException("Orientation not in range ($orientation)") + } + // "capture" the input pin states + val D = this.D + val CLK0 = this.CLK0 + val CLK = (!CLK0old && CLK0) // only TRUE on rising edge + val S = this.S + val R = this.R + + // force set internal state + if (S && !R) internalState = true // Set + else if (!S && R) internalState = false // Reset + else if (S && R) internalState = !internalState // Toggle + else if (CLK) internalState = D + + // if force set pin is not high and clock is pulsed, make transition; stay otherwise + val output = internalState + setWireEmissionAt(x, y, Vector2(output.toInt().toDouble(), 0.0)) + + CLK0old = CLK0 + + // TODO update sprite + } + + override fun updateSignal() { + updateQ() + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemSignalBlocker.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemSignalBlocker.kt index 924f42fc6..eea1b01f2 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemSignalBlocker.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemSignalBlocker.kt @@ -33,4 +33,31 @@ class ItemSignalBlocker(originalID: ItemID) : FixtureItemBase(originalID, "net.t (Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "" } +} + +/** + * Created by minjaesong on 2024-03-05. + */ +class ItemSignalLatch(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureSignalLatch") { + + 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(11, 3) + + override var baseToolSize: Double? = baseMass + override var originalName = "ITEM_LOGIC_SIGNAL_LATCH" + + 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 = "" + } + } \ No newline at end of file diff --git a/work_files/graphics/items/basegame_items.kra b/work_files/graphics/items/basegame_items.kra index 985bbea23..e62bbba8e 100644 --- a/work_files/graphics/items/basegame_items.kra +++ b/work_files/graphics/items/basegame_items.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5de7c1440cf95b983da15c1e758e22614e561985df0ca85e41f7ddffcde5b80 -size 1448581 +oid sha256:37967211b23bf87bc90280ea9800c243a0b7c59e5e761b72bd028edf0b8d9bf9 +size 1463128 diff --git a/work_files/graphics/wires/wire_single_items.kra b/work_files/graphics/wires/wire_single_items.kra index 17bddb590..d9961fc1b 100644 --- a/work_files/graphics/wires/wire_single_items.kra +++ b/work_files/graphics/wires/wire_single_items.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8430213e3a9f6e1d7620cce8404948e30e626cbf916c800f452114bfbeebe06 -size 383829 +oid sha256:8575952bba17c6fe9107162fdf9ea8879a7ca98fbc8b1eb6906d59f35478ca80 +size 476723