DEADSOFTWARE

Drop items on Q and add empty hearts to health bar
authorfredboy <fredboy@protonmail.com>
Tue, 7 May 2024 15:49:41 +0000 (22:49 +0700)
committerfredboy <fredboy@protonmail.com>
Tue, 7 May 2024 15:49:41 +0000 (22:49 +0700)
12 files changed:
android/assets/health.png
android/assets/json/texture_regions.json
core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt
core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt
core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenCraftingKeyboardInputHandler.kt [deleted file]
core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt
core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt
core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java
core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt
core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt
core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt

index 93314e6e623a263d9543f036bf1fb3036ce37e38..99011d5ef20d65a23d8ca601c99548a3b47bd475 100644 (file)
Binary files a/android/assets/health.png and b/android/assets/health.png differ
index 800098081fedec8efe5483a3ba2af7803c742a71..6ccbffa8650704579c3e52349d8e1b0786068cd5 100644 (file)
     "heart_half": {
       "x": 9,
       "w": 9
+    },
+    "heart_empty": {
+      "x": 18,
+      "w": 9
     }
   }
 }
\ No newline at end of file
index 80533d9a8a356530ed89f3139489ec65300dc516..0a33d9337db9b7802dea88b9f76304f409408187 100644 (file)
@@ -111,7 +111,7 @@ object KeyboardInputHandlersModule {
     @Binds
     @IntoSet
     @GameScope
-    fun bindOpenCraftingKeyboardInputHandler(handler: OpenCraftingKeyboardInputHandler): IGameInputHandler<KeyboardInputAction> {
+    fun bindOpenCraftingKeyboardInputHandler(handler: DropItemKeyboardInputHandler): IGameInputHandler<KeyboardInputAction> {
         return handler
     }
 
index cfac1328881d7de1171a66bbeb09bd521924b255..89ff50658340fd38c7366b6bec6cadbfc36d98b0 100644 (file)
@@ -9,6 +9,8 @@ sealed interface KeyboardInputActionKey {
 
     data object Crouch : KeyboardInputActionKey
 
+    data object DropItem : KeyboardInputActionKey
+
     data object SwitchControlsMode : KeyboardInputActionKey
 
     data object OpenInventory : KeyboardInputActionKey
@@ -19,5 +21,4 @@ sealed interface KeyboardInputActionKey {
     data object SpawnPig : KeyboardInputActionKey
     data object SwitchGameMode : KeyboardInputActionKey
     data object ShowMap : KeyboardInputActionKey
-    data object OpenCraft : KeyboardInputActionKey
 }
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt
new file mode 100644 (file)
index 0000000..7e6454c
--- /dev/null
@@ -0,0 +1,56 @@
+package ru.deadsoftware.cavedroid.game.input.handler.keyboard
+
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.GameUiWindow
+import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
+import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction
+import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey
+import ru.deadsoftware.cavedroid.game.mobs.MobsController
+import ru.deadsoftware.cavedroid.game.model.item.Item
+import ru.deadsoftware.cavedroid.game.objects.Drop
+import ru.deadsoftware.cavedroid.game.objects.DropController
+import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import javax.inject.Inject
+
+@GameScope
+class DropItemKeyboardInputHandler @Inject constructor(
+    private val gameWindowsManager: GameWindowsManager,
+    private val mobsController: MobsController,
+    private val dropController: DropController,
+) : IGameInputHandler<KeyboardInputAction> {
+
+    override fun checkConditions(action: KeyboardInputAction): Boolean {
+        return action.actionKey is KeyboardInputActionKey.DropItem &&
+                action.isKeyDown && gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE &&
+                !mobsController.player.inventory.activeItem.item.isNone()
+    }
+
+    private fun createDrop(item: Item, playerX: Float, playerY: Float) {
+        dropController.addDrop(playerX + ((DROP_DISTANCE - Drop.DROP_SIZE / 2) * mobsController.player.direction.basis), playerY, item)
+    }
+
+    override fun handle(action: KeyboardInputAction) {
+        val player = mobsController.player
+        val currentItem = player.inventory.activeItem
+
+        if (!currentItem.item.isTool()) {
+            createDrop(currentItem.item, player.x, player.y)
+        } else {
+            for (i in 1..currentItem.amount) {
+                createDrop(currentItem.item, player.x, player.y)
+            }
+        }
+
+        player.inventory.decreaseCurrentItemAmount(
+            if (currentItem.item.isTool()) {
+                currentItem.amount
+            } else {
+                1
+            }
+        )
+    }
+
+    companion object {
+        private const val DROP_DISTANCE = 20f
+    }
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenCraftingKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenCraftingKeyboardInputHandler.kt
deleted file mode 100644 (file)
index d2e333c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package ru.deadsoftware.cavedroid.game.input.handler.keyboard
-
-import ru.deadsoftware.cavedroid.game.GameScope
-import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
-import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction
-import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey
-import ru.deadsoftware.cavedroid.game.mobs.MobsController
-import ru.deadsoftware.cavedroid.game.objects.DropController
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
-import javax.inject.Inject
-
-@GameScope
-class OpenCraftingKeyboardInputHandler @Inject constructor(
-    private val gameWindowsManager: GameWindowsManager,
-) : IGameInputHandler<KeyboardInputAction> {
-
-    override fun checkConditions(action: KeyboardInputAction): Boolean {
-        return action.actionKey is KeyboardInputActionKey.OpenCraft &&
-                action.isKeyDown && gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE
-    }
-
-    override fun handle(action: KeyboardInputAction) {
-        gameWindowsManager.openCrafting()
-    }
-}
\ No newline at end of file
index f2ed1260b476365b917e6c527efa066e4fe0cb45..61e97932708cdcb07f122e8283a250fcfe0a89f1 100644 (file)
@@ -25,7 +25,7 @@ class KeyboardInputActionMapper @Inject constructor() {
             Input.Keys.GRAVE -> KeyboardInputActionKey.SwitchGameMode
             Input.Keys.M -> KeyboardInputActionKey.ShowMap
 
-            Input.Keys.T -> KeyboardInputActionKey.OpenCraft
+            Input.Keys.Q -> KeyboardInputActionKey.DropItem
 
             else -> null
         }
index 4469038ba6f7a1632c54297202650085b02e00e0..b82aa44bcb775991b4ff12e175a511925620c28b 100644 (file)
@@ -12,7 +12,11 @@ class Inventory(
     gameItemsHolder: GameItemsHolder
 ) : Serializable {
 
+    @Transient
+    private lateinit var fallbackItem: InventoryItem
+
     init {
+        fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
         if (size < 0 || hotbarSize < 0 || hotbarSize > size) {
             throw IllegalArgumentException("Invalid inventory sizes: hotbarSize=$hotbarSize; size=$size")
         }
@@ -34,6 +38,7 @@ class Inventory(
     val activeItem get() = items[activeSlot]
 
     fun initItems(gameItemsHolder: GameItemsHolder) {
+        fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
         items.forEach { item ->
             item.init(gameItemsHolder)
         }
@@ -82,4 +87,12 @@ class Inventory(
 
         _items[0] = item.toInventoryItem(item.params.maxStack)
     }
+
+    @JvmOverloads
+    fun decreaseCurrentItemAmount(count: Int = 1) {
+        activeItem.subtract(count)
+        if (activeItem.amount <= 0) {
+            _items[activeSlot] = fallbackItem
+        }
+    }
 }
\ No newline at end of file
index bcca82606eb711dea6add8f9003243a7e0b94d52..dcc77ef81202b4bb6e96018b3651b348b3aeb1f1 100644 (file)
@@ -21,8 +21,8 @@ public class Player extends Mob {
 
     private static final float SPEED = 69.072f;
     private static final float JUMP_VELOCITY = -133.332f;
-    private static final int MAX_HEALTH = 20;
 
+    public static final int MAX_HEALTH = 20;
     public static final int INVENTORY_SIZE = 36;
     public static final int HOTBAR_SIZE = 9;
 
index 5121ab3f9f778575af8131c553cbe07f035bdefc..765224334d1d29b8441e0f59d1a9b0bd07df503e 100644 (file)
@@ -12,9 +12,18 @@ import java.io.Serializable
 
 class InventoryItem @JvmOverloads constructor(
     val itemKey: String,
-    var amount: Int = 1,
+    _amount: Int = 1,
 ) : Serializable {
 
+    var amount = _amount
+        set(value) {
+            field = if (value < 0) {
+                0
+            } else {
+                value
+            }
+        }
+
     @Transient
     lateinit var item: Item
         private set
@@ -33,11 +42,19 @@ class InventoryItem @JvmOverloads constructor(
 
     @JvmOverloads
     fun add(count: Int = 1) {
+        if (count > 0 && Int.MAX_VALUE - count < amount) {
+            throw IllegalArgumentException("$amount + $count exceeds Int.MAX_VALUE")
+        }
+
         amount += count
     }
 
     @JvmOverloads
     fun subtract(count: Int = 1) {
+        if (count < 0) {
+            throw IllegalArgumentException("Can't subtract negative amount")
+        }
+
         add(-count)
     }
 
index d7c6a45d6773eb5f3af9a6db481cf05d49400ef3..5b10fed5e75476531df51651b8c99022d82944d1 100644 (file)
@@ -47,7 +47,7 @@ class Drop(
     }
 
     companion object {
-        private const val MAGNET_DISTANCE = 4f
+        private const val MAGNET_DISTANCE = 8f
 
         const val MAGNET_VELOCITY = 256f
         const val DROP_SIZE = 8f
index c5e02d4db43c14ada35aeb9c6680a29cffac4029..1053a9f3d2b887840f9a35ef018d37a93d5611aa 100644 (file)
@@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer
 import com.badlogic.gdx.math.Rectangle
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
+import ru.deadsoftware.cavedroid.game.mobs.player.Player
 import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import ru.deadsoftware.cavedroid.misc.Assets
@@ -23,6 +24,7 @@ class HudRenderer @Inject constructor(
     private val hotbarTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_KEY])
     private val hotbarSelectorTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_SELECTOR_KEY])
     private val wholeHeartTexture get() = requireNotNull(Assets.textureRegions[WHOLE_HEART_KEY])
+    private val emptyHeartTexture get() = requireNotNull(Assets.textureRegions[EMPTY_HEART_KEY])
     private val halfHeartTexture get() = requireNotNull(Assets.textureRegions[HALF_HEART_KEY])
 
     private fun drawCursor(spriteBatch: SpriteBatch, viewport: Rectangle) {
@@ -45,15 +47,25 @@ class HudRenderer @Inject constructor(
         }
 
         val wholeHeart = wholeHeartTexture
+        val halfHeart = halfHeartTexture
+        val emptyHeart = emptyHeartTexture
+
+        val totalHearts = Player.MAX_HEALTH / 2
         val wholeHearts = player.health / 2
 
-        for (i in 0..<wholeHearts) {
-            spriteBatch.draw(wholeHeart, x + i * wholeHeart.regionWidth, y)
+        for (i in 0..< totalHearts) {
+            if (i < wholeHearts) {
+                spriteBatch.draw(wholeHeart, x + i * wholeHeart.regionWidth, y)
+            } else if (i == wholeHearts && player.health % 2 == 1) {
+                spriteBatch.draw(halfHeart, x + i * wholeHeart.regionWidth, y)
+            } else {
+                spriteBatch.draw(emptyHeart, x + i * wholeHeart.regionWidth, y)
+            }
         }
 
-        if (player.health % 2 == 1) {
-            spriteBatch.draw(halfHeartTexture, x + wholeHearts * wholeHeart.regionWidth, y)
-        }
+
+
+
     }
 
     private fun drawHotbarItems(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer,  hotbarX: Float) {
@@ -105,6 +117,7 @@ class HudRenderer @Inject constructor(
         private const val HOTBAR_SELECTOR_KEY = "hotbar_selector"
         private const val WHOLE_HEART_KEY = "heart_whole"
         private const val HALF_HEART_KEY = "heart_half"
+        private const val EMPTY_HEART_KEY = "heart_empty"
 
         private data object HotbarConfig {
             const val horizontalMargin = 3f