diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemHomeComputer.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemHomeComputer.kt index 04eec156e..7f4f3bc57 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemHomeComputer.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemHomeComputer.kt @@ -36,7 +36,7 @@ class ItemHomeComputer(originalID: ItemID) : GameItem(originalID) { override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = mouseInInteractableRange(actor) { val item = FixtureHomeComputer() - item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1) + if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)) 1L else -1L // return true when placed, false when cannot be placed } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index f34980e52..eef309295 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -298,16 +298,8 @@ object Terrarum : Disposable { else -> throw IllegalArgumentException("Invalid vector index $vector for subtile $this") } - fun getNextTileCoord() = when (vector) { - SubtileVector.CENTRE -> x to y - SubtileVector.RIGHT -> (x + 1) to y - SubtileVector.BOTTOM -> x to (y + 1) - SubtileVector.LEFT -> (x - 1) to y - SubtileVector.TOP -> x to (y - 1) - else -> throw IllegalArgumentException("Invalid vector index $vector for subtile $this") - } - - fun getCurrentTileCoord() = x to y + val currentTileCoord = x to y + val nextTileCoord = nx to ny } fun getMouseSubtile4(): MouseSubtile4 { diff --git a/src/net/torvald/terrarum/gameitems/GameItem.kt b/src/net/torvald/terrarum/gameitems/GameItem.kt index a7a1a6bce..abdce512b 100644 --- a/src/net/torvald/terrarum/gameitems/GameItem.kt +++ b/src/net/torvald/terrarum/gameitems/GameItem.kt @@ -364,6 +364,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl /** * @param actor actor to check the reach * @param action returns true if the action was successfully performed + * @return an amount to remove from the inventory (>= 0); -1 if the action failed or not in interactable range */ fun mouseInInteractableRange(actor: ActorWithBody, action: () -> Long): Long { val mousePos1 = Vector2(Terrarum.mouseX, Terrarum.mouseY) diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 76d5af31d..4969c2c02 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -622,8 +622,8 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { ) it.setAsOpen() } - true - }) break + 0L + } == 0L) break } } @@ -638,7 +638,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { else if (itemOnGrip == null) { mouseInInteractableRange(actor) { performBarehandAction(actor, delta) - true + 0L } } } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/HumanoidNPC.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/HumanoidNPC.kt index 1e86f784f..bee516bc4 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/HumanoidNPC.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/HumanoidNPC.kt @@ -50,17 +50,17 @@ open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem { override val isDynamic = false override val material = Material() - override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Boolean { + override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long { try { // place the actor to the world this@HumanoidNPC.setPosition(Terrarum.mouseX, Terrarum.mouseY) INGAME.queueActorAddition(this@HumanoidNPC) // successful - return true + return 1 } catch (e: Exception) { e.printStackTrace() - return false + return -1 } } } diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt index 996a05833..abc61b7dc 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt @@ -1,10 +1,12 @@ package net.torvald.terrarum.modulebasegame.gameitems +import com.badlogic.gdx.Gdx import net.torvald.terrarum.* import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.mouseInInteractableRange +import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.TerrarumIngame /** @@ -75,17 +77,69 @@ object BlockBase { } private fun Int.shiftByTwo() = this.shl(4).or(this).ushr(2).and(15) - private fun connectedEachOther(one: Int, other: Int) = one.shiftByTwo() and other != 0 + private fun connectedEachOther(one: Int?, other: Int?) = + if (one == null || other == null) false + else (one.shiftByTwo().and(other) != 0) + + private var initialMouseDownTileX = -1 // keeps track of the tile coord where the mouse was just down (not dragged-on) + private var initialMouseDownTileY = -1 + + private var oldTileX = -1 + private var oldTileY = -1 + + private fun placeWirePieceTo(world: GameWorld, item: ItemID, x: Int, y: Int) { + world.setTileWire(x, y, item, false, 0) + } + + /** + * This function assumes xy and oxy are neighboured and tiles are correctly placed + */ + private fun setConnectivity(world: GameWorld, item: ItemID, x: Int, y: Int, ox: Int, oy: Int) { + val thisNodeCnx = world.getWireGraphOf(x, y, item)!! + val otherNodeCnx = world.getWireGraphOf(ox, oy, item)!! + + val vec = if (x - ox == 1) 4 // direction from thisNode towards the otherNode. [1, 2, 4, 8] = [RIGHT, DOWN, LEFT, UP] + else if (x - ox == -1) 1 + else if (y - oy == 1) 8 + else 2 + val antivec = if (x - ox == 1) 1 + else if (x - ox == -1) 4 + else if (y - oy == 1) 2 + else 8 + + world.setWireGraphOf(x, y, item, vec or thisNodeCnx) + world.setWireGraphOf(ox, oy, item, antivec or otherNodeCnx) + } fun wireStartPrimaryUse(actor: ActorWithBody, gameItem: GameItem, delta: Float) = mouseInInteractableRange(actor) { + val itemID = gameItem.originalID val ingame = Terrarum.ingame!! as TerrarumIngame - val mouseTile = Terrarum.getMouseSubtile4() + val mouseTileX = Terrarum.mouseTileX + val mouseTileY = Terrarum.mouseTileY - val thisTileWires = ingame.world.getAllWiresFrom(mouseTile.x, mouseTile.y) - val otherTileWires = ingame.world.getAllWiresFrom(mouseTile.nx, mouseTile.ny) - val thisTileWireCnx = ingame.world.getWireGraphOf(mouseTile.x, mouseTile.y, itemID) - val otherTileWireCnx = ingame.world.getWireGraphOf(mouseTile.x, mouseTile.y, itemID) + if (Gdx.input.isButtonJustPressed(App.getConfigInt("config_mouseprimary")) || + // reset dragged-on status when there's drag-discontinuity (not dragging towards the neighbouring tiles) + !((oldTileX - mouseTileX).abs() == 1 && (oldTileY - mouseTileY).abs() == 0 || + (oldTileX - mouseTileX).abs() == 0 && (oldTileY - mouseTileY).abs() == 1) + ) { + initialMouseDownTileX = mouseTileX + initialMouseDownTileY = mouseTileY + oldTileX = mouseTileX + oldTileY = mouseTileY + } + + val thisTileWires = ingame.world.getAllWiresFrom(mouseTileX, mouseTileY) + val oldTileWires = ingame.world.getAllWiresFrom(oldTileX, oldTileY) + val thisTileWireCnx = ingame.world.getWireGraphOf(mouseTileX, mouseTileY, itemID) + val oldTileWireCnx = ingame.world.getWireGraphOf(oldTileX, oldTileY, itemID) + + val thisTileOccupied = thisTileWires?.searchFor(itemID) != null + val oldTileOccupied = oldTileWires?.searchFor(itemID) != null + val connectedEachOther = connectedEachOther(thisTileWireCnx, oldTileWireCnx) + val thisTileWasDraggedOn = initialMouseDownTileX != mouseTileX || initialMouseDownTileY != mouseTileY + + var ret = -1L // cases: // * regardless of vector, this tile was not dragged-on @@ -97,11 +151,30 @@ object BlockBase { // else: place the tile, set connectivity, then return 1 // (dragged-on: let net.torvald.terrarum.Terrarum record the tile that the mouse button was just down, // and the poll again later; if tile now != recorded tile, it is dragged-on) + if (!thisTileWasDraggedOn) { + if (thisTileOccupied) return@mouseInInteractableRange -1 + else { + placeWirePieceTo(ingame.world, itemID, mouseTileX, mouseTileY) + ret = 1 + } + } + else { + if (thisTileOccupied && connectedEachOther) return@mouseInInteractableRange -1 + else if (thisTileOccupied && oldTileOccupied) { + setConnectivity(ingame.world, itemID, mouseTileX, mouseTileY, oldTileX, oldTileY) + ret = 0 + } + else { + placeWirePieceTo(ingame.world, itemID, mouseTileX, mouseTileY) + setConnectivity(ingame.world, itemID, mouseTileX, mouseTileY, oldTileX, oldTileY) + ret = 1 + } + } - // TODO + oldTileX = mouseTileX + oldTileY = mouseTileY - - TODO() + ret } fun wireEffectWhenEquipped(gameItem: GameItem, delta: Float) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/FixtureItemBase.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/FixtureItemBase.kt index 98632ddfb..3ace402e3 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/FixtureItemBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/FixtureItemBase.kt @@ -3,7 +3,6 @@ package net.torvald.terrarum.modulebasegame.gameitems import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.* -import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID @@ -11,7 +10,6 @@ import net.torvald.terrarum.gameitems.mouseInInteractableRange import net.torvald.terrarum.itemproperties.Material import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase -import net.torvald.terrarum.utils.RandomWordsName import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicReference @@ -72,7 +70,7 @@ open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : G it.isVisible = true it.update(delta) it.setGhostColourBlock() - mouseInInteractableRange(actor) { it.setGhostColourAllow(); true } + mouseInInteractableRange(actor) { it.setGhostColourAllow(); 0L } } } @@ -89,7 +87,7 @@ open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : G override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = mouseInInteractableRange(actor) { val item = ghostItem.getAndSet(makeFixture()) // renew the "ghost" otherwise you'll be spawning exactly the same fixture again; old ghost will be returned - item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1) + if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)) 1 else -1 // return true when placed, false when cannot be placed } diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt index 45cfe4759..d474e1d56 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/PickaxeGeneric.kt @@ -131,7 +131,8 @@ class PickaxeCopper(originalID: ItemID) : GameItem(originalID) { super.tags.add("PICK") } - override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.startPrimaryUse(actor, delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY) + override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = + if (PickaxeCore.startPrimaryUse(actor, delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY)) 0L else -1L override fun endPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.endPrimaryUse(actor, delta, this) } @@ -160,7 +161,8 @@ class PickaxeIron(originalID: ItemID) : GameItem(originalID) { super.tags.add("PICK") } - override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.startPrimaryUse(actor , delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY) + override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = + if (PickaxeCore.startPrimaryUse(actor , delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY)) 0L else -1L override fun endPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.endPrimaryUse(actor, delta, this) } @@ -189,6 +191,7 @@ class PickaxeSteel(originalID: ItemID) : GameItem(originalID) { super.tags.add("PICK") } - override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.startPrimaryUse(actor, delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY) + override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = + if (PickaxeCore.startPrimaryUse(actor, delta, this, Terrarum.mouseTileX, Terrarum.mouseTileY)) 0L else -1L override fun endPrimaryUse(actor: ActorWithBody, delta: Float) = PickaxeCore.endPrimaryUse(actor, delta, this) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt index b3aeef528..d6761c78e 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt @@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.Point2i import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.GameItem @@ -45,9 +44,9 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID) { wires?.forEach { ingame.world.removeTileWire(mouseTile.x, mouseTile.y, it, false) ingame.queueActorAddition(DroppedItem(it, mouseTile.x * TILE_SIZED, mouseTile.y * TILE_SIZED)) - } ?: return@mouseInInteractableRange false + } ?: return@mouseInInteractableRange -1L - true + 0L } override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {