Add death saving throw management.
This commit is contained in:
parent
d38caea015
commit
96149b951a
15 changed files with 367 additions and 27 deletions
|
|
@ -173,6 +173,15 @@ class DiceThrowUseCase @Inject constructor(
|
|||
relatedStat = Property.CHARISMA
|
||||
)
|
||||
|
||||
is DiceThrow.DeathSavingThrow -> savingThrow(
|
||||
character = sheet,
|
||||
alterations = alterations,
|
||||
abilityLabel = { getString(R.string.character_sheet_stat_death) },
|
||||
relatedLabel = { getString(R.string.character_sheet_stat_death) },
|
||||
ability = Property.DEATH_SAVING_THROW,
|
||||
relatedStat = null,
|
||||
)
|
||||
|
||||
is DiceThrow.Acrobatics -> abilityThrow(
|
||||
character = sheet,
|
||||
alterations = alterations,
|
||||
|
|
@ -494,7 +503,7 @@ class DiceThrowUseCase @Inject constructor(
|
|||
abilityLabel: Context.() -> String,
|
||||
relatedLabel: Context.() -> String?,
|
||||
ability: Property,
|
||||
relatedStat: Property,
|
||||
relatedStat: Property?,
|
||||
): DiceThrowResult = rollAbility(
|
||||
character = character,
|
||||
alterations = alterations,
|
||||
|
|
@ -514,7 +523,7 @@ class DiceThrowUseCase @Inject constructor(
|
|||
relatedTitle: Context.(label: String) -> String?,
|
||||
relatedLabel: Context.() -> String?,
|
||||
ability: Property,
|
||||
relatedStat: Property,
|
||||
relatedStat: Property?,
|
||||
): DiceThrowResult {
|
||||
// retrieve some wording.
|
||||
val abilityLabelString = abilityLabel(application)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ data class CharacterSheetFire(
|
|||
@set:PropertyName(HIT_POINT)
|
||||
var hitPoint: HitPoint? = null,
|
||||
|
||||
@get:PropertyName(DEATH)
|
||||
@set:PropertyName(DEATH)
|
||||
var death: Death? = null,
|
||||
|
||||
@get:PropertyName(SKILLS)
|
||||
@set:PropertyName(SKILLS)
|
||||
var skills: Map<String, Int> = emptyMap(),
|
||||
|
|
@ -31,8 +35,21 @@ data class CharacterSheetFire(
|
|||
var value: Int? = null,
|
||||
)
|
||||
|
||||
@Keep
|
||||
@IgnoreExtraProperties
|
||||
data class Death(
|
||||
@get:PropertyName("success")
|
||||
@set:PropertyName("success")
|
||||
var success: Int? = null,
|
||||
|
||||
@get:PropertyName("failure")
|
||||
@set:PropertyName("failure")
|
||||
var failure: Int? = null,
|
||||
)
|
||||
|
||||
companion object {
|
||||
const val HIT_POINT = "hit_point"
|
||||
const val DEATH = "death"
|
||||
const val SKILLS = "skills"
|
||||
const val SPELLS = "spells"
|
||||
const val SPELL_PREFIX = "lvl_"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ sealed class DiceThrow(val character: String) {
|
|||
class IntelligenceSavingThrow(character: String) : DiceThrow(character)
|
||||
class WisdomSavingThrow(character: String) : DiceThrow(character)
|
||||
class CharismaSavingThrow(character: String) : DiceThrow(character)
|
||||
class DeathSavingThrow(character: String): DiceThrow(character)
|
||||
class Acrobatics(character: String) : DiceThrow(character)
|
||||
class AnimalHandling(character: String) : DiceThrow(character)
|
||||
class Arcana(character: String) : DiceThrow(character)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ enum class Property(val key: String) {
|
|||
INTELLIGENCE_SAVING_THROW("Jet de sauvegarde: Intelligence"),
|
||||
WISDOM_SAVING_THROW("Jet de sauvegarde: Sagesse"),
|
||||
CHARISMA_SAVING_THROW("Jet de sauvegarde: Charisme"),
|
||||
DEATH_SAVING_THROW("Jet de sauvegarde: Mort"),
|
||||
ACROBATICS("Acrobaties"),
|
||||
ANIMAL_HANDLING("Dressage"),
|
||||
ARCANA("Arcanes"),
|
||||
|
|
|
|||
|
|
@ -75,6 +75,18 @@ class FirebaseRepository @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun setCharacterDeathCounter(character: String, success: Int, failure: Int) {
|
||||
val reference = database.getReference(
|
||||
"$PATH_CHARACTERS/$character/${CharacterSheetFire.DEATH}"
|
||||
)
|
||||
reference.setValue(
|
||||
CharacterSheetFire.Death(
|
||||
success = success,
|
||||
failure = failure,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun setSkill(character: String, name: String, value: Int) {
|
||||
val reference = database.getReference(
|
||||
"$PATH_CHARACTERS/$character/${CharacterSheetFire.SKILLS}/$name"
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ import com.pixelized.rplexicon.ui.composable.Loader
|
|||
import com.pixelized.rplexicon.ui.composable.edit.HandleHitPointEditDialog
|
||||
import com.pixelized.rplexicon.ui.composable.error.HandleFetchError
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterHeader.Action
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterHeader.Alteration
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterHeader.Inventory
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterHeader.Proficiency
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Action
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Alteration
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Inventory
|
||||
import com.pixelized.rplexicon.ui.screens.character.CharacterTabUio.Proficiency
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeader
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.ProficiencyUio.ID.*
|
||||
|
|
@ -99,7 +99,7 @@ import com.pixelized.rplexicon.utilitary.extentions.lexiconShadow
|
|||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
enum class CharacterHeader(@StringRes val label: Int) {
|
||||
enum class CharacterTabUio(@StringRes val label: Int) {
|
||||
Action(R.string.character_sheet_tab_actions),
|
||||
Alteration(R.string.character_sheet_tab_alteration),
|
||||
Inventory(R.string.character_sheet_tab_inventory),
|
||||
|
|
@ -154,6 +154,12 @@ fun CharacterSheetScreen(
|
|||
scope.launch { pagerState.animateScrollToPage(it) }
|
||||
},
|
||||
onHitPoint = headerViewModel::toggleHitPointDialog,
|
||||
onDeathRoll = {
|
||||
overlay.prepareRoll(diceThrow = headerViewModel.onDeathThrow())
|
||||
overlay.showOverlay()
|
||||
},
|
||||
onDeathSuccess = headerViewModel::onDeathSuccess,
|
||||
onDeathFailure = headerViewModel::onDeathFailure,
|
||||
onRefresh = {
|
||||
scope.launch { viewModel.update(force = true) }
|
||||
},
|
||||
|
|
@ -238,9 +244,12 @@ private fun CharacterSheetContent(
|
|||
onRefresh: () -> Unit,
|
||||
onFullRefresh: () -> Unit,
|
||||
name: String,
|
||||
tabs: State<List<CharacterHeader>>,
|
||||
tabs: State<List<CharacterTabUio>>,
|
||||
header: State<CharacterSheetHeaderUio?>,
|
||||
onHitPoint: () -> Unit,
|
||||
onDeathRoll: () -> Unit,
|
||||
onDeathSuccess: () -> Unit,
|
||||
onDeathFailure: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
onTab: (Int) -> Unit,
|
||||
loader: @Composable BoxScope.() -> Unit,
|
||||
|
|
@ -314,6 +323,9 @@ private fun CharacterSheetContent(
|
|||
modifier = Modifier.fillMaxWidth(),
|
||||
header = header,
|
||||
onHitPoint = onHitPoint,
|
||||
onDeathRoll = onDeathRoll,
|
||||
onDeathSuccess = onDeathSuccess,
|
||||
onDeathFailure = onDeathFailure,
|
||||
)
|
||||
PagerHeader(
|
||||
pagerState = pagerState,
|
||||
|
|
@ -353,7 +365,7 @@ private fun CharacterSheetContent(
|
|||
private fun PagerHeader(
|
||||
modifier: Modifier = Modifier,
|
||||
pagerState: PagerState,
|
||||
tabs: State<List<CharacterHeader>>,
|
||||
tabs: State<List<CharacterTabUio>>,
|
||||
onTab: (Int) -> Unit,
|
||||
) {
|
||||
if (tabs.value.isNotEmpty()) {
|
||||
|
|
@ -390,10 +402,10 @@ private fun rememberHeaderTabsState(
|
|||
spellsViewModel: SpellsViewModel = hiltViewModel(),
|
||||
skillViewModel: SkillsViewModel = hiltViewModel(),
|
||||
alterationsViewModel: AlterationViewModel = hiltViewModel(),
|
||||
): State<List<CharacterHeader>> {
|
||||
): State<List<CharacterTabUio>> {
|
||||
val headers = remember {
|
||||
derivedStateOf {
|
||||
mutableListOf<CharacterHeader>().apply {
|
||||
mutableListOf<CharacterTabUio>().apply {
|
||||
addAll(
|
||||
when {
|
||||
proficiencyViewModel.sheet.value != null -> listOf(Proficiency)
|
||||
|
|
@ -450,6 +462,9 @@ private fun CharacterScreenPreview(
|
|||
onFullRefresh = { },
|
||||
loader = { },
|
||||
onHitPoint = { },
|
||||
onDeathRoll = { },
|
||||
onDeathSuccess = { },
|
||||
onDeathFailure = { },
|
||||
proficiencies = { ProficiencyPreview() },
|
||||
actions = { ActionPagePreview() },
|
||||
alterations = { AlterationPagePreview() },
|
||||
|
|
@ -462,7 +477,7 @@ private fun CharacterScreenPreview(
|
|||
|
||||
@Composable
|
||||
@Stable
|
||||
private fun rememberHeaderPreview(): State<List<CharacterHeader>> = remember {
|
||||
private fun rememberHeaderPreview(): State<List<CharacterTabUio>> = remember {
|
||||
mutableStateOf(
|
||||
listOf(
|
||||
Proficiency,
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package com.pixelized.rplexicon.ui.screens.character.composable.character
|
|||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -18,8 +18,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberCharacterHeaderStatePreview
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.preview.rememberDeathThrowUio
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.utilitary.extentions.lexicon
|
||||
|
||||
@Stable
|
||||
data class CharacterSheetHeaderUio(
|
||||
|
|
@ -27,23 +27,28 @@ data class CharacterSheetHeaderUio(
|
|||
val hitPoint: LabelPointUio,
|
||||
val speed: LabelPointUio,
|
||||
val dC: LabelPointUio?,
|
||||
val death: DeathThrowUio? = null
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun CharacterSheetHeader(
|
||||
modifier: Modifier = Modifier,
|
||||
padding : PaddingValues = PaddingValues(start = 16.dp, end = 16.dp, bottom = 4.dp),
|
||||
padding: PaddingValues = PaddingValues(start = 16.dp, end = 16.dp, bottom = 4.dp),
|
||||
header: State<CharacterSheetHeaderUio?>,
|
||||
onHitPoint : () -> Unit,
|
||||
onHitPoint: () -> Unit,
|
||||
onDeathRoll: () -> Unit,
|
||||
onDeathSuccess: () -> Unit,
|
||||
onDeathFailure: () -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(padding),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(padding),
|
||||
verticalAlignment = Alignment.Bottom,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = 16.dp,
|
||||
|
|
@ -63,6 +68,17 @@ fun CharacterSheetHeader(
|
|||
LabelPoint(label = it)
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = header.value?.death != null,
|
||||
) {
|
||||
DeathHeader(
|
||||
death = header.value?.death,
|
||||
onDeathRoll = onDeathRoll,
|
||||
onDeathSuccess = onDeathSuccess,
|
||||
onDeathFailure = onDeathFailure,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,8 +90,14 @@ private fun CharacterSheetHeaderPreview() {
|
|||
LexiconTheme {
|
||||
Surface {
|
||||
CharacterSheetHeader(
|
||||
header = rememberCharacterHeaderStatePreview(),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
header = rememberCharacterHeaderStatePreview(
|
||||
death = rememberDeathThrowUio(),
|
||||
),
|
||||
onHitPoint = { },
|
||||
onDeathRoll = { },
|
||||
onDeathSuccess = { },
|
||||
onDeathFailure = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,198 @@
|
|||
package com.pixelized.rplexicon.ui.screens.character.composable.character
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
|
||||
@Stable
|
||||
data class DeathThrowUio(
|
||||
val success: Int,
|
||||
val failure: Int,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun DeathHeader(
|
||||
death: DeathThrowUio?,
|
||||
onDeathSuccess: () -> Unit,
|
||||
onDeathRoll: () -> Unit,
|
||||
onDeathFailure: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.height(intrinsicSize = IntrinsicSize.Min),
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
) {
|
||||
DeathMark(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.Center)
|
||||
.clip(shape = CircleShape)
|
||||
.clickable(onClick = onDeathSuccess)
|
||||
.padding(all = 8.dp),
|
||||
counter = death?.success ?: 0,
|
||||
leftToRight = false,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.BottomEnd)
|
||||
.padding(horizontal = 8.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = FontWeight.Light,
|
||||
text = stringResource(id = R.string.generic_success),
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.clip(shape = CircleShape)
|
||||
.clickable(onClick = onDeathRoll)
|
||||
.padding(all = 8.dp)
|
||||
.size(size = 42.dp),
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
painter = painterResource(id = R.drawable.ic_d20_24),
|
||||
contentDescription = null
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.fillMaxHeight(),
|
||||
) {
|
||||
DeathMark(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.Center)
|
||||
.clip(shape = CircleShape)
|
||||
.clickable(onClick = onDeathFailure)
|
||||
.padding(all = 8.dp),
|
||||
counter = death?.failure ?: 0,
|
||||
leftToRight = true,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.BottomStart)
|
||||
.padding(horizontal = 8.dp),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
fontWeight = FontWeight.Light,
|
||||
text = stringResource(id = R.string.generic_failure),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DeathMark(
|
||||
modifier: Modifier = Modifier,
|
||||
leftToRight: Boolean,
|
||||
counter: Int,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalLayoutDirection provides when (leftToRight) {
|
||||
true -> LayoutDirection.Ltr
|
||||
else -> LayoutDirection.Rtl
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Circle(
|
||||
full = counter > 0,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.width(width = 8.dp),
|
||||
thickness = 2.dp,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
Circle(
|
||||
full = counter > 1,
|
||||
)
|
||||
Divider(
|
||||
modifier = Modifier.width(width = 8.dp),
|
||||
thickness = 2.dp,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
Circle(
|
||||
full = counter > 2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Circle(
|
||||
modifier: Modifier = Modifier,
|
||||
full: Boolean,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(size = 24.dp)
|
||||
.border(
|
||||
width = 2.dp,
|
||||
shape = CircleShape,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = full,
|
||||
enter = fadeIn() + scaleIn(),
|
||||
exit = fadeOut() + scaleOut(),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size = 14.dp)
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
shape = CircleShape,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun DeathMarkPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
DeathHeader(
|
||||
death = DeathThrowUio(success = 2, failure = 1),
|
||||
onDeathRoll = { },
|
||||
onDeathSuccess = { },
|
||||
onDeathFailure = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,11 +6,14 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.DeathThrowUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberCharacterHeaderStatePreview() = remember {
|
||||
fun rememberCharacterHeaderStatePreview(
|
||||
death: DeathThrowUio? = null
|
||||
) = remember {
|
||||
mutableStateOf(
|
||||
CharacterSheetHeaderUio(
|
||||
armorClass = LabelPointUio(
|
||||
|
|
@ -31,6 +34,18 @@ fun rememberCharacterHeaderStatePreview() = remember {
|
|||
label = R.string.character_sheet_title_dc,
|
||||
value = "13",
|
||||
),
|
||||
death = death,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberDeathThrowUio(): DeathThrowUio {
|
||||
return remember {
|
||||
DeathThrowUio(
|
||||
success = 2,
|
||||
failure = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.pixelized.rplexicon.ui.screens.character.factory
|
|||
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.CharacterSheetHeaderUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.DeathThrowUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.composable.character.LabelPointUio
|
||||
import com.pixelized.rplexicon.ui.screens.character.pages.actions.HeaderViewModel
|
||||
import javax.inject.Inject
|
||||
|
|
@ -33,7 +34,15 @@ class CharacterSheetHeaderUioFactory @Inject constructor() {
|
|||
label = R.string.character_sheet_title_dc,
|
||||
value = "$it",
|
||||
)
|
||||
}
|
||||
},
|
||||
death = if (fireHeaderData?.hp == 0) {
|
||||
DeathThrowUio(
|
||||
success = fireHeaderData.deathSuccess,
|
||||
failure = fireHeaderData.deathFailure,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.rplexicon.model.DiceThrow
|
||||
import com.pixelized.rplexicon.model.Property
|
||||
import com.pixelized.rplexicon.repository.authentication.FirebaseRepository
|
||||
import com.pixelized.rplexicon.repository.data.character.AlterationRepository
|
||||
|
|
@ -72,6 +73,8 @@ class HeaderViewModel @Inject constructor(
|
|||
val data = FireHeaderData(
|
||||
hp = sheets.hitPoint?.value ?: 1,
|
||||
extra = sheets.hitPoint?.additional ?: 0,
|
||||
deathSuccess = sheets.death?.success ?: 0,
|
||||
deathFailure = sheets.death?.failure ?: 0,
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
fireData.value = data
|
||||
|
|
@ -81,6 +84,26 @@ class HeaderViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun onDeathThrow(): DiceThrow {
|
||||
return DiceThrow.DeathSavingThrow(character = character)
|
||||
}
|
||||
|
||||
fun onDeathSuccess() {
|
||||
firebaseRepository.setCharacterDeathCounter(
|
||||
character = character,
|
||||
success = ((fireData.value?.deathSuccess ?: 0) + 1) % 4,
|
||||
failure = fireData.value?.deathFailure ?: 0,
|
||||
)
|
||||
}
|
||||
|
||||
fun onDeathFailure() {
|
||||
firebaseRepository.setCharacterDeathCounter(
|
||||
character = character,
|
||||
success = fireData.value?.deathSuccess ?: 0,
|
||||
failure = ((fireData.value?.deathFailure ?: 0) + 1) % 4,
|
||||
)
|
||||
}
|
||||
|
||||
fun toggleHitPointDialog() {
|
||||
_hitPointDialog.value = if (_hitPointDialog.value == null) {
|
||||
HpPointDialogUio(
|
||||
|
|
@ -94,6 +117,15 @@ class HeaderViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun applyHitPointChange(hp: Int, extra: Int) {
|
||||
val hpDownToZero = (fireData.value?.hp ?: 0) > 0 && hp == 0
|
||||
val hpUpFromZero = (fireData.value?.hp ?: 0) == 0 && hp > 0
|
||||
if (hpDownToZero || hpUpFromZero) {
|
||||
firebaseRepository.setCharacterDeathCounter(
|
||||
character = character,
|
||||
success = 0,
|
||||
failure = 0,
|
||||
)
|
||||
}
|
||||
firebaseRepository.setCharacterHitPoint(
|
||||
character = character,
|
||||
value = hp,
|
||||
|
|
@ -114,5 +146,7 @@ class HeaderViewModel @Inject constructor(
|
|||
data class FireHeaderData(
|
||||
val hp: Int,
|
||||
val extra: Int,
|
||||
val deathSuccess: Int,
|
||||
val deathFailure: Int,
|
||||
)
|
||||
}
|
||||
|
|
@ -189,8 +189,8 @@ private fun Critical(
|
|||
else -> MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
text = when (it) {
|
||||
1 -> stringResource(id = R.string.generic_critical_success)
|
||||
2 -> stringResource(id = R.string.generic_critical_failure)
|
||||
1 -> stringResource(id = R.string.generic_success_critical)
|
||||
2 -> stringResource(id = R.string.generic_failure_critical)
|
||||
else -> ""
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ class AlterationFactory @Inject constructor(
|
|||
is DiceThrow.IntelligenceSavingThrow -> listOf(Property.INTELLIGENCE_SAVING_THROW)
|
||||
is DiceThrow.WisdomSavingThrow -> listOf(Property.WISDOM_SAVING_THROW)
|
||||
is DiceThrow.CharismaSavingThrow -> listOf(Property.CHARISMA_SAVING_THROW)
|
||||
is DiceThrow.DeathSavingThrow -> listOf(Property.DEATH_SAVING_THROW)
|
||||
is DiceThrow.Acrobatics -> listOf(Property.ACROBATICS, Property.DEXTERITY)
|
||||
is DiceThrow.AnimalHandling -> listOf(Property.ANIMAL_HANDLING, Property.WISDOM)
|
||||
is DiceThrow.Arcana -> listOf(Property.ARCANA, Property.INTELLIGENCE)
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
<string name="error_structure_location">La structure des cartes semble avoir changé et n\'est plus compatible avec cette application.</string>
|
||||
<string name="error_structure_quest">La structure des quêtes semble avoir changé et n\'est plus compatible avec cette application.</string>
|
||||
|
||||
<string name="generic_critical_success">SUCCÈS CRITIQUE</string>
|
||||
<string name="generic_critical_failure">ÉCHEC CRITIQUE</string>
|
||||
<string name="generic_success">Succès</string>
|
||||
<string name="generic_success_critical">SUCCÈS CRITIQUE</string>
|
||||
<string name="generic_failure">Échec</string>
|
||||
<string name="generic_failure_critical">ÉCHEC CRITIQUE</string>
|
||||
|
||||
<string name="gender_male">Mâle</string>
|
||||
<string name="gender_female">Femelle</string>
|
||||
|
|
@ -116,6 +118,7 @@
|
|||
<string name="character_sheet_stat_wisdom_short">SAG</string>
|
||||
<string name="character_sheet_stat_charisma">Charisme</string>
|
||||
<string name="character_sheet_stat_charisma_short">CHA</string>
|
||||
<string name="character_sheet_stat_death">Mort</string>
|
||||
<string name="character_sheet_proficiency">Talent</string>
|
||||
<string name="character_sheet_proficiency_acrobatics">Acrobaties</string>
|
||||
<string name="character_sheet_proficiency_animal_handling">Dressage</string>
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
<string name="error_structure_location">The location sheet structure appears to have changed and is no longer compatible with this application</string>
|
||||
<string name="error_structure_quest">The quest sheet structure appears to have changed and is no longer compatible with this application</string>
|
||||
|
||||
<string name="generic_critical_success">CRITICAL SUCCESS</string>
|
||||
<string name="generic_critical_failure">CRITICAL FAILURE</string>
|
||||
<string name="generic_success">Success</string>
|
||||
<string name="generic_success_critical">CRITICAL SUCCESS</string>
|
||||
<string name="generic_failure">Failure</string>
|
||||
<string name="generic_failure_critical">CRITICAL FAILURE</string>
|
||||
|
||||
<string name="gender_male">Male</string>
|
||||
<string name="gender_female">Female</string>
|
||||
|
|
@ -116,6 +118,7 @@
|
|||
<string name="character_sheet_stat_wisdom_short">WIS</string>
|
||||
<string name="character_sheet_stat_charisma">Charisma</string>
|
||||
<string name="character_sheet_stat_charisma_short">CHA</string>
|
||||
<string name="character_sheet_stat_death">Death</string>
|
||||
<string name="character_sheet_proficiency">Proficiency</string>
|
||||
<string name="character_sheet_proficiency_acrobatics">Acrobatics</string>
|
||||
<string name="character_sheet_proficiency_animal_handling">Animal Handling</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue