X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGameItemsHolder.kt;h=050ae6fe442acacc4d3c20211d94b7200738182c;hb=9606fce8cc7c9b264abd7cb38583faaebb610540;hp=075af6f4f39cf707ad9bd48f78c6f21f8fc66b06;hpb=fd73b6dd24b9fe55c0bc8f52f8aa1104a5fe3cb0;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt b/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt index 075af6f..050ae6f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt @@ -3,13 +3,18 @@ package ru.deadsoftware.cavedroid.game import com.badlogic.gdx.Gdx import kotlinx.serialization.json.Json import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.model.craft.CraftingRecipe +import ru.deadsoftware.cavedroid.game.model.craft.CraftingResult import ru.deadsoftware.cavedroid.game.model.dto.BlockDto +import ru.deadsoftware.cavedroid.game.model.dto.CraftingDto import ru.deadsoftware.cavedroid.game.model.dto.GameItemsDto import ru.deadsoftware.cavedroid.game.model.dto.ItemDto +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.model.mapper.BlockMapper import ru.deadsoftware.cavedroid.game.model.mapper.ItemMapper import ru.deadsoftware.cavedroid.misc.utils.AssetLoader +import java.util.LinkedList import javax.inject.Inject @GameScope @@ -23,6 +28,7 @@ class GameItemsHolder @Inject constructor( private val blocksMap = LinkedHashMap() private val itemsMap = LinkedHashMap() + private val craftingRecipes = LinkedList() lateinit var fallbackBlock: Block private set @@ -49,13 +55,40 @@ class GameItemsHolder @Inject constructor( } dtoMap.forEach { (key, dto) -> - itemsMap[key] = itemMapper.map(key, dto, blocksMap[key]) + try { + itemsMap[key] = itemMapper.map( + key = key, + dto = dto, + block = blocksMap[key], + slabTopBlock = blocksMap[dto.topSlabBlock] as? Block.Slab, + slabBottomBlock = blocksMap[dto.bottomSlabBlock] as? Block.Slab + ) + } catch (e: Exception) { + Gdx.app.error(TAG, "Failed to map item $key. Reason: ${e.message}") + e.printStackTrace() + } } fallbackItem = itemsMap[FALLBACK_ITEM_KEY] ?: throw IllegalArgumentException("Fallback item key '$FALLBACK_ITEM_KEY' not found") } + private fun loadCraftingRecipes() { + val jsonString = assetLoader.getAssetHandle("json/crafting.json").readString() + val jsonMap = JsonFormat.decodeFromString>(jsonString) + + if (jsonMap.isNotEmpty() && itemsMap.isEmpty()) { + throw IllegalStateException("items should be loaded before crafting") + } + + jsonMap.forEach { (key, value) -> + craftingRecipes += CraftingRecipe( + input = value.input.map(::Regex), + output = CraftingResult(getItem(key), value.count) + ) + } + } + fun initialize() { if (_initialized) { Gdx.app.debug(TAG, "Attempted to init when already initialized") @@ -69,6 +102,8 @@ class GameItemsHolder @Inject constructor( loadItems(gameItemsDto.items) _initialized = true + + loadCraftingRecipes() } private fun Map.getOrFallback(key: String, fallback: T, lazyErrorMessage: () -> String): T { @@ -95,6 +130,26 @@ class GameItemsHolder @Inject constructor( } } + fun craftItem(input: List): InventoryItem? { + val startIndex = input.indexOfFirst { !it.isNone() }.takeIf { it >= 0 } ?: return null + + return try { + 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 + } + } + fun getAllItems(): Collection { return itemsMap.values } @@ -107,7 +162,7 @@ class GameItemsHolder @Inject constructor( } } - fun getCreativeScrollAmount(): Int = itemsMap.size / 8 + fun getMaxCreativeScrollAmount(): Int = itemsMap.size / 8 fun getBlocksByType(type: Class): List { return blocksMap.values.filterIsInstance(type)