DEADSOFTWARE

Better crafting
authorfredboy <fredboy@protonmail.com>
Tue, 7 May 2024 15:13:39 +0000 (22:13 +0700)
committerfredboy <fredboy@protonmail.com>
Tue, 7 May 2024 15:13:39 +0000 (22:13 +0700)
android/assets/json/crafting.json
android/assets/json/game_items.json
core/src/ru/deadsoftware/cavedroid/game/GameComponent.java
core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt
core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt
core/src/ru/deadsoftware/cavedroid/game/model/craft/CraftingRecipe.kt
core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt

index 94cbe4705b786d40dc0d3daf2c1ca1497cf5ee6c..ddb9a676153b8b5be13fdc17dc5ce5ff5d07d946 100644 (file)
@@ -3,24 +3,28 @@
     "input": ["log_oak", "none", "none", "none", "none", "none", "none", "none", "none"],
     "count": 4
   },
+  "planks_spruce": {
+    "input": ["log_spruce", "none", "none", "none", "none", "none", "none", "none", "none"],
+    "count": 4
+  },
   "stick": {
-    "input": ["planks_oak", "none", "none", "planks_oak", "none", "none", "none", "none", "none"],
+    "input": ["planks.*", "none", "none", "planks.*", "none", "none", "none", "none", "none"],
     "count": 4
   },
   "wood_pickaxe": {
-    "input": ["planks_oak", "planks_oak", "planks_oak", "none", "stick", "none", "none", "stick", "none"],
+    "input": ["planks.*", "planks.*", "planks.*", "none", "stick", "none", "none", "stick", "none"],
     "count": 59
   },
   "wood_axe": {
-    "input": ["planks_oak", "planks_oak", "none", "planks_oak", "stick", "none", "none", "stick", "none"],
+    "input": ["planks.*", "planks.*", "none", "planks.*", "stick", "none", "none", "stick", "none"],
     "count": 60
   },
   "wood_sword": {
-    "input": ["none", "planks_oak", "none", "none", "planks_oak", "none", "none", "stick", "none"],
+    "input": ["planks.*", "none", "none", "planks.*", "none", "none", "stick", "none", "none"],
     "count": 60
   },
   "wood_shovel": {
-    "input": ["none", "planks_oak", "none", "none", "stick", "none", "none", "stick", "none"],
+    "input": ["planks.*", "none", "none", "stick", "none", "none", "stick", "none", "none"],
     "count": 59
   },
   "stone_pickaxe": {
     "count": 131
   },
   "stone_sword": {
-    "input": ["none", "cobblestone", "none", "none", "cobblestone", "none", "none", "stick", "none"],
+    "input": ["cobblestone", "none", "none", "cobblestone", "none", "none", "stick", "none", "none"],
     "count": 132
   },
   "stone_shovel": {
-    "input": ["none", "cobblestone", "none", "none", "stick", "none", "none", "stick", "none"],
+    "input": ["cobblestone", "none", "none", "stick", "none", "none", "stick", "none", "none"],
     "count": 131
   },
   "snow_block": {
     "input": ["snowball", "snowball", "none", "snowball", "snowball", "none", "none", "none", "none"],
     "count": 1
+  },
+  "crafting_table": {
+    "input": ["planks.*", "planks.*", "none", "planks.*", "planks.*", "none", "none", "none", "none"]
   }
 }
\ No newline at end of file
index f6bfb63201f9b2f517313855cc4ea063a0e6729e..d8523b9672dc7cf536ff1d9f6a8f0079175528e7 100644 (file)
       "tool_level": 0,
       "tool_type": "axe"
     },
+    "crafting_table": {
+      "hp": 180,
+      "drop": "crafting_table",
+      "texture": "crafting_table",
+      "tool_level": 0,
+      "tool_type": "axe"
+    },
     "sapling_oak": {
       "collision": false,
       "transparent": true,
       "type": "block",
       "texture": "planks_spruce"
     },
+    "crafting_table": {
+      "name": "Crafting Table",
+      "type": "block",
+      "texture": "crafting_table"
+    },
     "sapling_spruce": {
       "name": "Spruce Sapling",
       "type": "block",
index 2dafcd5e0346fb00a7d2fec91d132f7bce74a664..624e544ec17034d6bba141a35b28e250ea4cbab3 100644 (file)
@@ -4,6 +4,7 @@ import dagger.Component;
 import ru.deadsoftware.cavedroid.MainComponent;
 import ru.deadsoftware.cavedroid.game.actions.PlaceBlockActionsModule;
 import ru.deadsoftware.cavedroid.game.actions.UpdateBlockActionsModule;
+import ru.deadsoftware.cavedroid.game.actions.UseBlockActionsModule;
 import ru.deadsoftware.cavedroid.game.actions.UseItemActionsModule;
 import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandlersModule;
 import ru.deadsoftware.cavedroid.game.input.MouseInputHandlersModule;
@@ -17,7 +18,8 @@ import ru.deadsoftware.cavedroid.game.render.RenderModule;
                 PlaceBlockActionsModule.class,
                 RenderModule.class,
                 KeyboardInputHandlersModule.class,
-                MouseInputHandlersModule.class
+                MouseInputHandlersModule.class,
+                UseBlockActionsModule.class
         })
 public interface GameComponent {
     GameProc getGameProc();
index 832845eb0c11f60f2ae6168661d1a99961b28c37..050ae6fe442acacc4d3c20211d94b7200738182c 100644 (file)
@@ -83,7 +83,7 @@ class GameItemsHolder @Inject constructor(
 
         jsonMap.forEach { (key, value) ->
             craftingRecipes += CraftingRecipe(
-                input = value.input.map(::getItem),
+                input = value.input.map(::Regex),
                 output = CraftingResult(getItem(key), value.count)
             )
         }
@@ -131,8 +131,20 @@ class GameItemsHolder @Inject constructor(
     }
 
     fun craftItem(input: List<Item>): InventoryItem? {
+        val startIndex = input.indexOfFirst { !it.isNone() }.takeIf { it >= 0 } ?: return null
+
         return  try {
-            craftingRecipes.first { rec -> rec.input == input}.output.toInventoryItem()
+            craftingRecipes.first { rec ->
+                for (i in rec.input.indices) {
+                    if (startIndex + i >= input.size) {
+                        return@first rec.input.subList(i, rec.input.size).all { it.matches("none") }
+                    }
+                    if (!input[startIndex + i].params.key.matches(rec.input[i])) {
+                        return@first false
+                    }
+                }
+                return@first true
+            }.output.toInventoryItem()
         } catch (e: NoSuchElementException) {
             null
         }
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt
new file mode 100644 (file)
index 0000000..76127fa
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.deadsoftware.cavedroid.game.actions
+
+import dagger.Binds
+import dagger.Module
+import dagger.multibindings.IntoMap
+import dagger.multibindings.StringKey
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction
+import ru.deadsoftware.cavedroid.game.actions.useblock.UseCraftingTableAction
+
+@Module
+class UseBlockActionsModule {
+
+    @Binds
+    @IntoMap
+    @StringKey(UseCraftingTableAction.KEY)
+    @GameScope
+    fun bindUseCraftingTableAction(action: UseCraftingTableAction): IUseBlockAction {
+        return action
+    }
+}
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt
new file mode 100644 (file)
index 0000000..ddc70c5
--- /dev/null
@@ -0,0 +1,9 @@
+package ru.deadsoftware.cavedroid.game.actions.useblock
+
+import ru.deadsoftware.cavedroid.game.model.block.Block
+
+interface IUseBlockAction {
+
+    fun perform(block: Block, x: Int, y: Int)
+
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt
new file mode 100644 (file)
index 0000000..7c41364
--- /dev/null
@@ -0,0 +1,20 @@
+package ru.deadsoftware.cavedroid.game.actions.useblock
+
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.model.block.Block
+import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import javax.inject.Inject
+
+@GameScope
+class UseCraftingTableAction @Inject constructor(
+    private val gameWindowsManager: GameWindowsManager
+) : IUseBlockAction {
+
+    override fun perform(block: Block, x: Int, y: Int) {
+        gameWindowsManager.openCrafting()
+    }
+
+    companion object {
+        const val KEY = "crafting_table"
+    }
+}
\ No newline at end of file
index c3b52450b45f8c3ac558ca5796be0901ef08153c..da59bc65cc612e301edf8a355920c5ca285dff3c 100644 (file)
@@ -7,6 +7,7 @@ import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.actions.placeToBackgroundAction
 import ru.deadsoftware.cavedroid.game.actions.placeToForegroundAction
 import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction
+import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction
 import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
@@ -15,6 +16,7 @@ import ru.deadsoftware.cavedroid.game.input.isInsideHotbar
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.model.item.Item
 import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.world.GameWorld
 import javax.inject.Inject
 
 @GameScope
@@ -22,7 +24,9 @@ class UseItemMouseInputHandler @Inject constructor(
     private val mobsController: MobsController,
     private val useItemActionMap: Map<String, @JvmSuppressWildcards IUseItemAction>,
     private val placeBlockActionMap: Map<String, @JvmSuppressWildcards IPlaceBlockAction>,
+    private val useBlockActionMap: Map<String, @JvmSuppressWildcards IUseBlockAction>,
     private val gameWindowsManager: GameWindowsManager,
+    private val gameWorld: GameWorld,
 ) : IGameInputHandler<MouseInputAction> {
 
     private var buttonHoldTask: Timer.Task? = null
@@ -67,6 +71,20 @@ class UseItemMouseInputHandler @Inject constructor(
         Timer.schedule(buttonHoldTask, TOUCH_HOLD_TIME_SEC)
     }
 
+    private fun tryUseBlock() {
+        val block = gameWorld.getForeMap(mobsController.player.cursorX, mobsController.player.cursorY)
+            .takeIf { !it.isNone() }
+            ?: gameWorld.getBackMap(mobsController.player.cursorX, mobsController.player.cursorY)
+                .takeIf { !it.isNone() }
+            ?: return
+
+        useBlockActionMap[block.params.key]?.perform(
+            block = block,
+            x = mobsController.player.cursorX,
+            y = mobsController.player.cursorY
+        )
+    }
+
     private fun handleUp(action: MouseInputAction) {
         val player = mobsController.player
         val item = player.inventory.activeItem.item
@@ -84,6 +102,8 @@ class UseItemMouseInputHandler @Inject constructor(
         } else if (item is Item.Usable) {
             useItemActionMap[item.useActionKey]?.perform(item, player.cursorX, player.cursorY)
                 ?: Gdx.app.error(TAG, "use item action ${item.useActionKey} not found");
+        } else {
+            tryUseBlock()
         }
     }
 
index eebe13f0992644fcf0a6c65335ad06845a993808..c8b2a869761f62a0fe07de152c1ce543633868dd 100644 (file)
@@ -4,7 +4,7 @@ import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
 import ru.deadsoftware.cavedroid.game.model.item.Item
 
 data class CraftingRecipe(
-    val input: List<Item>,
+    val input: List<Regex>,
     val output: CraftingResult
 )
 
index aa646cbe8fb88437cae365ea8c4c724fd335319d..5121ab3f9f778575af8131c553cbe07f035bdefc 100644 (file)
@@ -43,7 +43,7 @@ class InventoryItem @JvmOverloads constructor(
 
     @JvmOverloads
     fun canBeAdded(count: Int = 1): Boolean {
-        return !item.isTool() && amount + count <= item.params.maxStack
+        return amount + count <= item.params.maxStack
     }
 
     private fun drawAmountText(spriteBatch: SpriteBatch, text: String,  x: Float, y: Float) {