diff --git a/assets/mods/basegame/items/items.tga b/assets/mods/basegame/items/items.tga index 582af182c..e728696e1 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:394fe44a8dcbc1dbb9b70be78de5747bfa1d01decf3eed6b725ad7ca76f431c0 +oid sha256:78a25d01dfbbfd4cde5a1ac034598191ba8e5b252e2a1969354a9b59906d72f6 size 2408466 diff --git a/src/net/torvald/terrarum/gameactors/AVKey.kt b/src/net/torvald/terrarum/gameactors/AVKey.kt index 9949b8f02..4401dfa82 100644 --- a/src/net/torvald/terrarum/gameactors/AVKey.kt +++ b/src/net/torvald/terrarum/gameactors/AVKey.kt @@ -122,6 +122,8 @@ object AVKey { const val __PLAYER_QUICKSLOTSEL = "__quickslotselection" + const val __PLAYER_WIRECUTTERSEL = "__wirecutterselection" + /** Double * When using tool/arm/etc. how long action button is held, in milliseconds (Int) * Or for NPCs, how long it has been waiting for next move diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 2935413d5..ba77edad8 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -798,6 +798,9 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { } override fun worldSecondaryClickEnd(actor: ActorWithBody, delta: Float) { + val itemOnGrip = (actor as Pocketed).inventory.itemEquipped.get(GameItem.EquipPosition.HAND_GRIP) + ItemCodex[itemOnGrip]?.endSecondaryUse(actor, delta) + worldSecondaryClickLatch = false } diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt index 1601cef29..dc06f40f8 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/WireCutterAll.kt @@ -1,10 +1,11 @@ package net.torvald.terrarum.modulebasegame.gameitems import com.badlogic.gdx.graphics.g2d.TextureRegion -import net.torvald.terrarum.CommonResourcePool -import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.* +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.Terrarum.toInt import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED +import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.FixtureInteractionBlocked import net.torvald.terrarum.gameitems.GameItem @@ -13,8 +14,8 @@ import net.torvald.terrarum.gameitems.mouseInInteractableRangeTools import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.DroppedItem import net.torvald.terrarum.modulebasegame.gameitems.BlockBase.wireNodeMirror -import net.torvald.terrarum.notEmptyOrNull -import net.torvald.terrarum.toInt +import net.torvald.terrarum.modulebasegame.ui.UIWireCutterPie +import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.utils.WiringGraphMap /** @@ -93,6 +94,8 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID), FixtureInteracti override val itemImage: TextureRegion get() = CommonResourcePool.getAsItemSheet("basegame.items").get(1, 3) + @Transient val selectorUI = UIWireCutterPie() + init { stackable = false isUnique = true @@ -100,8 +103,37 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID), FixtureInteracti originalName = "ITEM_WIRE_CUTTER" } - override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = - WireCutterBase.startPrimaryUse(this, actor, delta) { true } + + override fun startPrimaryUse(actor: ActorWithBody, delta: Float): Long { + val itemToRemove = UIWireCutterPie.getWireItemID(actor.actorValue.getAsInt(AVKey.__PLAYER_WIRECUTTERSEL) ?: 0) + + val filter = if (itemToRemove == "__all__") { + { it: ItemID -> true } + } + else { + { it: ItemID -> it == itemToRemove } + } + + return WireCutterBase.startPrimaryUse(this, actor, delta, filter) + } + + override fun startSecondaryUse(actor: ActorWithBody, delta: Float): Long { + (Terrarum.ingame as? TerrarumIngame)?.let { + it.wearableDeviceUI = selectorUI + + if (!selectorUI.isOpening && !selectorUI.isOpened) + selectorUI.setAsOpen() + } + + selectorUI.setPosition(Toolkit.hdrawWidth, App.scr.halfh) + + return -1L // to keep the UI open + } + + override fun endSecondaryUse(actor: ActorWithBody, delta: Float): Boolean { + selectorUI.setAsClose() + return true + } override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) { (Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "wire_render_all" @@ -109,5 +141,6 @@ class WireCutterAll(originalID: ItemID) : GameItem(originalID), FixtureInteracti override fun effectOnUnequip(actor: ActorWithBody) { (Terrarum.ingame!! as TerrarumIngame).selectedWireRenderClass = "" + selectorUI.setAsClose() } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/ItemSlotImageFactory.kt b/src/net/torvald/terrarum/modulebasegame/ui/ItemSlotImageFactory.kt index 050708775..979282c65 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/ItemSlotImageFactory.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/ItemSlotImageFactory.kt @@ -4,8 +4,6 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion -import net.torvald.terrarum.ItemCodex -import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.toInt import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack @@ -32,13 +30,13 @@ object ItemSlotImageFactory { val slotImage = TextureRegionPack(Gdx.files.internal("./assets/graphics/gui/quickbar/item_slots_atlas2.tga"), TILE_WIDTH, TILE_HEIGHT) // must have same w/h as slotLarge - fun produce(isBlack: Boolean, number: Int = 10, item: GameItem?): ItemSlotImage { - return ItemSlotImage(slotImage.get(number, 0 or isBlack.toInt().shl(1)), ItemCodex.getItemImage(item)) + fun produce(isBlack: Boolean, number: Int?, sprite: TextureRegion?): ItemSlotImage { + return ItemSlotImage(slotImage.get(number ?: 10, 0 or isBlack.toInt().shl(1)), sprite) } - fun produceLarge(isBlack: Boolean, number: Int = 10, item: GameItem?, hasGauge: Boolean): ItemSlotImage { + fun produceLarge(isBlack: Boolean, number: Int?, sprite: TextureRegion?, hasGauge: Boolean): ItemSlotImage { val y = if (hasGauge && isBlack) 9 else if (hasGauge && !isBlack) 8 else if (!hasGauge && isBlack) 3 else 1 - return ItemSlotImage(slotImage.get(number, y), ItemCodex.getItemImage(item)) + return ItemSlotImage(slotImage.get(number ?: 10, y), sprite) } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt index bb55ce509..578f43240 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt @@ -109,9 +109,9 @@ class UIQuickslotBar : UICanvas() { val itemHasGauge = ((item?.maxDurability ?: 0) > 0.0) || item?.stackable == true val image = if (i == selection) - ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge) + ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, ItemCodex.getItemImage(item), itemHasGauge) else - ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item) + ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, ItemCodex.getItemImage(item)) val slotX = cellSize / 2 + (cellSize + gutter) * i val slotY = cellSize / 2 diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt index ef88fd123..1ce22c0cd 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt @@ -82,9 +82,9 @@ class UIQuickslotPie : UICanvas() { // draw cells val image = if (i == selection) - ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item, itemHasGauge) + ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, ItemCodex.getItemImage(item), itemHasGauge) else - ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, item) + ItemSlotImageFactory.produce(true, (i + 1) % SLOT_COUNT, ItemCodex.getItemImage(item)) val slotX = slotCentrePoint.x.toInt() val slotY = slotCentrePoint.y.toInt() diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIWireCutterPie.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIWireCutterPie.kt new file mode 100644 index 000000000..a075d0f65 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIWireCutterPie.kt @@ -0,0 +1,140 @@ +package net.torvald.terrarum.modulebasegame.ui + +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.OrthographicCamera +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.g2d.TextureRegion +import com.jme3.math.FastMath +import net.torvald.terrarum.* +import net.torvald.terrarum.gameactors.AVKey +import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.toItemCountText +import net.torvald.terrarum.ui.Toolkit +import net.torvald.terrarum.ui.UICanvas +import org.dyn4j.geometry.Vector2 +import kotlin.math.roundToInt + +/** + * Created by minjaesong on 2024-03-14. + */ +class UIWireCutterPie : UICanvas() { + + init { + handler.allowESCtoClose = false + } + + private val cellSize = ItemSlotImageFactory.slotImage.tileW + + private val slotCount = 6 + + private val slotDistanceFromCentre: Double + get() = cellSize * 2.666 * handler.scale + override var width: Int = cellSize * 7 + override var height: Int = width + + + /** + * In milliseconds + */ + override var openCloseTime: Second = UIQuickslotBar.COMMON_OPEN_CLOSE + + private val smallenSize = 0.92f + + var selection: Int = -1 + + override fun updateImpl(delta: Float) { + if (selection >= 0 && (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying != null) + (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying!!.actorValue[AVKey.__PLAYER_WIRECUTTERSEL] = + selection % slotCount + + + // update controls + if (handler.isOpened || handler.isOpening) { + val cursorPos = Vector2(Terrarum.mouseScreenX.toDouble(), Terrarum.mouseScreenY.toDouble()) + val centre = Vector2(Toolkit.hdrawWidth.toDouble(), App.scr.halfh.toDouble()) + val deg = -(centre - cursorPos).direction.toFloat() + + selection = Math.round(deg * slotCount / FastMath.TWO_PI) + if (selection < 0) selection += slotCount + + // TODO add gamepad support + } + } + + private val drawColor = Color(1f, 1f, 1f, 1f) + + private fun getSprite(index: Int): TextureRegion { + val (x, y) = when (index) { + 0 -> 1 to 3 + 1 -> 11 to 2 + 2 -> 12 to 2 + 3 -> 13 to 2 + 4 -> 14 to 2 + 5 -> 15 to 2 + else -> throw IllegalArgumentException() + } + return CommonResourcePool.getAsItemSheet("basegame.items").get(x, y) + } + + companion object { + fun getWireItemID(index: Int): String { + return when (index) { + 0 -> "__all__" + 1 -> "wire@basegame:8192" + 2 -> "wire@basegame:8193" + 3 -> "wire@basegame:8194" + 4 -> "wire@basegame:8195" + 5 -> "wire@basegame:8196" + else -> throw IllegalArgumentException() + } + } + } + + override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { + // draw radial thingies + for (i in 0 until slotCount) { + val sprite = getSprite(i) + + // set position + val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise + val slotCentrePoint = Vector2(0.0, slotDistanceFromCentre).setDirection(-angle) // NOTE: NOT a center of circle! + + // draw cells + val image = if (i == selection) + ItemSlotImageFactory.produceLarge(false, null, sprite, false) + else + ItemSlotImageFactory.produce(true, null, sprite) + + val slotX = slotCentrePoint.x.toInt() + val slotY = slotCentrePoint.y.toInt() + + drawColor.a = UIQuickslotBar.DISPLAY_OPACITY + batch.color = drawColor + image.draw(batch, slotX, slotY) + } + } + + override fun doOpening(delta: Float) { + doOpeningFade(this, openCloseTime) + handler.scale = smallenSize + (1f.minus(smallenSize) * handler.opacity) + } + + override fun doClosing(delta: Float) { + doClosingFade(this, openCloseTime) + handler.scale = smallenSize + (1f.minus(smallenSize) * handler.opacity) + } + + override fun endOpening(delta: Float) { + endOpeningFade(this) + handler.scale = 1f + } + + override fun endClosing(delta: Float) { + endClosingFade(this) + handler.scale = 1f + } + + override fun dispose() { + } + +} \ 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 226949ed9..fe63eb5a4 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:c9c616d04cf22859aadba68d21988f6de0f7f7b928eaca3f096d56cb001c31a4 -size 1652930 +oid sha256:34a8d23fd7fd6b5111672d16f6573adf92bd617c63f89118c006ac5ccd50b769 +size 1665215