Add auto check feature to skill after a successfull roll.
This commit is contained in:
		
							parent
							
								
									9588a3bfaf
								
							
						
					
					
						commit
						04b203239d
					
				
					 9 changed files with 116 additions and 35 deletions
				
			
		| 
						 | 
				
			
			@ -31,7 +31,7 @@ class PortraitOverlayViewModel(
 | 
			
		|||
        .stateIn(
 | 
			
		||||
            scope = viewModelScope,
 | 
			
		||||
            started = SharingStarted.Eagerly,
 | 
			
		||||
            initialValue = null
 | 
			
		||||
            initialValue = defaultPortrait()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    val options = settingsRepository.settingsFlow()
 | 
			
		||||
| 
						 | 
				
			
			@ -45,10 +45,7 @@ class PortraitOverlayViewModel(
 | 
			
		|||
        .stateIn(
 | 
			
		||||
            scope = viewModelScope,
 | 
			
		||||
            started = SharingStarted.Eagerly,
 | 
			
		||||
            initialValue = PortraitOptionUio(
 | 
			
		||||
                isGameMaster = false,
 | 
			
		||||
                isBrowserAvailable = false,
 | 
			
		||||
            )
 | 
			
		||||
            initialValue = defaultOptions()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    suspend fun dismissPortrait() {
 | 
			
		||||
| 
						 | 
				
			
			@ -68,4 +65,11 @@ class PortraitOverlayViewModel(
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun defaultPortrait() = null
 | 
			
		||||
 | 
			
		||||
    private fun defaultOptions() = PortraitOptionUio(
 | 
			
		||||
        isGameMaster = false,
 | 
			
		||||
        isBrowserAvailable = false,
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -49,13 +49,37 @@ class RollHostState {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
enum class RollResult {
 | 
			
		||||
    Dismissed,
 | 
			
		||||
    CriticalSuccess,
 | 
			
		||||
    SpecialSuccess,
 | 
			
		||||
    Success,
 | 
			
		||||
    Failure,
 | 
			
		||||
    CriticalFailure,
 | 
			
		||||
interface RollResult {
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    data class BoundedRollResult(
 | 
			
		||||
        val result: Result,
 | 
			
		||||
        val difficulty: Difficulty,
 | 
			
		||||
    ) : RollResult {
 | 
			
		||||
        @Stable
 | 
			
		||||
        enum class Result {
 | 
			
		||||
            CriticalSuccess,
 | 
			
		||||
            SpecialSuccess,
 | 
			
		||||
            Success,
 | 
			
		||||
            Failure,
 | 
			
		||||
            CriticalFailure,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Stable
 | 
			
		||||
        enum class Difficulty{
 | 
			
		||||
            Easy,
 | 
			
		||||
            Normal,
 | 
			
		||||
            Hard,
 | 
			
		||||
            Impossible
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Stable
 | 
			
		||||
    data class BoundlessRollResult(
 | 
			
		||||
        val value: Int,
 | 
			
		||||
    ) : RollResult
 | 
			
		||||
 | 
			
		||||
    data object Dismissed: RollResult
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@Stable
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,6 +83,7 @@ data class DifficultyUio(
 | 
			
		|||
    val open: Boolean,
 | 
			
		||||
    val difficulty: Difficulty,
 | 
			
		||||
) {
 | 
			
		||||
    @Stable
 | 
			
		||||
    enum class Difficulty {
 | 
			
		||||
        EASY, NORMAL, HARD, IMPOSSIBLE
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,16 +212,29 @@ class RollViewModel(
 | 
			
		|||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    lastRollResult = rollStep?.let {
 | 
			
		||||
                        when (roll) {
 | 
			
		||||
                            in it.criticalSuccess -> RollResult.CriticalSuccess
 | 
			
		||||
                            in it.specialSuccess -> RollResult.SpecialSuccess
 | 
			
		||||
                            in it.success -> RollResult.Success
 | 
			
		||||
                            in it.failure -> RollResult.Failure
 | 
			
		||||
                            in it.criticalFailure -> RollResult.CriticalFailure
 | 
			
		||||
                            else -> RollResult.Dismissed
 | 
			
		||||
                        }
 | 
			
		||||
                    } ?: RollResult.Dismissed
 | 
			
		||||
                    // build the roll result.
 | 
			
		||||
                    lastRollResult = if (rollStep != null) {
 | 
			
		||||
                        RollResult.BoundedRollResult(
 | 
			
		||||
                            result = when (roll) {
 | 
			
		||||
                                in rollStep.criticalSuccess -> RollResult.BoundedRollResult.Result.CriticalSuccess
 | 
			
		||||
                                in rollStep.specialSuccess -> RollResult.BoundedRollResult.Result.SpecialSuccess
 | 
			
		||||
                                in rollStep.success -> RollResult.BoundedRollResult.Result.Success
 | 
			
		||||
                                in rollStep.criticalFailure -> RollResult.BoundedRollResult.Result.CriticalFailure
 | 
			
		||||
                                else -> RollResult.BoundedRollResult.Result.Failure
 | 
			
		||||
                            },
 | 
			
		||||
                            difficulty = when (_rollDifficulty.value?.difficulty) {
 | 
			
		||||
                                Difficulty.IMPOSSIBLE -> RollResult.BoundedRollResult.Difficulty.Impossible
 | 
			
		||||
                                Difficulty.HARD -> RollResult.BoundedRollResult.Difficulty.Hard
 | 
			
		||||
                                Difficulty.NORMAL -> RollResult.BoundedRollResult.Difficulty.Normal
 | 
			
		||||
                                else -> RollResult.BoundedRollResult.Difficulty.Easy
 | 
			
		||||
                            }
 | 
			
		||||
                        )
 | 
			
		||||
 | 
			
		||||
                    } else {
 | 
			
		||||
                        RollResult.BoundlessRollResult(
 | 
			
		||||
                            value = roll,
 | 
			
		||||
                        )
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _rollResult.value = RollResultUio(
 | 
			
		||||
                        label = resultLabel ?: "",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@ import com.pixelized.desktop.lwa.ui.composable.character.characteristic.Characte
 | 
			
		|||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedDialogViewModel
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeader
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeaderUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheet
 | 
			
		||||
| 
						 | 
				
			
			@ -123,6 +124,10 @@ fun CharacterDetailPanel(
 | 
			
		|||
        onSkill = {
 | 
			
		||||
            scope.launch {
 | 
			
		||||
                val result = roll.showRollOverlay(roll = it.roll)
 | 
			
		||||
                detailViewModel.onSkillUse(
 | 
			
		||||
                    skillId = it.skillId,
 | 
			
		||||
                    result = result,
 | 
			
		||||
                )
 | 
			
		||||
                println("result: $result")
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,9 @@ import com.pixelized.desktop.lwa.repository.network.NetworkRepository
 | 
			
		|||
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.navigation.window.WindowController
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult.BoundedRollResult.Difficulty
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult.BoundedRollResult.Result
 | 
			
		||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
 | 
			
		||||
import kotlinx.coroutines.flow.MutableStateFlow
 | 
			
		||||
import kotlinx.coroutines.flow.SharingStarted
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +18,6 @@ import kotlinx.coroutines.flow.StateFlow
 | 
			
		|||
import kotlinx.coroutines.flow.combine
 | 
			
		||||
import kotlinx.coroutines.flow.map
 | 
			
		||||
import kotlinx.coroutines.flow.stateIn
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
 | 
			
		||||
import org.jetbrains.compose.resources.getString
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +42,7 @@ class CharacterDetailViewModel(
 | 
			
		|||
                    characterSheetRepository.characterDetailFlow(characterSheetId = characterSheetId),
 | 
			
		||||
                    alterationRepository.fieldAlterationsFlow(characterSheetId = characterSheetId),
 | 
			
		||||
                    settingRepository.settingsFlow()
 | 
			
		||||
                ) { characterSheet, alterations, settings, ->
 | 
			
		||||
                ) { characterSheet, alterations, settings ->
 | 
			
		||||
                    characterDetailFactory.convertToCharacterDetailHeaderUio(
 | 
			
		||||
                        characterSheetId = characterSheetId,
 | 
			
		||||
                        characterSheet = characterSheet,
 | 
			
		||||
| 
						 | 
				
			
			@ -100,12 +102,41 @@ class CharacterDetailViewModel(
 | 
			
		|||
        displayedCharacterId.value = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun onSkillUse(
 | 
			
		||||
        skillId: String,
 | 
			
		||||
        result: RollResult,
 | 
			
		||||
    ) {
 | 
			
		||||
        val characterSheetId = displayedCharacterId.value ?: return
 | 
			
		||||
        // check if the RollResult is a BoundedRollResult. can work with other roll result.
 | 
			
		||||
        val roll = result as? RollResult.BoundedRollResult ?: return
 | 
			
		||||
        // check if the roll is a success with some challenge.
 | 
			
		||||
        val difficulty = roll.difficulty != Difficulty.Easy
 | 
			
		||||
        val success = roll.result.let {
 | 
			
		||||
            it == Result.Success || it == Result.SpecialSuccess || it == Result.CriticalSuccess
 | 
			
		||||
        }
 | 
			
		||||
        if (!success || !difficulty) return
 | 
			
		||||
        // Get the skill that have been rolled.
 | 
			
		||||
        val skill = characterSheetRepository
 | 
			
		||||
            .characterDetail(characterSheetId = characterSheetId)
 | 
			
		||||
            ?.skill(id = skillId)
 | 
			
		||||
        // Check the skill if needed.
 | 
			
		||||
        if (skill?.used == false) {
 | 
			
		||||
            network.share(
 | 
			
		||||
                message = CharacterSheetEvent.UpdateSkillUsageEvent(
 | 
			
		||||
                    timestamp = System.currentTimeMillis(),
 | 
			
		||||
                    characterSheetId = characterSheetId,
 | 
			
		||||
                    skillId = skillId,
 | 
			
		||||
                    used = true,
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun onSkillUse(
 | 
			
		||||
        skillId: String,
 | 
			
		||||
        used: Boolean,
 | 
			
		||||
    ) {
 | 
			
		||||
        val characterSheetId = displayedCharacterId.value ?: return
 | 
			
		||||
 | 
			
		||||
        network.share(
 | 
			
		||||
            message = CharacterSheetEvent.UpdateSkillUsageEvent(
 | 
			
		||||
                timestamp = System.currentTimeMillis(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@ package com.pixelized.desktop.lwa.ui.screen.levelup
 | 
			
		|||
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
 | 
			
		||||
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult.BoundedRollResult.Result
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpCharacteristicUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSkillUio
 | 
			
		||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSubCharacteristicUio
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ import com.pixelized.shared.lwa.model.AlteredCharacterSheet
 | 
			
		|||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
 | 
			
		||||
import com.pixelized.shared.lwa.model.alteration.Alteration
 | 
			
		||||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
 | 
			
		||||
import com.pixelized.shared.lwa.model.campaign.Campaign
 | 
			
		||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
 | 
			
		||||
import com.pixelized.shared.lwa.parser.expression.Expression
 | 
			
		||||
import com.pixelized.shared.lwa.usecase.ExpressionUseCase
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +232,7 @@ class LevelUpFactory(
 | 
			
		|||
    fun convertToLevelUpSectionUio(
 | 
			
		||||
        characterSheetId: String,
 | 
			
		||||
        characterSheet: CharacterSheet?,
 | 
			
		||||
        results: Map<String, RollResult>,
 | 
			
		||||
        results: Map<String, RollResult.BoundedRollResult>,
 | 
			
		||||
    ): LevelUpSectionUio? {
 | 
			
		||||
        if (characterSheet == null) return null
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,7 +285,7 @@ class LevelUpFactory(
 | 
			
		|||
        characterSheetId: String,
 | 
			
		||||
        alteredCharacterSheet: AlteredCharacterSheet,
 | 
			
		||||
        skill: CharacterSheet.Skill,
 | 
			
		||||
        results: Map<String, RollResult>,
 | 
			
		||||
        results: Map<String, RollResult.BoundedRollResult>,
 | 
			
		||||
    ): LevelUpSkillUio? {
 | 
			
		||||
        if (!skill.used) return null
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -326,8 +325,8 @@ class LevelUpFactory(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Map<String, RollResult>.isSkillLeveledUp(skillId: String): Boolean {
 | 
			
		||||
    return this.getOrElse(skillId) { RollResult.Dismissed }.let {
 | 
			
		||||
        it == RollResult.CriticalSuccess || it == RollResult.SpecialSuccess || it == RollResult.Success
 | 
			
		||||
    }
 | 
			
		||||
fun Map<String, RollResult.BoundedRollResult>.isSkillLeveledUp(skillId: String): Boolean {
 | 
			
		||||
    return this[skillId]?.let { roll ->
 | 
			
		||||
        roll.result == Result.CriticalSuccess || roll.result == Result.SpecialSuccess || roll.result == Result.Success
 | 
			
		||||
    } ?: false
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ class LevelUpViewModel(
 | 
			
		|||
    private val _errors = MutableSharedFlow<ErrorSnackUio>()
 | 
			
		||||
    val error: SharedFlow<ErrorSnackUio> = _errors
 | 
			
		||||
 | 
			
		||||
    private val results = MutableStateFlow<Map<String, RollResult>>(emptyMap())
 | 
			
		||||
    private val results = MutableStateFlow<Map<String, RollResult.BoundedRollResult>>(emptyMap())
 | 
			
		||||
    private val selectedCharacteristicId = MutableStateFlow<String?>(null)
 | 
			
		||||
 | 
			
		||||
    val header = combine(
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ class LevelUpViewModel(
 | 
			
		|||
 | 
			
		||||
    fun applyRollResult(skillId: String, result: RollResult) {
 | 
			
		||||
        // Discard this case.
 | 
			
		||||
        if (result == RollResult.Dismissed) return
 | 
			
		||||
        if (result !is RollResult.BoundedRollResult) return
 | 
			
		||||
        // If not save the roll result to the map.
 | 
			
		||||
        results.value = results.value.toMutableMap().also {
 | 
			
		||||
            it[skillId] = result
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue