manueldidonna / pokemon-save-editor-android

A work-in-progress pokémon save editor for Android
GNU General Public License v3.0
0 stars 0 forks source link

Support Inventory #9

Closed manueldidonna closed 4 years ago

manueldidonna commented 4 years ago
  1. Each game use different ids for the inventory items
  2. Each id can have a different string representation based on the game version
interface InventoryResources {
    fun getItems(version: Version): List<String>
    fun getTypeName(type: Inventory.Type) : String
}
interface Inventory {
    /**
     * Every game supports a limited set of [Type]s
     * @see [SaveData.supportedInventoryTypes]
     */
    val type: Type

    enum class Type {
        General,
        Computer,
        Balls,
        Keys
    }

    /**
     * List of ids that an Inventory instance recognizes
     */
    val supportedItemIds: List<Int>

    /**
     * It is the value to which all [Item.quantity] are coerced
     */
    val maxAllowedQuantity: Int

    val maxAllowedItemCounts: Int

    val itemCounts: Int

    fun getItem(index: Int): Item

    /**
     * Should throw an [IllegalStateException] if [item] id isn't included in [supportedItemIds]
     */
    fun setItem(item: Item)

    data class Item(
        val index: Int,
        val id: Int,
        val quantity: Int
    )
}

interface SaveData {

    val supportedInventoryTypes: List<Inventory.Type>

    /**
     * Return null if [type] is not supported
    */
    fun getInventory(type: Inventory.Type) : Inventory?
}
manueldidonna commented 4 years ago

Maximize current items quantity

fun Inventory.applyToCurrentItems(quantity: Int = maxAllowedQuantity) {
    val reusableItem = object : Inventory.Item {
        override var index = 0
        override var id = 0
        override val quantity = quantity
    }
    val mutateItem = fun (index: Int, id: Int, quantity: Int) -> Inventory.Item {  
        reusableItem.index = index
        reusableItem.id = id
        return reusableItem
    }
    for (index in 0 until itemCounts) {
        setItem(selectItem(index, mapTo = mutateItem))
    }
}

Give max quantity of all items

fun Inventory.giveAllItems() {
    val itemsCount = supportedItemIds.size.coerceAtMost(capacity)
    val reusableItem = object : Inventory.Item {
        override var index = 0
        override var id = 0
        override val quantity = maxAllowedQuantity
    }
    for (i in 0 until maxSupportedCount) {
        reusableItem.index = i
        reusableItem.id = supportedItemIds[i]
        setItem(reusableItem)
    }
}

Sort items by id

fun Inventory.sortItemsById() {
    val items = MutableList(size) { getItem(it) }
    items.sortBy { it.id }
    items.forEachIndexed { index, item ->
        setItem(item, index)
    }
}
manueldidonna commented 4 years ago
@Composable
fun LoadItems(saveData: SaveData, resources: PokemonTextResources.Items) {
    val inventories: List<Inventory> = remember { 
        saveData
            .supportedInventoryTypes
            .map { type -> saveData.getInventory(type) }
            .filterNotNull()
    }
    val itemNames = remember { resources.getItems(saveData.version) }
    InventoryTabs(inventories) { inventory -> 
        ItemsList(inventory.getAllItems(), itemNames)
    }
}

@Composable
fun ItemsList(items: List<Inventory.Item>, names: List<String>) {
    AdapterList(items) { item ->
        ItemRow(names[item.id], item.quantity)
    }
}