Add the equipment alteration feature to the AlteredCharacterSheet

This commit is contained in:
Thomas Andres Gomez 2025-05-07 19:38:44 +02:00
parent 8d7b63ab96
commit 2c04559bb7
4 changed files with 56 additions and 12 deletions

View file

@ -2,6 +2,8 @@ package com.pixelized.desktop.lwa.repository.alteration
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.inventory.InventoryRepository
import com.pixelized.desktop.lwa.repository.item.ItemRepository
import com.pixelized.shared.lwa.model.alteration.Alteration
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
@ -19,6 +21,8 @@ import kotlinx.coroutines.flow.stateIn
class AlterationRepository(
private val alterationStore: AlterationStore,
private val inventoryRepository: InventoryRepository,
private val itemRepository: ItemRepository,
campaignRepository: CampaignRepository,
characterRepository: CharacterSheetRepository,
) {
@ -28,17 +32,17 @@ class AlterationRepository(
/**
* This flow transform the campaign instance (player + npc) into a
* Map<CharacterSheetId, List<AlterationId>>.
* Map<CharacterSheetId, List<AlterationId>> from the CharacterSheet Alteration
* It is used by an other flow to build the FieldAlteration cache.
*/
@OptIn(ExperimentalCoroutinesApi::class)
private val campaignCharactersFlow: Flow<Map<String, List<String>>> =
private val campaignCharacterAlterationFlow: Flow<Map<String, List<String>>> =
campaignRepository.campaignFlow()
.flatMapLatest { campaign ->
val flows = campaign.instances.map {
val characters = campaign.instances.map {
characterRepository.characterDetailFlow(characterSheetId = it)
}
combine(flows) { sheets: Array<CharacterSheet?> ->
combine(characters) { sheets: Array<CharacterSheet?> ->
sheets
.asSequence()
.filterNotNull()
@ -46,17 +50,46 @@ class AlterationRepository(
}
}
/**
* This flow transform the campaign instance (player + npc) into a
* Map<CharacterSheetId, List<AlterationId>> from the character inventory items Alteration
* It is used by an other flow to build the FieldAlteration cache.
*/
@OptIn(ExperimentalCoroutinesApi::class)
private val campaignCharacterInventoryAlterationFlow: Flow<Map<String, List<String>>> =
campaignRepository.campaignFlow()
.flatMapLatest { campaign ->
val equippedItems = campaign.instances.map { characterSheetId ->
combine(
inventoryRepository.equippedItemsFlow(characterSheetId = characterSheetId),
itemRepository.itemFlow(),
) { equipments, items ->
characterSheetId to equipments.flatMap { equipment ->
items[equipment.itemId]?.alterations ?: emptyList()
}
}
}
combine(equippedItems) { equipments: Array<Pair<String, List<String>>> ->
equipments
.asSequence()
.associate { it.first to it.second }
}
}
private val activeAlterationMapFlow: StateFlow<Map<String, Map<String, List<FieldAlteration>>>> =
combine(
alterationStore.alterationsFlow,
campaignCharactersFlow,
) { alterations, characters ->
characters.map { (characterSheetId, alterationIds) ->
characterSheetId to transformToAlterationFieldMap(
campaignCharacterAlterationFlow,
campaignCharacterInventoryAlterationFlow,
) { alterations, characters, inventories ->
val characterSheetIds = characters.keys + inventories.keys
characterSheetIds.associateWith {
transformToAlterationFieldMap(
alterations = alterations,
actives = alterationIds,
actives = characters.getOrElse(it) { emptyList() } +
inventories.getOrElse(it) { emptyList() }
)
}.toMap()
}
}.stateIn(
scope = scope,
started = SharingStarted.Eagerly,
@ -96,7 +129,7 @@ class AlterationRepository(
)
}
@kotlin.jvm.Throws
@Throws
suspend fun deleteAlteration(
alterationId: String,
) {

View file

@ -3,6 +3,7 @@ package com.pixelized.desktop.lwa.repository.inventory
import com.pixelized.shared.lwa.model.inventory.Inventory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
class InventoryRepository(
@ -30,6 +31,14 @@ class InventoryRepository(
.map { it[characterSheetId] ?: Inventory.empty(characterSheetId) }
}
fun equippedItemsFlow(
characterSheetId: String,
): Flow<List<Inventory.Item>> {
return inventoryStore.inventories
.map { it[characterSheetId] ?: Inventory.empty(characterSheetId) }
.map { inventory -> inventory.items.filter { item -> item.equipped } }
}
@Throws
suspend fun updateInventory(
inventory: Inventory,

View file

@ -199,7 +199,7 @@ fun InventoryItem(
.size(size = 64)
.build(),
contentScale = ContentScale.Crop,
filterQuality = FilterQuality.Low,
filterQuality = FilterQuality.Medium,
contentDescription = null,
)
if (item.consumable) {

View file

@ -21,6 +21,8 @@ import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.Characterist
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.REFLEX
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.STR
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId.THUMBNAIL
import com.pixelized.shared.lwa.model.inventory.Inventory
import com.pixelized.shared.lwa.model.inventory.Inventory.Item
import com.pixelized.shared.lwa.parser.expression.Expression
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
import com.pixelized.shared.lwa.usecase.ExpressionUseCase