Fix skill throw bonus.

This commit is contained in:
Thomas Andres Gomez 2023-10-09 17:35:44 +02:00
parent bb1575ea84
commit 81b74cd03f
11 changed files with 178 additions and 25 deletions

View file

@ -442,6 +442,8 @@ class DiceThrowUseCase @Inject constructor(
skill = diceThrow.skill, skill = diceThrow.skill,
) )
skillThrow( skillThrow(
character = sheet,
alterations = alterations,
skill = skill, skill = skill,
) )
} }
@ -908,6 +910,8 @@ class DiceThrowUseCase @Inject constructor(
} }
private fun skillThrow( private fun skillThrow(
character: CharacterSheet,
alterations: Map<Property, List<Alteration.Status>>,
skill: Skill?, skill: Skill?,
): DiceThrowResult { ): DiceThrowResult {
// retrieve some wording. // retrieve some wording.
@ -924,6 +928,40 @@ class DiceThrowUseCase @Inject constructor(
) )
allValue.add(result.value) allValue.add(result.value)
// fetch and build the associated characteristic
val relatedStatBonus = skill?.effect?.modifier?.mapNotNull { property ->
when (property) {
Property.STRENGTH -> (character.strength + alterations[property].sum).modifier
Property.DEXTERITY -> (character.dexterity + alterations[property].sum).modifier
Property.CONSTITUTION -> (character.constitution + alterations[property].sum).modifier
Property.INTELLIGENCE -> (character.intelligence + alterations[property].sum).modifier
Property.WISDOM -> (character.wisdom + alterations[property].sum).modifier
Property.CHARISMA -> (character.charisma + alterations[property].sum).modifier
Property.PROFICIENCY -> character.proficiency
else -> null
}?.let { value ->
val titleLabel = if (property == Property.PROFICIENCY) {
application.getString(R.string.dice_roll_mastery_proficiency, skill)
} else {
val label = when (property) {
Property.STRENGTH -> application.getString(R.string.character_sheet_stat_strength)
Property.DEXTERITY -> application.getString(R.string.character_sheet_stat_dexterity)
Property.CONSTITUTION -> application.getString(R.string.character_sheet_stat_constitution)
Property.INTELLIGENCE -> application.getString(R.string.character_sheet_stat_intelligence)
Property.WISDOM -> application.getString(R.string.character_sheet_stat_wisdom)
Property.CHARISMA -> application.getString(R.string.character_sheet_stat_charisma)
else -> ""
}
application.getString(R.string.dice_roll_bonus_detail, label)
}
allValue.add(value)
ThrowsCardUio.Detail(
title = titleLabel,
result = "$value",
)
}
} ?: emptyList()
// build the result. // build the result.
return DiceThrowResult( return DiceThrowResult(
dice = RollDiceUio( dice = RollDiceUio(
@ -946,7 +984,7 @@ class DiceThrowUseCase @Inject constructor(
), ),
result = "${result.value}", result = "${result.value}",
), ),
), ) + relatedStatBonus,
) )
) )
} }

View file

@ -0,0 +1,74 @@
package com.pixelized.rplexicon.ui.screens.character.composable.actions
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.ui.theme.LexiconTheme
import com.pixelized.rplexicon.utilitary.extentions.lexicon
@Composable
fun AlterationHeader(
modifier: Modifier = Modifier,
padding: PaddingValues = PaddingValues(horizontal = 16.dp),
) {
Column(
modifier = modifier,
) {
Surface(
modifier = Modifier.fillMaxWidth(),
) {
Text(
modifier = Modifier.padding(paddingValues = padding),
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Bold,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
text = stringResource(id = R.string.character_sheet_title_alteration).let {
AnnotatedString(
text = it,
spanStyles = listOf(
AnnotatedString.Range(
item = MaterialTheme.lexicon.typography.bodyDropCapSpan,
start = 0,
end = Integer.min(1, it.length),
)
)
)
},
)
}
Divider(
modifier = Modifier.padding(paddingValues = padding),
color = MaterialTheme.lexicon.colorScheme.placeholder,
)
}
}
@Composable
@Preview(uiMode = UI_MODE_NIGHT_NO)
@Preview(uiMode = UI_MODE_NIGHT_YES)
private fun AlterationPreview() {
LexiconTheme {
Surface {
AlterationHeader()
}
}
}

View file

@ -40,7 +40,7 @@ fun AttackHeader(
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
text = stringResource(id = R.string.character_sheet_attack_title).let { text = stringResource(id = R.string.character_sheet_title_attacks).let {
AnnotatedString( AnnotatedString(
text = it, text = it,
spanStyles = listOf( spanStyles = listOf(
@ -65,7 +65,7 @@ fun AttackHeader(
@Composable @Composable
@Preview(uiMode = UI_MODE_NIGHT_NO) @Preview(uiMode = UI_MODE_NIGHT_NO)
@Preview(uiMode = UI_MODE_NIGHT_YES) @Preview(uiMode = UI_MODE_NIGHT_YES)
private fun SkillHeaderPreview() { private fun AttackHeaderPreview() {
LexiconTheme { LexiconTheme {
Surface { Surface {
SkillHeader() SkillHeader()

View file

@ -2,18 +2,15 @@ package com.pixelized.rplexicon.ui.screens.character.composable.actions
import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Divider import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
@ -43,7 +40,7 @@ fun SkillHeader(
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
text = stringResource(id = R.string.character_sheet_skill_title).let { text = stringResource(id = R.string.character_sheet_title_skills).let {
AnnotatedString( AnnotatedString(
text = it, text = it,
spanStyles = listOf( spanStyles = listOf(

View file

@ -31,6 +31,9 @@ class SpellUioFactory @Inject constructor() {
val modifier = dice.modifier.sumOf { val modifier = dice.modifier.sumOf {
when (it) { when (it) {
Property.PROFICIENCY -> characterSheet.proficiency Property.PROFICIENCY -> characterSheet.proficiency
Property.STRENGTH -> characterSheet.strength.modifier
Property.DEXTERITY -> characterSheet.dexterity.modifier
Property.CONSTITUTION -> characterSheet.constitution.modifier
Property.INTELLIGENCE -> characterSheet.intelligence.modifier Property.INTELLIGENCE -> characterSheet.intelligence.modifier
Property.WISDOM -> characterSheet.wisdom.modifier Property.WISDOM -> characterSheet.wisdom.modifier
Property.CHARISMA -> characterSheet.charisma.modifier Property.CHARISMA -> characterSheet.charisma.modifier

View file

@ -6,14 +6,20 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.pixelized.rplexicon.model.CharacterSheet
import com.pixelized.rplexicon.model.CharacterSheetFire
import com.pixelized.rplexicon.model.DiceThrow import com.pixelized.rplexicon.model.DiceThrow
import com.pixelized.rplexicon.model.Property
import com.pixelized.rplexicon.model.Skill
import com.pixelized.rplexicon.repository.authentication.FirebaseRepository import com.pixelized.rplexicon.repository.authentication.FirebaseRepository
import com.pixelized.rplexicon.repository.data.CharacterSheetRepository
import com.pixelized.rplexicon.repository.data.DescriptionRepository import com.pixelized.rplexicon.repository.data.DescriptionRepository
import com.pixelized.rplexicon.repository.data.SkillRepository import com.pixelized.rplexicon.repository.data.SkillRepository
import com.pixelized.rplexicon.ui.composable.edit.SkillEditDialogUio import com.pixelized.rplexicon.ui.composable.edit.SkillEditDialogUio
import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument import com.pixelized.rplexicon.ui.navigation.screens.characterSheetArgument
import com.pixelized.rplexicon.ui.screens.character.composable.actions.SkillItemUio import com.pixelized.rplexicon.ui.screens.character.composable.actions.SkillItemUio
import com.pixelized.rplexicon.utilitary.extentions.icon import com.pixelized.rplexicon.utilitary.extentions.icon
import com.pixelized.rplexicon.utilitary.extentions.modifier
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@ -23,6 +29,7 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class SkillsViewModel @Inject constructor( class SkillsViewModel @Inject constructor(
private val sheetRepository: CharacterSheetRepository,
private val skillRepository: SkillRepository, private val skillRepository: SkillRepository,
private val firebaseRepository: FirebaseRepository, private val firebaseRepository: FirebaseRepository,
private val descriptionRepository: DescriptionRepository, private val descriptionRepository: DescriptionRepository,
@ -43,15 +50,30 @@ class SkillsViewModel @Inject constructor(
init { init {
viewModelScope.launch { viewModelScope.launch {
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
skillRepository.skills sheetRepository.data
.combine(firebaseRepository.getCharacter(character = character)) { sheets, fire -> .combine(skillRepository.skills) { sheets, skills ->
sheets[character] to fire Struct(sheet = sheets[character], skill = skills[character] ?: emptyList())
}
.combine(firebaseRepository.getCharacter(character = character)) { data, fire ->
data.apply { this.fire = fire }
} }
.collect { data -> .collect { data ->
val (values, fire) = data val (character, values, fire) = data
val skills = values?.map { skill -> val skills = values.map { skill ->
val description = descriptionRepository.find(name = skill.name) val description = descriptionRepository.find(name = skill.name)
val modifier = skill.effect?.modifier?.sumOf {
when (it) {
Property.PROFICIENCY -> character?.proficiency ?: 0
Property.STRENGTH -> character?.strength?.modifier ?: 0
Property.DEXTERITY -> character?.dexterity?.modifier ?: 0
Property.CONSTITUTION -> character?.constitution?.modifier ?: 0
Property.INTELLIGENCE -> character?.intelligence?.modifier ?: 0
Property.WISDOM -> character?.wisdom?.modifier ?: 0
Property.CHARISMA -> character?.charisma?.modifier ?: 0
else -> 0
}
} ?: 0
SkillItemUio( SkillItemUio(
label = skill.name, label = skill.name,
translate = description?.original, translate = description?.original,
@ -60,14 +82,14 @@ class SkillsViewModel @Inject constructor(
effect = skill.effect?.let { effect = skill.effect?.let {
SkillItemUio.Dice( SkillItemUio.Dice(
icon = it.faces.icon, icon = it.faces.icon,
label = "${it.amount}d${it.faces}", label = "${skill.effect.amount}d${skill.effect.faces}${if (modifier > 0) "+$modifier" else ""}",
) )
}, },
value = fire.skills[skill.name], value = fire?.skills?.get(skill.name) ?: 0,
max = skill.amount, max = skill.amount,
haveDetail = description?.description != null, haveDetail = description?.description != null,
) )
} ?: emptyList() }
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
_skills.value = skills _skills.value = skills
@ -116,4 +138,10 @@ class SkillsViewModel @Inject constructor(
firebaseRepository.setSkill(character = character, name = id, value = value) firebaseRepository.setSkill(character = character, name = id, value = value)
hideSkillEditDialog() hideSkillEditDialog()
} }
data class Struct(
val sheet: CharacterSheet?,
val skill: List<Skill>,
var fire: CharacterSheetFire? = null
)
} }

View file

@ -2,6 +2,7 @@ package com.pixelized.rplexicon.ui.screens.character.pages.alteration
import android.content.res.Configuration.UI_MODE_NIGHT_NO import android.content.res.Configuration.UI_MODE_NIGHT_NO
import android.content.res.Configuration.UI_MODE_NIGHT_YES import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -17,6 +18,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationHeader
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItem
import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio import com.pixelized.rplexicon.ui.screens.character.composable.actions.AlterationItemUio
import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations import com.pixelized.rplexicon.ui.screens.rolls.preview.rememberRollAlterations
@ -48,6 +50,7 @@ fun AlterationPage(
) )
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun AlterationPageContent( fun AlterationPageContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -59,6 +62,9 @@ fun AlterationPageContent(
modifier = modifier, modifier = modifier,
contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp), contentPadding = PaddingValues(top = 8.dp, bottom = 16.dp),
) { ) {
stickyHeader {
AlterationHeader()
}
items(items = alterations.value) { items(items = alterations.value) {
AlterationItem( AlterationItem(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View file

@ -164,7 +164,7 @@ private fun RollOverlayContent(
Text( Text(
modifier = Modifier.padding(horizontal = 16.dp), modifier = Modifier.padding(horizontal = 16.dp),
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
text = stringResource(id = R.string.dice_roll_alteraton_action).let { text = stringResource(id = R.string.dice_roll_alteration_action).let {
AnnotatedString( AnnotatedString(
text = it, text = it,
spanStyles = listOf( spanStyles = listOf(
@ -246,7 +246,7 @@ private fun RollOverlayContent(
TextButton(onClick = onMenu) { TextButton(onClick = onMenu) {
Text( Text(
modifier = Modifier.padding(horizontal = 8.dp), modifier = Modifier.padding(horizontal = 8.dp),
text = stringResource(id = R.string.dice_roll_alteraton_action), text = stringResource(id = R.string.dice_roll_alteration_action),
) )
} }
} }

View file

@ -3,6 +3,7 @@ package com.pixelized.rplexicon.ui.screens.rolls.factory
import com.pixelized.rplexicon.R import com.pixelized.rplexicon.R
import com.pixelized.rplexicon.model.DiceThrow import com.pixelized.rplexicon.model.DiceThrow
import com.pixelized.rplexicon.repository.data.ActionRepository import com.pixelized.rplexicon.repository.data.ActionRepository
import com.pixelized.rplexicon.repository.data.SkillRepository
import com.pixelized.rplexicon.repository.data.SpellRepository import com.pixelized.rplexicon.repository.data.SpellRepository
import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio import com.pixelized.rplexicon.ui.screens.rolls.composable.RollDiceUio
import com.pixelized.rplexicon.utilitary.extentions.icon import com.pixelized.rplexicon.utilitary.extentions.icon
@ -10,6 +11,7 @@ import javax.inject.Inject
class DiceFactory @Inject constructor( class DiceFactory @Inject constructor(
private val actionRepository: ActionRepository, private val actionRepository: ActionRepository,
private val skillRepository: SkillRepository,
private val spellRepository: SpellRepository, private val spellRepository: SpellRepository,
) { ) {
fun convertDiceThrow(diceThrow: DiceThrow) = when (diceThrow) { fun convertDiceThrow(diceThrow: DiceThrow) = when (diceThrow) {
@ -27,6 +29,13 @@ class DiceFactory @Inject constructor(
RollDiceUio(icon = it) RollDiceUio(icon = it)
} }
is DiceThrow.Skill -> skillRepository.find(
character = diceThrow.character,
skill = diceThrow.skill
)?.effect?.faces?.icon?.let {
RollDiceUio(icon = it)
}
is DiceThrow.SpellDamage -> spellRepository.find( is DiceThrow.SpellDamage -> spellRepository.find(
character = diceThrow.character, character = diceThrow.character,
spell = diceThrow.spell spell = diceThrow.spell

View file

@ -82,7 +82,8 @@
<string name="character_sheet_title_initiative">Initiative</string> <string name="character_sheet_title_initiative">Initiative</string>
<string name="character_sheet_title_saving_throws">Jet de sauvegarde</string> <string name="character_sheet_title_saving_throws">Jet de sauvegarde</string>
<string name="character_sheet_title_proficiencies">Maîtrises</string> <string name="character_sheet_title_proficiencies">Maîtrises</string>
<string name="character_sheet_title_actions">Actions</string> <string name="character_sheet_title_skills">Capacités</string>
<string name="character_sheet_title_attacks">Attaques</string>
<string name="character_sheet_title_alteration">Altérations</string> <string name="character_sheet_title_alteration">Altérations</string>
<string name="character_sheet_stat_strength">Force</string> <string name="character_sheet_stat_strength">Force</string>
<string name="character_sheet_stat_strength_short">FOR</string> <string name="character_sheet_stat_strength_short">FOR</string>
@ -118,8 +119,6 @@
<string name="character_sheet_action_spell_cast">Lancer</string> <string name="character_sheet_action_spell_cast">Lancer</string>
<string name="character_sheet_action_spell_level_0">Sorts mineurs</string> <string name="character_sheet_action_spell_level_0">Sorts mineurs</string>
<string name="character_sheet_action_spell_level_X">Sorts de niveau %1$s</string> <string name="character_sheet_action_spell_level_X">Sorts de niveau %1$s</string>
<string name="character_sheet_skill_title">Capacités</string>
<string name="character_sheet_attack_title">Attaques</string>
<string name="dice_roll_mastery_proficiency">Maîtrise \"%1$s\" </string> <string name="dice_roll_mastery_proficiency">Maîtrise \"%1$s\" </string>
<string name="dice_roll_mastery_expertise">Expertise \"%1$s\" </string> <string name="dice_roll_mastery_expertise">Expertise \"%1$s\" </string>
@ -135,7 +134,7 @@
<string name="dice_roll_spell_hit_title">Jet de sort : \"%1$s"</string> <string name="dice_roll_spell_hit_title">Jet de sort : \"%1$s"</string>
<string name="dice_roll_spell_damage_title">Jet de dommage : \"%1$s\"</string> <string name="dice_roll_spell_damage_title">Jet de dommage : \"%1$s\"</string>
<string name="dice_roll_critical_label">Critique</string> <string name="dice_roll_critical_label">Critique</string>
<string name="dice_roll_alteraton_action">Alterations</string> <string name="dice_roll_alteration_action">Alterations</string>
<string name="dice_roll_saving_throw_title">Jet de sauvegarde : %1$s</string> <string name="dice_roll_saving_throw_title">Jet de sauvegarde : %1$s</string>
<string name="dice_roll_saving_throw_detail">Sauvegarde de \"%1$s\"</string> <string name="dice_roll_saving_throw_detail">Sauvegarde de \"%1$s\"</string>

View file

@ -82,7 +82,8 @@
<string name="character_sheet_title_initiative">Initiative</string> <string name="character_sheet_title_initiative">Initiative</string>
<string name="character_sheet_title_saving_throws">Saving Throws</string> <string name="character_sheet_title_saving_throws">Saving Throws</string>
<string name="character_sheet_title_proficiencies">Proficiencies</string> <string name="character_sheet_title_proficiencies">Proficiencies</string>
<string name="character_sheet_title_actions">Actions</string> <string name="character_sheet_title_attacks">Attacks</string>
<string name="character_sheet_title_skills">Skills</string>
<string name="character_sheet_title_alteration">Alterations</string> <string name="character_sheet_title_alteration">Alterations</string>
<string name="character_sheet_stat_strength">Strength</string> <string name="character_sheet_stat_strength">Strength</string>
<string name="character_sheet_stat_strength_short">STR</string> <string name="character_sheet_stat_strength_short">STR</string>
@ -118,8 +119,6 @@
<string name="character_sheet_action_spell_cast">Cast</string> <string name="character_sheet_action_spell_cast">Cast</string>
<string name="character_sheet_action_spell_level_0">Cantrip</string> <string name="character_sheet_action_spell_level_0">Cantrip</string>
<string name="character_sheet_action_spell_level_X">Spell level %1$s</string> <string name="character_sheet_action_spell_level_X">Spell level %1$s</string>
<string name="character_sheet_skill_title">Skills</string>
<string name="character_sheet_attack_title">Attacks</string>
<string name="dice_roll_mastery_proficiency">%1$s proficiency</string> <string name="dice_roll_mastery_proficiency">%1$s proficiency</string>
<string name="dice_roll_mastery_expertise">%1$s expertise</string> <string name="dice_roll_mastery_expertise">%1$s expertise</string>
@ -135,7 +134,7 @@
<string name="dice_roll_spell_hit_title">%1$s hit</string> <string name="dice_roll_spell_hit_title">%1$s hit</string>
<string name="dice_roll_spell_damage_title">%1$s damage</string> <string name="dice_roll_spell_damage_title">%1$s damage</string>
<string name="dice_roll_critical_label">Critical</string> <string name="dice_roll_critical_label">Critical</string>
<string name="dice_roll_alteraton_action">Altérations</string> <string name="dice_roll_alteration_action">Alterations</string>
<string name="dice_roll_saving_throw_title">%1$s saving throw</string> <string name="dice_roll_saving_throw_title">%1$s saving throw</string>
<string name="dice_roll_saving_throw_detail">%1$s save</string> <string name="dice_roll_saving_throw_detail">%1$s save</string>