"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
"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",
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;
PlaceBlockActionsModule.class,
RenderModule.class,
KeyboardInputHandlersModule.class,
- MouseInputHandlersModule.class
+ MouseInputHandlersModule.class,
+ UseBlockActionsModule.class
})
public interface GameComponent {
GameProc getGameProc();
jsonMap.forEach { (key, value) ->
craftingRecipes += CraftingRecipe(
- input = value.input.map(::getItem),
+ input = value.input.map(::Regex),
output = CraftingResult(getItem(key), value.count)
)
}
}
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
}
--- /dev/null
+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
+ }
+}
--- /dev/null
+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
--- /dev/null
+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
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
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
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
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
} 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()
}
}
import ru.deadsoftware.cavedroid.game.model.item.Item
data class CraftingRecipe(
- val input: List<Item>,
+ val input: List<Regex>,
val output: CraftingResult
)
@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) {