diff --git a/src/net/torvald/terrarum/gameitems/GameItem.kt b/src/net/torvald/terrarum/gameitems/GameItem.kt index d171aeaf8..4a1a3e9d3 100644 --- a/src/net/torvald/terrarum/gameitems/GameItem.kt +++ b/src/net/torvald/terrarum/gameitems/GameItem.kt @@ -103,8 +103,10 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl var itemProperties = ItemValue() - /** Single-use then destroyed (e.g. Tiles), same as "consumable" */ + /** Single-use then destroyed (e.g. Tiles) */ @Transient var stackable: Boolean = true + val isConsumable: Boolean + get() = stackable && !canBeDynamic /** @@ -449,3 +451,8 @@ fun ItemID.isBlock() = !this.contains('@') && !this.isDynamic() fun ItemID.isWall() = this.startsWith("wall@") fun ItemID.isFluid() = this.startsWith("fluid@") fun ItemID.isOre() = this.startsWith("ores@") + +/** + * Created by minjaesong on 2024-03-06. + */ +interface FixtureInteractionBlocked diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index ffb2ec278..6f227f157 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -23,6 +23,7 @@ import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gamecontroller.IngameController import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent +import net.torvald.terrarum.gameitems.FixtureInteractionBlocked import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.mouseInInteractableRange import net.torvald.terrarum.gameparticles.ParticleBase @@ -716,33 +717,22 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { //////////////////////////////// - // #1. If holding an item, use it + // #1. Consume an consumables // don't want to open the UI and use the item at the same time, would ya? - if (itemOnGrip != null) { + if (itemOnGrip?.isConsumable == true) { + // click filtering (latch stuff) is handled by IngameController (see inventoryCategoryAllowClickAndDrag) val consumptionSuccessful = itemOnGrip.startPrimaryUse(actor, delta) if (consumptionSuccessful > -1) (actor as Pocketed).inventory.consumeItem(itemOnGrip, consumptionSuccessful) - // TODO filter blocks/walls/wires/wire cutter - if (fixtureUnderMouse != null) { - if (!worldPrimaryClickLatch) { - mouseInInteractableRange(actor) { mwx, mwy, mtx, mty -> - fixtureUnderMouse.let { fixture -> - fireFixtureInteractEvent(fixture, mwx, mwy) - } - 0L - } - } - } - worldPrimaryClickLatch = true } - else { + else { // held item is not consumable or holding no items mouseInInteractableRange(actor) { mwx, mwy, mtx, mty -> // #2. interact with the fixture // scan for the one with non-null UI. // what if there's multiple of such fixtures? whatever, you are supposed to DISALLOW such situation. - if (fixtureUnderMouse != null) { + if (fixtureUnderMouse != null && itemOnGrip !is FixtureInteractionBlocked) { if (!worldPrimaryClickLatch) { worldPrimaryClickLatch = true fixtureUnderMouse.let { fixture -> @@ -765,14 +755,22 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { } } } - 0L } - // #3. If not holding any item and can do barehandaction (size big enough that barehandactionminheight check passes), do it + // #3. If no fixture under mouse or FixtureInteractionBlocked, use the item + else if (itemOnGrip != null) { + // click filtering (latch stuff) is handled by IngameController (see inventoryCategoryAllowClickAndDrag) + val consumptionSuccessful = itemOnGrip.startPrimaryUse(actor, delta) + if (consumptionSuccessful > -1) + (actor as Pocketed).inventory.consumeItem(itemOnGrip, consumptionSuccessful) + + worldPrimaryClickLatch = true + } + // #4. If not holding any item and can do barehandaction (size big enough that barehandactionminheight check passes), do it else { performBarehandAction(actor, delta, mwx, mwy, mtx, mty) - 0L } + 0L } } } @@ -794,14 +792,12 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { override fun worldSecondaryClickStart(actor: ActorWithBody, delta: Float) { val itemOnGrip = ItemCodex[(actor as Pocketed).inventory.itemEquipped.get(GameItem.EquipPosition.HAND_GRIP)] - // #1. If ~~there is no UI under and~~ I'm holding an item, use it + // #1. Perform item's secondaryUse // don't want to open the UI and use the item at the same time, would ya? - if (itemOnGrip != null) { - val consumptionSuccessful = itemOnGrip.startSecondaryUse(actor, delta) - if (consumptionSuccessful > -1) - (actor as Pocketed).inventory.consumeItem(itemOnGrip, consumptionSuccessful) - } - // #2. Try to pick up the fixture + val consumptionSuccessful = itemOnGrip?.startSecondaryUse(actor, delta) ?: -1 + if (consumptionSuccessful > -1) + (actor as Pocketed).inventory.consumeItem(itemOnGrip!!, consumptionSuccessful) + // #2. If #1 failed, try to pick up the fixture else { mouseInInteractableRange(actor) { mwx, mwy, mtx, mty -> pickupFixture(actor, delta, mwx, mwy, mtx, mty) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt index dd5a47317..ca42c2f61 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt @@ -100,7 +100,7 @@ class ActorInventory() : FixtureInventory() { if (amount < 0) throw IllegalArgumentException("Consuming negative amount of an item (expected >=0, got $amount)") - if (item.stackable && !item.canBeDynamic) { + if (item.isConsumable) { remove(item, amount) } else if (item.isUnique) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt index 40608b2db..1601cef29 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt @@ -6,10 +6,10 @@ import net.torvald.terrarum.Terrarum import net.torvald.terrarum.Terrarum.toInt import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.gameitems.FixtureInteractionBlocked import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameitems.mouseInInteractableRangeTools -import net.torvald.terrarum.itemproperties.Material import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.DroppedItem import net.torvald.terrarum.modulebasegame.gameitems.BlockBase.wireNodeMirror @@ -82,7 +82,7 @@ object WireCutterBase { * * Created by minjaesong on 2021-09-18. */ -class WireCutterAll(originalID: ItemID) : GameItem(originalID) { +class WireCutterAll(originalID: ItemID) : GameItem(originalID), FixtureInteractionBlocked { override var dynamicID: ItemID = originalID override var baseMass = 0.1