diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt b/core/src/ru/deadsoftware/cavedroid/game/GameItemsHolder.kt
index 075af6f4f39cf707ad9bd48f78c6f21f8fc66b06..050ae6fe442acacc4d3c20211d94b7200738182c 100644 (file)
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
private val blocksMap = LinkedHashMap<String, Block>()
private val itemsMap = LinkedHashMap<String, Item>()
+ private val craftingRecipes = LinkedList<CraftingRecipe>()
lateinit var fallbackBlock: Block
private set
}
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<Map<String, CraftingDto>>(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")
loadItems(gameItemsDto.items)
_initialized = true
+
+ loadCraftingRecipes()
}
private fun <T> Map<String, T>.getOrFallback(key: String, fallback: T, lazyErrorMessage: () -> String): T {
}
}
+ fun craftItem(input: List<Item>): 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<Item> {
return itemsMap.values
}
}
}
- fun getCreativeScrollAmount(): Int = itemsMap.size / 8
+ fun getMaxCreativeScrollAmount(): Int = itemsMap.size / 8
fun <T : Block> getBlocksByType(type: Class<T>): List<T> {
return blocksMap.values.filterIsInstance(type)